aGrUM  0.13.2
multiDimContainer_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
27 #include <agrum/agrum.h>
28 #include <algorithm>
29 
30 
31 namespace gum {
32 
33  template < typename GUM_SCALAR >
36  MultiDimAdressable(std::forward< MultiDimAdressable >(from)) {
37  GUM_CONS_MOV(MultiDimContainer);
38  }
39 
40  // Default constructor
41  template < typename GUM_SCALAR >
44  GUM_CONSTRUCTOR(MultiDimContainer);
45  }
46 
47  // Copy constructor
48  template < typename GUM_SCALAR >
51  MultiDimAdressable(src) {
52  GUM_CONS_CPY(MultiDimContainer);
53  }
54  template < typename GUM_SCALAR >
58  return *this;
59  }
60  template < typename GUM_SCALAR >
63  GUM_OP_MOV(MultiDimContainer);
64  MultiDimAdressable::operator=(std::forward< MultiDimAdressable >(from));
65  return *this;
66  }
67 
68  // destructor
69 
70  template < typename GUM_SCALAR >
72  GUM_DESTRUCTOR(MultiDimContainer);
73  }
74 
75  // an [] operator using a Instantiation as argument
76 
77  template < typename GUM_SCALAR >
78  INLINE GUM_SCALAR MultiDimContainer< GUM_SCALAR >::
79  operator[](const Instantiation& i) const {
80  return get(i);
81  }
82 
83  // an [] operator using a Instantiation as argument
84 
85  template < typename GUM_SCALAR >
87  const GUM_SCALAR& value) const {
88  _get(i) = value;
89  }
90 
91  // an [] operator using a Instantiation as argument
92 
93  template < typename GUM_SCALAR >
94  INLINE GUM_SCALAR
96  return _get(i);
97  }
98 
99  // display the content of an array
100 
101  template < typename GUM_SCALAR >
102  const std::string MultiDimContainer< GUM_SCALAR >::toString() const {
103  // we create a new instantiation and iterate over it to display the whole
104  // content of the array
105  if (this->nbrDim() == 0) { return "[]"; }
106 
107  std::stringstream ss;
108  Instantiation inst(const_cast< MultiDimContainer* >(this));
109 
110  bool first = true;
111 
112  for (inst.setFirst(); !inst.end(); ++inst) {
113  if (!first) { ss << " /"; }
114  first = false;
115 
116  ss << inst << " :: " << get(inst);
117  }
118 
119  return ss.str();
120  }
121 
122  // Test if this potential is equal to p.
123 
124  template < typename GUM_SCALAR >
127  if ((nbrDim() == p.nbrDim()) && (domainSize() == p.domainSize())) {
128  if (nbrDim() == 0) return true;
129 
131  var_iterator;
132 
133  for (var_iterator iter = variablesSequence().beginSafe();
134  iter != variablesSequence().endSafe();
135  ++iter) {
136  if (!p.variablesSequence().exists(*iter)) { return false; }
137  }
138  } else {
139  return false;
140  }
141 
142  Instantiation i(*this);
143 
145 
146  for (i.setFirst(); !i.end(); ++i) {
147  if (cmp(get(i), p.get(i))) { return false; }
148  }
149 
150  return true;
151  }
152 
153  // Test if this potential is different of p.
154 
155  template < typename GUM_SCALAR >
158  return !operator==(p);
159  }
160 
161  // automation fill with vector.
162  template < typename GUM_SCALAR >
164  const std::vector< GUM_SCALAR >& v) const {
165  if (domainSize() != v.size()) {
166  GUM_ERROR(SizeError, "Sizes do not match in populate");
167  }
168 
169  Size cpt = 0;
170 
171  Instantiation i(*this);
172 
173  for (i.setFirst(); !i.end(); ++i, ++cpt)
174  set(i, v[cpt]);
175  }
176 
177  template < typename GUM_SCALAR >
179  std::initializer_list< GUM_SCALAR > l) const {
180  if (domainSize() != l.size()) {
181  GUM_ERROR(SizeError, "Sizes do not match in populate");
182  }
183 
184  Instantiation i(*this);
185  // insert all the elements
186  for (const auto& elt : l) {
187  set(i, elt);
188  ++i;
189  }
190  }
191 
192  template < typename GUM_SCALAR >
194  std::function< GUM_SCALAR(GUM_SCALAR) > f) const {
195  Instantiation i(*this);
196  for (i.setFirst(); !i.end(); ++i) {
197  set(i, f(get(i)));
198  }
199  }
200 
201  template < typename GUM_SCALAR >
203  std::function< GUM_SCALAR(GUM_SCALAR, GUM_SCALAR) > f, GUM_SCALAR base) const {
204  GUM_SCALAR tmp = base;
205  Instantiation i(*this);
206  for (i.setFirst(); !i.end(); ++i) {
207  tmp = f(tmp, get(i));
208  }
209  return tmp;
210  }
211 
212 
213  template < typename GUM_SCALAR >
215  const MultiDimContainer< GUM_SCALAR >& src, Instantiation* p_i) const {
216  if (src.domainSize() != domainSize()) {
217  GUM_ERROR(OperationNotAllowed, "Domain sizes do not fit");
218  }
219 
220  if (p_i == nullptr) { // if null, we just follow the same order
221  Instantiation i(src);
222  for (i.setFirst(); !i.end(); ++i) {
223  set(i, src[i]);
224  }
225  } else {
226  Instantiation i_dest(*this);
227  Instantiation i_src(src);
228  for (i_dest.setFirst(), i_src.setFirst(); !i_dest.end();
229  i_dest.incIn(*p_i), ++i_src) {
230  set(i_dest, src[i_src]);
231  }
232  }
233  }
234 
235  template < typename GUM_SCALAR >
237  const MultiDimContainer< GUM_SCALAR >& src, const Instantiation& imask) {
238  this->beginMultipleChanges();
239 
240  Size nbr = this->nbrDim();
241 
242  for (Idx i = 0; i < nbr; i++) {
243  this->erase(this->variable(0));
244  }
245 
246  for (Idx i = 0; i < src.nbrDim(); i++) {
247  if (!imask.contains(src.variable(i))) this->add(src.variable(i));
248  }
249 
250  if (this->nbrDim() == 0) { GUM_ERROR(FatalError, "Empty potential"); }
251 
252  this->endMultipleChanges();
253 
254  Instantiation inst(src);
255  inst.setVals(imask);
256  for (inst.setFirstOut(imask); !inst.end(); inst.incOut(imask))
257  set(inst, src[inst]);
258  }
259 
260  template < typename GUM_SCALAR >
262  const MultiDimContainer< GUM_SCALAR >& src) const {
263  if (src.domainSize() != domainSize()) {
264  GUM_ERROR(OperationNotAllowed, "Domain sizes do not fit");
265  }
266 
267  Instantiation i_dest(*this);
268  Instantiation i_src(src);
269 
270  for (i_dest.setFirst(), i_src.setFirst(); !i_dest.end(); ++i_dest, ++i_src) {
271  set(i_dest, src[i_src]);
272  }
273  }
274 
275  // copy
276 
277  template < typename GUM_SCALAR >
279  const MultiDimContainer< GUM_SCALAR >& src) {
280  this->beginMultipleChanges();
281 
282  Size nbr = this->nbrDim();
283 
284  for (Idx i = 0; i < nbr; i++) {
285  this->erase(this->variable(0));
286  }
287 
288  for (Idx i = 0; i < src.nbrDim(); i++) {
289  this->add(src.variable(i));
290  }
291 
292  this->endMultipleChanges();
293  this->copyFrom(src);
294  }
295 
296  template < typename GUM_SCALAR >
298  return static_cast< MultiDimAdressable& >(*content());
299  }
300 
301  template < typename GUM_SCALAR >
302  INLINE const MultiDimAdressable&
304  return static_cast< const MultiDimAdressable& >(*content());
305  }
306 
307  // display the content of an array
308 
309  template < typename GUM_SCALAR >
310  std::ostream& operator<<(std::ostream& out,
311  const MultiDimContainer< GUM_SCALAR >& array) {
312  out << array.toString();
313  return out;
314  }
315 
316 } /* namespace gum */
virtual void endMultipleChanges()=0
Call this method after doing important changes in this MultiDimContainer.
virtual void add(const DiscreteVariable &v)=0
Adds a new var to the variables of the multidimensional matrix.
Safe iterators for Sequence.
Definition: sequence.h:1203
unsigned long Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:50
virtual ~MultiDimContainer()
Destructor.
virtual Idx nbrDim() const =0
Returns the number of vars in the multidimensional container.
virtual void copyFrom(const MultiDimContainer< GUM_SCALAR > &src) const
Basic copy of a MultiDimContainer.
bool operator==(const MultiDimContainer< GUM_SCALAR > &p) const
Test if this MultiDimContainer is equal to p.
virtual const DiscreteVariable & variable(Idx i) const =0
Returns a const ref to the ith var.
GUM_SCALAR operator[](const Instantiation &i) const
An [] operator using a Instantiation as argument.
virtual void apply(std::function< GUM_SCALAR(GUM_SCALAR) > f) const
Apply a function on every element of the container.
STL namespace.
virtual GUM_SCALAR & _get(const Instantiation &i) const =0
Return a data, given a Instantiation.
virtual GUM_SCALAR reduce(std::function< GUM_SCALAR(GUM_SCALAR, GUM_SCALAR) > f, GUM_SCALAR base) const
compute lfold for this container
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
Abstract base class for all multi dimensionnal containers.
Instantiation & setVals(const Instantiation &i)
Assign the values from i in the Instantiation.
Indicate whether two elements are (almost) different or not.
Definition: utils_misc.h:140
virtual void copy(const MultiDimContainer< GUM_SCALAR > &src)
Removes all variables in this MultiDimContainer and copy the content of src, variables included...
virtual void beginMultipleChanges()=0
Call this method before doing important changes in this MultiDimContainer.
void incOut(const Instantiation &i)
Operator increment for the variables not in i.
std::ostream & operator<<(std::ostream &output, const BayesNet< GUM_SCALAR > &bn)
Prints map&#39;s DAG in output using the Graphviz-dot format.
Definition: BayesNet_tpl.h:573
virtual void set(const Instantiation &i, const GUM_SCALAR &value) const
Changes the value pointed by i.
virtual Size domainSize() const =0
Returns the product of the variables domain size.
virtual void populate(const std::vector< GUM_SCALAR > &v) const
Automatically fills this MultiDimContainer with the values in v.
MultiDimAdressable & operator=(const MultiDimAdressable &from)
Default constructor.
bool operator!=(const MultiDimContainer< GUM_SCALAR > &p) const
Test if this MultiDimContainer is different of p.
bool end() const
Returns true if the Instantiation reached the end.
void incIn(const Instantiation &i)
Operator increment for the variables in i.
virtual const MultiDimImplementation< GUM_SCALAR > * content() const =0
Returns the implementation for this object (may be *this).
Abstract base class for all multi dimensionnal addressable.
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
bool contains(const DiscreteVariable &v) const final
Indicates whether a given variable belongs to the Instantiation.
MultiDimContainer()
Default constructor.
void setFirst()
Assign the first values to the tuple of the Instantiation.
virtual const std::string toString() const
Returns a representation of this MultiDimContainer.
virtual void erase(const DiscreteVariable &v)=0
Removes a var from the variables of the multidimensional matrix.
virtual const Sequence< const DiscreteVariable * > & variablesSequence() const =0
Returns a const ref to the sequence of DiscreteVariable*.
unsigned long Idx
Type for indexes.
Definition: types.h:43
#define GUM_ERROR(type, msg)
Definition: exceptions.h:66
virtual MultiDimAdressable & getMasterRef()
In order to insure the dereference for decorators, we need to virtualize the access to master pointer...
virtual void extractFrom(const MultiDimContainer< GUM_SCALAR > &src, const Instantiation &mask)
Basic extraction of a MultiDimContainer.
virtual GUM_SCALAR get(const Instantiation &i) const
Returns the value pointed by i.
void setFirstOut(const Instantiation &i)
Assign the first values in the Instantiation for the variables not in i.
MultiDimContainer & operator=(const MultiDimContainer< GUM_SCALAR > &src)
Default constructor.