aGrUM  0.14.3
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,
204  GUM_SCALAR base) const {
205  GUM_SCALAR tmp = base;
206  Instantiation i(*this);
207  for (i.setFirst(); !i.end(); ++i) {
208  tmp = f(tmp, get(i));
209  }
210  return tmp;
211  }
212 
213 
214  template < typename GUM_SCALAR >
216  const MultiDimContainer< GUM_SCALAR >& src, Instantiation* p_i) const {
217  if (src.domainSize() != domainSize()) {
218  GUM_ERROR(OperationNotAllowed, "Domain sizes do not fit");
219  }
220 
221  if (p_i == nullptr) { // if null, we just follow the same order
222  Instantiation i(src);
223  for (i.setFirst(); !i.end(); ++i) {
224  set(i, src[i]);
225  }
226  } else {
227  Instantiation i_dest(*this);
228  Instantiation i_src(src);
229  for (i_dest.setFirst(), i_src.setFirst(); !i_dest.end();
230  i_dest.incIn(*p_i), ++i_src) {
231  set(i_dest, src[i_src]);
232  }
233  }
234  }
235 
236  template < typename GUM_SCALAR >
238  const MultiDimContainer< GUM_SCALAR >& src, const Instantiation& imask) {
239  this->beginMultipleChanges();
240 
241  Size nbr = this->nbrDim();
242 
243  for (Idx i = 0; i < nbr; i++) {
244  this->erase(this->variable(0));
245  }
246 
247  for (Idx i = 0; i < src.nbrDim(); i++) {
248  if (!imask.contains(src.variable(i))) this->add(src.variable(i));
249  }
250 
251  if (this->nbrDim() == 0) { GUM_ERROR(FatalError, "Empty potential"); }
252 
253  this->endMultipleChanges();
254 
255  Instantiation inst(src);
256  inst.setVals(imask);
257  for (inst.setFirstOut(imask); !inst.end(); inst.incOut(imask))
258  set(inst, src[inst]);
259  }
260 
261  template < typename GUM_SCALAR >
263  const MultiDimContainer< GUM_SCALAR >& src) const {
264  if (src.domainSize() != domainSize()) {
265  GUM_ERROR(OperationNotAllowed, "Domain sizes do not fit");
266  }
267 
268  Instantiation i_dest(*this);
269  Instantiation i_src(src);
270 
271  for (i_dest.setFirst(), i_src.setFirst(); !i_dest.end(); ++i_dest, ++i_src) {
272  set(i_dest, src[i_src]);
273  }
274  }
275 
276  // copy
277 
278  template < typename GUM_SCALAR >
280  const MultiDimContainer< GUM_SCALAR >& src) {
281  this->beginMultipleChanges();
282 
283  Size nbr = this->nbrDim();
284 
285  for (Idx i = 0; i < nbr; i++) {
286  this->erase(this->variable(0));
287  }
288 
289  for (Idx i = 0; i < src.nbrDim(); i++) {
290  this->add(src.variable(i));
291  }
292 
293  this->endMultipleChanges();
294  this->copyFrom(src);
295  }
296 
297  template < typename GUM_SCALAR >
299  return static_cast< MultiDimAdressable& >(*content());
300  }
301 
302  template < typename GUM_SCALAR >
303  INLINE const MultiDimAdressable&
305  return static_cast< const MultiDimAdressable& >(*content());
306  }
307 
308  // display the content of an array
309 
310  template < typename GUM_SCALAR >
311  std::ostream& operator<<(std::ostream& out,
312  const MultiDimContainer< GUM_SCALAR >& array) {
313  out << array.toString();
314  return out;
315  }
316 
317 } /* 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
virtual ~MultiDimContainer()
Destructor.
virtual Idx nbrDim() const =0
Returns the number of vars in the multidimensional container.
virtual const DiscreteVariable & variable(Idx i) const =0
Returns a const ref to the ith var.
STL namespace.
virtual GUM_SCALAR & _get(const Instantiation &i) const =0
Return a data, given a Instantiation.
virtual const std::string toString() const
Returns a representation of this MultiDimContainer.
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:152
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.
virtual void set(const Instantiation &i, const GUM_SCALAR &value) const
Changes the value pointed by i.
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:583
virtual GUM_SCALAR reduce(std::function< GUM_SCALAR(GUM_SCALAR, GUM_SCALAR) > f, GUM_SCALAR base) const
compute lfold for this container
virtual Size domainSize() const =0
Returns the product of the variables domain size.
MultiDimAdressable & operator=(const MultiDimAdressable &from)
Default constructor.
bool operator!=(const MultiDimContainer< GUM_SCALAR > &p) const
Test if this MultiDimContainer is different of p.
virtual void copyFrom(const MultiDimContainer< GUM_SCALAR > &src) const
Basic copy of a MultiDimContainer.
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
GUM_SCALAR operator[](const Instantiation &i) const
An [] operator using a Instantiation as argument.
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 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*.
Size Idx
Type for indexes.
Definition: types.h:50
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
virtual void apply(std::function< GUM_SCALAR(GUM_SCALAR) > f) const
Apply a function on every element of the container.
virtual GUM_SCALAR get(const Instantiation &i) const
Returns the value pointed by i.
bool operator==(const MultiDimContainer< GUM_SCALAR > &p) const
Test if this MultiDimContainer is equal to p.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
virtual MultiDimAdressable & getMasterRef()
In order to insure the dereference for decorators, we need to virtualize the access to master pointer...
virtual void populate(const std::vector< GUM_SCALAR > &v) const
Automatically fills this MultiDimContainer with the values in v.
bool end() const
Returns true if the Instantiation reached the end.
virtual void extractFrom(const MultiDimContainer< GUM_SCALAR > &src, const Instantiation &mask)
Basic extraction of a MultiDimContainer.
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.