aGrUM  0.16.0
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.
virtual void setDecNotification(const Instantiation &i) override
Listen to increment in each recorded Instantiation.
Size __bufferSize
The number of element allowed in __bucket.
Instantiation __allVarsInst
Instantiation over all variable in this.
MultiDimArray< GUM_SCALAR > * __bucket
The result table of this bucket.
HashTable< const MultiDimContainer< GUM_SCALAR > *, Instantiation *> __multiDims
The set of MultiDimContainer in this bucket.
virtual void setChangeNotification(const Instantiation &i) override
Listen to an assignment of a value in a Instantiation.
std::string __name
The class name.
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
bool isBucketEmpty() const
Returns true if this bucket is empty.
const List< Instantiation *> & _slaves() const
Returns a constant reference over the list of slaved instantiations.
virtual const std::string toString() const
Returns a representation of this MultiDimContainer.
A multidim implementation for buckets.
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...
GUM_SCALAR __computeValue(const Instantiation &value) const
Compute the value of the final table of this bucket given i.
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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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.
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.
void __addVariable(const DiscreteVariable *var)
Add a variable to __allVariables, and do nothing if var is already in the set.
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
void __initializeBuffer()
Initialize the internal buffer.
void __eraseBuffer()
Clean the buffer and switch it&#39;s instantiation to this bucket.
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.
virtual void _replace(const DiscreteVariable *x, const DiscreteVariable *y) override
Replace variable x by y.
void inc()
Operator increment.
const MultiDimArray< GUM_SCALAR > & bucket() const
Returns the MultiDimArray used by this MultiDimBucket.
void __eraseVariable(const DiscreteVariable *var)
Erase a variable from __allVariables if no other multidimensional table uses it in this bucket...
Size bucketSize() const
Returns the number of MultiDimContainer in in this bukcet.
MultiDimBucket(Size bufferSize=INT_MAX)
Default constructor.
virtual GUM_SCALAR & _get(const Instantiation &i) const override
void compute(bool force=false) const
This method computes the final table of this 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
Bijection< Instantiation *, Instantiation *> __instantiations
Bijection between instantiations registered on this and their equivalent on __bucket.
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.
bool __changed
Flag used to know if changes has occurred in the bucket since last computation.
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 void _commitMultipleChanges() override
Synchronize content after MultipleChanges.
virtual Size domainSize() const override
Returns the product of the variables domain size.
Set< const DiscreteVariable *> __allVariables
The set of all variables of the multidims in this bucket.
Size bufferSize() const
Returns the amount of memory allowed for this bucket.
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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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.
virtual void _commitMultipleChanges()
Synchronize content after MultipleChanges.
Safe const iterators for Lists.
Definition: list.h:2030
virtual bool registerSlave(Instantiation &i) override
Register i as a slave of this MultiDimAdressable.
<agrum/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 add(const DiscreteVariable &v) final
Adds a new variable in the Instantiation.
void erase(const DiscreteVariable &v) final
Removes a variable from the Instantiation.
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.
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.
virtual void _replace(const DiscreteVariable *x, const DiscreteVariable *y) override
Replace variable x by y.
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
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.