aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
multiDimBucket_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Implementation of the MultiDimBucket class.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  * @author Lionel TORTI
28  */
29 
30 #include <agrum/tools/multidim/implementations/multiDimBucket.h>
31 
32 namespace gum {
33 
34  template < typename GUM_SCALAR >
35  MultiDimBucket< GUM_SCALAR >::MultiDimBucket(Size bufferSize) :
36  MultiDimReadOnly< GUM_SCALAR >(), bufferSize__(bufferSize), bucket__(0),
37  changed__(false), name__("MultiDimBucket") {
38  GUM_CONSTRUCTOR(MultiDimBucket);
39  }
40 
41  template < typename GUM_SCALAR >
43  const MultiDimBucket< GUM_SCALAR >& source) :
48  name__("MultiDimBucket") {
50  }
51 
52  template < typename GUM_SCALAR >
56 
59  ++iter) {
60  delete iter.second();
61  }
62 
63  if (bucket__) { delete bucket__; }
64 
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) {
84 
86  for (const auto var: impl->variablesSequence()) {
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];
106 
108  for (auto var: impl->variablesSequence()) {
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 >
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)) {
166 
167  for (values.setFirst(); !values.end(); values.inc()) {
169  }
170  } else if ((bucket__ == 0) && changed__) {
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 >
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)) {
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 {
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 {
263  }
264  }
265 
266  template < typename GUM_SCALAR >
267  INLINE void
269  if (bucket__) {
270  try {
272  *(instantiations__).second(const_cast< Instantiation* >(&i)));
273  } catch (NotFound&) {
274  // Then i is not a slave of this
275  }
276  } else {
278  }
279  }
280 
281  template < typename GUM_SCALAR >
282  INLINE void
284  if (bucket__) {
285  try {
287  *(instantiations__).second(const_cast< Instantiation* >(&i)));
288  } catch (NotFound&) {
289  // Then i is not a slave of this
290  }
291  } else {
293  }
294  }
295 
296  template < typename GUM_SCALAR >
297  INLINE void
299  if (bucket__) {
300  try {
302  *(instantiations__.second(const_cast< Instantiation* >(&i))));
303  } catch (NotFound&) {
304  // Then i is not a slave of this
305  }
306  } else {
308  }
309  }
310 
311  template < typename GUM_SCALAR >
312  INLINE void
314  if (bucket__) {
315  try {
317  *(instantiations__.second(const_cast< Instantiation* >(&i))));
318  } catch (NotFound&) {
319  // Then i is not a slave of this
320  }
321  } else {
323  }
324  }
325 
326  template < typename GUM_SCALAR >
327  INLINE void
329  if (bucket__) {
330  try {
332  *(instantiations__.second(const_cast< Instantiation* >(&i))));
333  } catch (NotFound&) {
334  // Then i is not a slave of this
335  }
336  } else {
338  }
339  }
340 
341  template < typename GUM_SCALAR >
343  if (bucket__) {
344  try {
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);
360  return true;
361  } catch (NotFound&) { return false; }
362  } else {
363  if (slavesValue__.exists(&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 >
384  if (bucket__) {
385  return *bucket__;
386  } else {
387  return *this;
388  }
389  }
390 
391  template < typename GUM_SCALAR >
392  INLINE std::string
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 
410 
411  while (!allVarsInst__.empty()) {
413  }
414 
415  for ( // HashTableIteratorSafe<const MultiDimContainer<GUM_SCALAR>*,
416  // Instantiation*>
418  ++iter) {
419  for (auto var: iter.key()->variablesSequence()) {
421  }
422  }
423 
424  changed__ = true;
425  }
426 
427  template < typename 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 {
439  } catch (DuplicateElement&) {
440  // Nothing to do then!
441  }
442  }
443 
444  template < typename GUM_SCALAR >
446  bool found = false;
447 
451  iter != multiDims__.endSafe();
452  ++iter) {
453  if (iter.key()->contains(*var)) {
454  found = true;
455  break;
456  }
457  }
458 
459  // No one use it, we can safely remove it
460  if (!found) {
463  }
464  }
465 
466  template < typename GUM_SCALAR >
468  if (bucket__) {
470 
473  ++iter) {
474  delete iter.second();
475  }
476 
478  delete bucket__;
479  bucket__ = 0;
480  }
481 
482  // Creating the table.
483  bucket__ = new MultiDimArray< GUM_SCALAR >();
484 
485  for (auto var: this->variablesSequence()) {
486  bucket__->add(*var);
487  }
488 
489  if (!this->slaves_().empty()) {
491  = this->slaves_().cbeginSafe();
492  iter != this->slaves_().cendSafe();
493  ++iter) {
495  }
496  }
497 
498  changed__ = true;
499  }
500 
501  template < typename GUM_SCALAR >
503  if (bucket__) {
505 
508  ++iter) {
509  delete iter.second();
510  }
511 
513  delete bucket__;
514  bucket__ = 0;
515  }
516  }
517 
518  template < typename GUM_SCALAR >
520  const Instantiation& value) const {
521  try {
525 
528  current = (GUM_SCALAR)1;
529 
533  iter != multiDims__.endSafe();
534  ++iter) {
536  current *= iter.key()->get(*(iter.val()));
537  }
538 
539  sum += current;
540  }
541 
542  return sum;
543  } catch (NotFound& e) {
544  std::cerr << std::endl << e.errorContent() << std::endl;
545  // This happens if the bucket is empty.
546  GUM_ERROR(SizeError, "This MultiDimBucket is empty.");
547  }
548  }
549 
550  template < typename GUM_SCALAR >
553  return new MultiDimBucket< GUM_SCALAR >;
554  }
555 
556  template < typename GUM_SCALAR >
559  if (bucket__) {
560  return *bucket__;
561  } else {
562  GUM_ERROR(OperationNotAllowed, "bucket not used.");
563  }
564  }
565 
566  template < typename GUM_SCALAR >
568  const DiscreteVariable* y) {
571 
574  ++iter) {
575  iter.first()->replace(*x, *y);
576  iter.second()->replace(*x, *y);
577  }
578 
579  if (bucket__) bucket__->replace(*x, *y);
580 
583  allVarsInst__.replace(*x, *y);
584  }
585 
586  template < typename GUM_SCALAR >
589  return multiDims__;
590  }
591 
592 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669