aGrUM  0.18.1
a C++ library for (probabilistic) graphical models
multiDimBucket_tpl.h
Go to the documentation of this file.
1 
32 
33 namespace gum {
34 
35  template < typename GUM_SCALAR >
37  MultiDimReadOnly< GUM_SCALAR >(), bufferSize__(bufferSize), bucket__(0),
38  changed__(false), name__("MultiDimBucket") {
39  GUM_CONSTRUCTOR(MultiDimBucket);
40  }
41 
42  template < typename GUM_SCALAR >
44  const MultiDimBucket< GUM_SCALAR >& source) :
45  MultiDimReadOnly< GUM_SCALAR >(source),
49  name__("MultiDimBucket") {
50  GUM_CONS_CPY(MultiDimBucket);
51  }
52 
53  template < typename GUM_SCALAR >
55  GUM_DESTRUCTOR(MultiDimBucket);
57 
58  for (BiIter iter = instantiations__.beginSafe();
59  iter != instantiations__.endSafe();
60  ++iter) {
61  delete iter.second();
62  }
63 
64  if (bucket__) { delete bucket__; }
65 
67  Instantiation* > iter = multiDims__.beginSafe();
68  iter != multiDims__.endSafe();
69  ++iter) {
70  delete iter.val();
71  }
72  }
73 
74  template < typename GUM_SCALAR >
76  const MultiDimContainer< GUM_SCALAR >& impl) {
77  this->add(&impl);
78  }
79 
80  template < typename GUM_SCALAR >
82  const MultiDimContainer< GUM_SCALAR >* impl) {
83  multiDims__.insert(impl, new Instantiation(*impl));
84 
86  for (const auto var: impl->variablesSequence()) {
87  addVariable__(var);
88  }
89  }
90 
91  changed__ = true;
92  }
93 
94  template < typename GUM_SCALAR >
96  const MultiDimContainer< GUM_SCALAR >& impl) {
97  this->erase(&impl);
98  }
99 
100  template < typename GUM_SCALAR >
102  const MultiDimContainer< GUM_SCALAR >* impl) {
103  try {
104  delete multiDims__[impl];
105  multiDims__.erase(impl);
106 
108  for (auto var: impl->variablesSequence()) {
109  eraseVariable__(var);
110  }
111  }
112 
113  changed__ = true;
114  } catch (NotFound&) {
115  // Do nothing
116  }
117  }
118 
119  template < typename GUM_SCALAR >
121  const MultiDimContainer< GUM_SCALAR >& impl) const {
122  return multiDims__.exists(&impl);
123  }
124 
125  template < typename GUM_SCALAR >
126  INLINE const Set< const DiscreteVariable* >&
128  return allVariables__;
129  }
130 
131  template < typename GUM_SCALAR >
133  return multiDims__.size();
134  }
135 
136  template < typename GUM_SCALAR >
138  return multiDims__.empty();
139  }
140 
141  template < typename GUM_SCALAR >
143  return changed__;
144  }
145 
146  template < typename GUM_SCALAR >
148  return bufferSize__;
149  }
150 
151  template < typename GUM_SCALAR >
153  bufferSize__ = ammount;
154 
155  if ((this->domainSize() > bufferSize__) && (bucket__ != 0)) {
156  eraseBuffer__();
157  } else if (bucket__ == 0) {
159  }
160  }
161 
162  template < typename GUM_SCALAR >
163  void MultiDimBucket< GUM_SCALAR >::compute(bool force) const {
164  if ((bucket__) && (changed__ || force)) {
165  Instantiation values(*bucket__);
166 
167  for (values.setFirst(); !values.end(); values.inc()) {
168  bucket__->set(values, computeValue__(values));
169  }
170  } else if ((bucket__ == 0) && changed__) {
171  slavesValue__.clear();
172  changed__ = false;
173  }
174 
175  changed__ = false;
176  }
177 
178  template < typename GUM_SCALAR >
179  const std::string& MultiDimBucket< GUM_SCALAR >::name() const {
180  return name__;
181  }
182 
183  template < typename GUM_SCALAR >
186 
188  if (this->domainSize() <= bufferSize__) {
189  if (bucket__)
190  bucket__->add(v);
191  else
193  } else if (bucket__) {
194  eraseBuffer__();
195  }
196  }
197  }
198 
199  template < typename GUM_SCALAR >
202 
204  && (this->domainSize() <= bufferSize__)) {
205  if (bucket__) {
206  bucket__->erase(v);
207  } else {
209  }
210  }
211  }
212 
213  template < typename GUM_SCALAR >
215  return (bucket__) ? bucket__->realSize() : (Size)0;
216  }
217 
218  template < typename GUM_SCALAR >
219  INLINE bool
222  }
223 
224  template < typename GUM_SCALAR >
225  INLINE GUM_SCALAR
227  compute();
228 
229  if (bucket__) {
230  try {
231  return bucket__->get(
232  *(instantiations__.second(const_cast< Instantiation* >(&i))));
233  } catch (NotFound&) { return bucket__->get(i); }
234  } else if (i.isMaster(this)) {
235  if (!slavesValue__.exists(&i)) {
236  slavesValue__.insert(&i, computeValue__(i));
237  }
238 
239  return slavesValue__[&i];
240  } else {
241  return computeValue__(i);
242  }
243  }
244 
245  template < typename GUM_SCALAR >
247  const Instantiation& i,
248  const DiscreteVariable* const var,
249  Idx oldval,
250  Idx newval) {
251  if (bucket__) {
252  try {
253  bucket__->changeNotification(
254  *(instantiations__).second(const_cast< Instantiation* >(&i)),
255  var,
256  oldval,
257  newval);
258  } catch (NotFound&) {
259  // Then i is not a slave of this
260  }
261  } else {
262  slavesValue__.erase(&i);
263  }
264  }
265 
266  template < typename GUM_SCALAR >
267  INLINE void
269  if (bucket__) {
270  try {
271  bucket__->setFirstNotification(
272  *(instantiations__).second(const_cast< Instantiation* >(&i)));
273  } catch (NotFound&) {
274  // Then i is not a slave of this
275  }
276  } else {
277  slavesValue__.erase(&i);
278  }
279  }
280 
281  template < typename GUM_SCALAR >
282  INLINE void
284  if (bucket__) {
285  try {
286  bucket__->setLastNotification(
287  *(instantiations__).second(const_cast< Instantiation* >(&i)));
288  } catch (NotFound&) {
289  // Then i is not a slave of this
290  }
291  } else {
292  slavesValue__.erase(&i);
293  }
294  }
295 
296  template < typename GUM_SCALAR >
297  INLINE void
299  if (bucket__) {
300  try {
301  bucket__->setIncNotification(
302  *(instantiations__.second(const_cast< Instantiation* >(&i))));
303  } catch (NotFound&) {
304  // Then i is not a slave of this
305  }
306  } else {
307  slavesValue__.erase(&i);
308  }
309  }
310 
311  template < typename GUM_SCALAR >
312  INLINE void
314  if (bucket__) {
315  try {
316  bucket__->setDecNotification(
317  *(instantiations__.second(const_cast< Instantiation* >(&i))));
318  } catch (NotFound&) {
319  // Then i is not a slave of this
320  }
321  } else {
322  slavesValue__.erase(&i);
323  }
324  }
325 
326  template < typename GUM_SCALAR >
327  INLINE void
329  if (bucket__) {
330  try {
331  bucket__->setChangeNotification(
332  *(instantiations__.second(const_cast< Instantiation* >(&i))));
333  } catch (NotFound&) {
334  // Then i is not a slave of this
335  }
336  } else {
337  slavesValue__.erase(&i);
338  }
339  }
340 
341  template < typename GUM_SCALAR >
343  if (bucket__) {
344  try {
345  instantiations__.insert(&i, new Instantiation(*bucket__));
346  } catch (DuplicateElement&) { return false; }
347  }
348 
350  }
351 
352  template < typename GUM_SCALAR >
355 
356  if (bucket__) {
357  try {
358  delete instantiations__.second(&i);
359  instantiations__.eraseFirst(&i);
360  return true;
361  } catch (NotFound&) { return false; }
362  } else {
363  if (slavesValue__.exists(&i)) {
364  slavesValue__.erase(&i);
365  return true;
366  } else {
367  return false;
368  }
369  }
370  }
371 
372  template < typename GUM_SCALAR >
374  if (bucket__) {
375  return *bucket__;
376  } else {
377  return *this;
378  }
379  }
380 
381  template < typename GUM_SCALAR >
382  INLINE const MultiDimAdressable&
384  if (bucket__) {
385  return *bucket__;
386  } else {
387  return *this;
388  }
389  }
390 
391  template < typename GUM_SCALAR >
392  INLINE const std::string
394  std::stringstream sBuff;
395  sBuff << (*i) << " = " << get(*i);
396  return sBuff.str();
397  }
398 
399  template < typename GUM_SCALAR >
402 
403  if (this->domainSize() <= bufferSize__) {
405  } else {
406  eraseBuffer__();
407  }
408 
409  allVariables__.clear();
410 
411  while (!allVarsInst__.empty()) {
413  }
414 
415  for ( // HashTableIteratorSafe<const MultiDimContainer<GUM_SCALAR>*,
416  // Instantiation*>
417  auto iter = multiDims__.beginSafe(); iter != multiDims__.endSafe();
418  ++iter) {
419  for (auto var: iter.key()->variablesSequence()) {
420  addVariable__(var);
421  }
422  }
423 
424  changed__ = true;
425  }
426 
427  template < typename GUM_SCALAR >
428  INLINE GUM_SCALAR&
430  GUM_ERROR(OperationNotAllowed, "a MultiDimBucket is a read only MultiDim");
431  }
432 
433  template < typename GUM_SCALAR >
434  INLINE void
436  try {
437  allVariables__.insert(var);
438  allVarsInst__.add(*var);
439  } catch (DuplicateElement&) {
440  // Nothing to do then!
441  }
442  }
443 
444  template < typename GUM_SCALAR >
446  bool found = false;
447 
449  Instantiation* > iter = multiDims__.beginSafe();
450  iter != multiDims__.endSafe();
451  ++iter) {
452  if (iter.key()->contains(*var)) {
453  found = true;
454  break;
455  }
456  }
457 
458  // No one use it, we can safely remove it
459  if (!found) {
460  allVariables__.erase(var);
461  allVarsInst__.erase(*var);
462  }
463  }
464 
465  template < typename GUM_SCALAR >
467  if (bucket__) {
469 
470  for (BiIter iter = instantiations__.beginSafe();
471  iter != instantiations__.endSafe();
472  ++iter) {
473  delete iter.second();
474  }
475 
476  instantiations__.clear();
477  delete bucket__;
478  bucket__ = 0;
479  }
480 
481  // Creating the table.
483 
484  for (auto var: this->variablesSequence()) {
485  bucket__->add(*var);
486  }
487 
488  if (!this->slaves_().empty()) {
490  this->slaves_().cbeginSafe();
491  iter != this->slaves_().cendSafe();
492  ++iter) {
493  instantiations__.insert(*iter, new Instantiation(*bucket__));
494  }
495  }
496 
497  changed__ = true;
498  }
499 
500  template < typename GUM_SCALAR >
502  if (bucket__) {
504 
505  for (BiIter iter = instantiations__.beginSafe();
506  iter != instantiations__.endSafe();
507  ++iter) {
508  delete iter.second();
509  }
510 
511  instantiations__.clear();
512  delete bucket__;
513  bucket__ = 0;
514  }
515  }
516 
517  template < typename GUM_SCALAR >
519  const Instantiation& value) const {
520  try {
521  GUM_SCALAR sum = (GUM_SCALAR)0;
522  GUM_SCALAR current;
523  allVarsInst__.setVals(value);
524 
525  for (allVarsInst__.setFirstOut(value); !allVarsInst__.end();
526  allVarsInst__.incOut(value)) {
527  current = (GUM_SCALAR)1;
528 
530  Instantiation* > iter =
531  multiDims__.beginSafe();
532  iter != multiDims__.endSafe();
533  ++iter) {
534  (iter.val())->setVals(allVarsInst__);
535  current *= iter.key()->get(*(iter.val()));
536  }
537 
538  sum += current;
539  }
540 
541  return sum;
542  } catch (NotFound& e) {
543  std::cerr << std::endl << e.errorContent() << std::endl;
544  // This happens if the bucket is empty.
545  GUM_ERROR(SizeError, "This MultiDimBucket is empty.");
546  }
547  }
548 
549  template < typename GUM_SCALAR >
552  return new MultiDimBucket< GUM_SCALAR >;
553  }
554 
555  template < typename GUM_SCALAR >
556  INLINE const MultiDimArray< GUM_SCALAR >&
558  if (bucket__) {
559  return *bucket__;
560  } else {
561  GUM_ERROR(OperationNotAllowed, "bucket not used.");
562  }
563  }
564 
565  template < typename GUM_SCALAR >
567  const DiscreteVariable* y) {
570 
571  for (Iter iter = instantiations__.beginSafe();
572  iter != instantiations__.endSafe();
573  ++iter) {
574  iter.first()->replace(*x, *y);
575  iter.second()->replace(*x, *y);
576  }
577 
578  if (bucket__) bucket__->replace(*x, *y);
579 
580  allVariables__.erase(x);
581  allVariables__.insert(y);
582  allVarsInst__.replace(*x, *y);
583  }
584 
585  template < typename GUM_SCALAR >
588  return multiDims__;
589  }
590 
591 } /* namespace gum */
virtual bool unregisterSlave(Instantiation &i) override
Unregister i as a slave of this MultiDimAdressable.
HashTable< const MultiDimContainer< GUM_SCALAR > *, Instantiation *> multiDims__
The set of MultiDimContainer in this bucket.
virtual void setDecNotification(const Instantiation &i) override
Listen to increment in each recorded Instantiation.
const List< Instantiation *> & slaves_() const
Returns a constant reference over the list of slaved instantiations.
void initializeBuffer__()
Initialize the internal buffer.
virtual void setChangeNotification(const Instantiation &i) override
Listen to an assignment of a value in a Instantiation.
virtual Size realSize() const override
Returns the real number of parameters used for this table.
virtual void erase(const DiscreteVariable &v) override
Removes a var from the variables of the multidimensional matrix.
Safe iterators for bijectionIterator.
Definition: bijection.h:1411
virtual void commitMultipleChanges_()
Synchronize content after MultipleChanges.
bool isBucketEmpty() const
Returns true if this bucket is empty.
virtual const std::string toString() const
Returns a representation of this MultiDimContainer.
A multidim implementation for buckets.
Base class for discrete random variable.
bool contains(const MultiDimContainer< GUM_SCALAR > &impl) const
Returns true if the MultiDimContainer is in this bucket.
Safe Iterators for hashtables.
Definition: hashTable.h:2220
virtual bool unregisterSlave(Instantiation &slave) override
Unregister i as a slave of this MultiDimAdressable.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Definition: agrum.h:25
Abstract base class for all multi dimensionnal containers.
virtual bool empty() const override
Returns true if no var is in *this.
virtual MultiDimContainer< GUM_SCALAR > * newFactory() const override
Default constructor.
virtual GUM_SCALAR get(const Instantiation &i) const override
Returns the value pointed by i.
Abstract base class for all multi dimensionnal read only structure.
Instantiation & setVals(const Instantiation &i)
Assign the values from i in the Instantiation.
Bijection< Instantiation *, Instantiation *> instantiations__
Bijection between instantiations registered on this and their equivalent on bucket__.
const Sequence< const DiscreteVariable *> & variablesSequence() const final
Returns the sequence of DiscreteVariable of this instantiation.
The class for generic Hash Tables.
Definition: hashTable.h:679
virtual ~MultiDimBucket()
Destructor.
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
void erase(const MultiDimContainer< GUM_SCALAR > &impl)
Remove a MultiDimContainer from this bucket.
void incOut(const Instantiation &i)
Operator increment for the variables not in i.
virtual void changeNotification(const Instantiation &i, const DiscreteVariable *const var, Idx oldval, Idx newval) override
Listen to changes in a given Instantiation.
virtual void setLastNotification(const Instantiation &i) override
Listen to setLast in a given Instantiation.
Instantiation allVarsInst__
Instantiation over all variable in this.
MultiDimArray< GUM_SCALAR > * bucket__
The result table of this bucket.
void eraseVariable__(const DiscreteVariable *var)
Erase a variable from allVariables__ if no other multidimensional table uses it in this bucket...
void inc()
Operator increment.
const MultiDimArray< GUM_SCALAR > & bucket() const
Returns the MultiDimArray used by this MultiDimBucket.
Size bucketSize() const
Returns the number of MultiDimContainer in in this bukcet.
MultiDimBucket(Size bufferSize=INT_MAX)
Default constructor.
void compute(bool force=false) const
This method computes the final table of this bucket.
virtual void replace_(const DiscreteVariable *x, const DiscreteVariable *y) override
Replace variable x by y.
Size bufferSize__
The number of element allowed in bucket__.
virtual void setIncNotification(const Instantiation &i) override
Listen to increment in a given Instantiation.
Multidimensional matrix stored as an array in memory.
Definition: multiDimArray.h:54
bool bucketChanged() const
Returns true if the bucket need re-computation since the last computation.
virtual bool empty() const final
Returns true if the instantiation is empty.
virtual void add(const DiscreteVariable &v) override
Adds a new var to the variables of the multidimensional matrix.
virtual const Sequence< const DiscreteVariable *> & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
virtual void setFirstNotification(const Instantiation &i) override
Listen to setFirst in a given Instantiation.
Abstract base class for all multi dimensionnal addressable.
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:83
virtual Size domainSize() const override
Returns the product of the variables domain size.
Size bufferSize() const
Returns the amount of memory allowed for this bucket.
virtual void commitMultipleChanges_() override
Synchronize content after MultipleChanges.
bool isMaster(const MultiDimAdressable *m) const
Indicates whether m is the master of this instantiation.
void setFirst()
Assign the first values to the tuple of the Instantiation.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
const T2 & second() const
Returns the second element of the current association.
void replace(const DiscreteVariable &x, const DiscreteVariable &y)
Replace variables in this multidim.
Safe const iterators for Lists.
Definition: list.h:2030
virtual bool registerSlave(Instantiation &i) override
Register i as a slave of this MultiDimAdressable.
<agrum/tools/multidim/multiDimImplementation.h>
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:53
void eraseBuffer__()
Clean the buffer and switch it&#39;s instantiation to this bucket.
void add(const DiscreteVariable &v) final
Adds a new variable in the Instantiation.
virtual GUM_SCALAR & get_(const Instantiation &i) const override
void erase(const DiscreteVariable &v) final
Removes a variable from the Instantiation.
Set< const DiscreteVariable *> allVariables__
The set of all variables of the multidims in this bucket.
bool changed__
Flag used to know if changes has occurred in the bucket since last computation.
std::string name__
The class name.
HashTable< const Instantiation *, GUM_SCALAR > slavesValue__
This table is used to keep the last value computed for an instantiation when the value are computed o...
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
void setBufferSize(Size amount)
Changes the amount of memory allowed for this bucket.
virtual void replace_(const DiscreteVariable *x, const DiscreteVariable *y) override
Replace variable x by y.
const Set< const DiscreteVariable *> & allVariables() const
Returns the sequence of all the variables contained in the bucket.
virtual bool contains(const DiscreteVariable &v) const override
Returns true if var is in *this.
const HashTable< const MultiDimContainer< GUM_SCALAR > *, Instantiation *> & multidims() const
Returns the MultiDimContainer and their respective Instantiation.
const std::string & name() const override
Returns the real name of the multiDim implementation.
const std::string errorContent() const
Returns the message content.
Definition: exceptions.h:135
virtual MultiDimAdressable & getMasterRef() override
In order to insure the dereference for decorators, we need to virtualize the access to master pointer...
void add(const MultiDimContainer< GUM_SCALAR > &impl)
Add a MultiDimContainer in the bucket.
GUM_SCALAR computeValue__(const Instantiation &value) const
Compute the value of the final table of this bucket given i.
const T1 & first() const
Returns the first element of the current association.
virtual bool registerSlave(Instantiation &slave) override
Register i as a slave of this MultiDimAdressable.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
void addVariable__(const DiscreteVariable *var)
Add a variable to allVariables__, and do nothing if var is already in the set.
bool end() const
Returns true if the Instantiation reached the end.
void setFirstOut(const Instantiation &i)
Assign the first values in the Instantiation for the variables not in i.