aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
multiDimBucket_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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), _changed_(false),
37  _name_("MultiDimBucket") {
38  GUM_CONSTRUCTOR(MultiDimBucket);
39  }
40 
41  template < typename GUM_SCALAR >
47  }
48 
49  template < typename GUM_SCALAR >
53 
55  delete iter.second();
56  }
57 
58  if (_bucket_) { delete _bucket_; }
59 
63  ++iter) {
64  delete iter.val();
65  }
66  }
67 
68  template < typename GUM_SCALAR >
70  this->add(&impl);
71  }
72 
73  template < typename GUM_SCALAR >
76 
78  for (const auto var: impl->variablesSequence()) {
80  }
81  }
82 
83  _changed_ = true;
84  }
85 
86  template < typename GUM_SCALAR >
88  this->erase(&impl);
89  }
90 
91  template < typename GUM_SCALAR >
93  try {
94  delete _multiDims_[impl];
96 
98  for (auto var: impl->variablesSequence()) {
100  }
101  }
102 
103  _changed_ = true;
104  } catch (NotFound&) {
105  // Do nothing
106  }
107  }
108 
109  template < typename GUM_SCALAR >
110  INLINE bool
112  return _multiDims_.exists(&impl);
113  }
114 
115  template < typename GUM_SCALAR >
117  return _allVariables_;
118  }
119 
120  template < typename GUM_SCALAR >
122  return _multiDims_.size();
123  }
124 
125  template < typename GUM_SCALAR >
127  return _multiDims_.empty();
128  }
129 
130  template < typename GUM_SCALAR >
132  return _changed_;
133  }
134 
135  template < typename GUM_SCALAR >
137  return _bufferSize_;
138  }
139 
140  template < typename GUM_SCALAR >
143 
144  if ((this->domainSize() > _bufferSize_) && (_bucket_ != 0)) {
145  _eraseBuffer_();
146  } else if (_bucket_ == 0) {
148  }
149  }
150 
151  template < typename GUM_SCALAR >
152  void MultiDimBucket< GUM_SCALAR >::compute(bool force) const {
153  if ((_bucket_) && (_changed_ || force)) {
155 
156  for (values.setFirst(); !values.end(); values.inc()) {
158  }
159  } else if ((_bucket_ == 0) && _changed_) {
161  _changed_ = false;
162  }
163 
164  _changed_ = false;
165  }
166 
167  template < typename GUM_SCALAR >
168  const std::string& MultiDimBucket< GUM_SCALAR >::name() const {
169  return _name_;
170  }
171 
172  template < typename GUM_SCALAR >
175 
177  if (this->domainSize() <= _bufferSize_) {
178  if (_bucket_)
179  _bucket_->add(v);
180  else
182  } else if (_bucket_) {
183  _eraseBuffer_();
184  }
185  }
186  }
187 
188  template < typename GUM_SCALAR >
191 
193  && (this->domainSize() <= _bufferSize_)) {
194  if (_bucket_) {
195  _bucket_->erase(v);
196  } else {
198  }
199  }
200  }
201 
202  template < typename GUM_SCALAR >
204  return (_bucket_) ? _bucket_->realSize() : (Size)0;
205  }
206 
207  template < typename GUM_SCALAR >
210  }
211 
212  template < typename GUM_SCALAR >
214  compute();
215 
216  if (_bucket_) {
217  try {
218  return _bucket_->get(*(_instantiations_.second(const_cast< Instantiation* >(&i))));
219  } catch (NotFound&) { return _bucket_->get(i); }
220  } else if (i.isMaster(this)) {
222 
223  return _slavesValue_[&i];
224  } else {
225  return _computeValue_(i);
226  }
227  }
228 
229  template < typename GUM_SCALAR >
231  const DiscreteVariable* const var,
232  Idx oldval,
233  Idx newval) {
234  if (_bucket_) {
235  try {
237  var,
238  oldval,
239  newval);
240  } catch (NotFound&) {
241  // Then i is not a slave of this
242  }
243  } else {
245  }
246  }
247 
248  template < typename GUM_SCALAR >
250  if (_bucket_) {
251  try {
253  *(_instantiations_).second(const_cast< Instantiation* >(&i)));
254  } catch (NotFound&) {
255  // Then i is not a slave of this
256  }
257  } else {
259  }
260  }
261 
262  template < typename GUM_SCALAR >
264  if (_bucket_) {
265  try {
267  } catch (NotFound&) {
268  // Then i is not a slave of this
269  }
270  } else {
272  }
273  }
274 
275  template < typename GUM_SCALAR >
277  if (_bucket_) {
278  try {
280  } catch (NotFound&) {
281  // Then i is not a slave of this
282  }
283  } else {
285  }
286  }
287 
288  template < typename GUM_SCALAR >
290  if (_bucket_) {
291  try {
293  } catch (NotFound&) {
294  // Then i is not a slave of this
295  }
296  } else {
298  }
299  }
300 
301  template < typename GUM_SCALAR >
303  if (_bucket_) {
304  try {
306  *(_instantiations_.second(const_cast< Instantiation* >(&i))));
307  } catch (NotFound&) {
308  // Then i is not a slave of this
309  }
310  } else {
312  }
313  }
314 
315  template < typename GUM_SCALAR >
317  if (_bucket_) {
318  try {
320  } catch (DuplicateElement&) { return false; }
321  }
322 
324  }
325 
326  template < typename GUM_SCALAR >
329 
330  if (_bucket_) {
331  try {
332  delete _instantiations_.second(&i);
334  return true;
335  } catch (NotFound&) { return false; }
336  } else {
337  if (_slavesValue_.exists(&i)) {
339  return true;
340  } else {
341  return false;
342  }
343  }
344  }
345 
346  template < typename GUM_SCALAR >
348  if (_bucket_) {
349  return *_bucket_;
350  } else {
351  return *this;
352  }
353  }
354 
355  template < typename GUM_SCALAR >
357  if (_bucket_) {
358  return *_bucket_;
359  } else {
360  return *this;
361  }
362  }
363 
364  template < typename GUM_SCALAR >
367  sBuff << (*i) << " = " << get(*i);
368  return sBuff.str();
369  }
370 
371  template < typename GUM_SCALAR >
374 
375  if (this->domainSize() <= _bufferSize_) {
377  } else {
378  _eraseBuffer_();
379  }
380 
382 
383  while (!_allVarsInst_.empty()) {
385  }
386 
387  for ( // HashTableIteratorSafe<const MultiDimContainer<GUM_SCALAR>*,
388  // Instantiation*>
389  auto iter = _multiDims_.beginSafe(); iter != _multiDims_.endSafe(); ++iter) {
390  for (auto var: iter.key()->variablesSequence()) {
392  }
393  }
394 
395  _changed_ = true;
396  }
397 
398  template < typename GUM_SCALAR >
400  GUM_ERROR(OperationNotAllowed, "a MultiDimBucket is a read only MultiDim")
401  }
402 
403  template < typename GUM_SCALAR >
405  try {
408  } catch (DuplicateElement&) {
409  // Nothing to do then!
410  }
411  }
412 
413  template < typename GUM_SCALAR >
415  bool found = false;
416 
419  iter != _multiDims_.endSafe();
420  ++iter) {
421  if (iter.key()->contains(*var)) {
422  found = true;
423  break;
424  }
425  }
426 
427  // No one use it, we can safely remove it
428  if (!found) {
431  }
432  }
433 
434  template < typename GUM_SCALAR >
436  if (_bucket_) {
438 
440  delete iter.second();
441  }
442 
444  delete _bucket_;
445  _bucket_ = 0;
446  }
447 
448  // Creating the table.
449  _bucket_ = new MultiDimArray< GUM_SCALAR >();
450 
451  for (auto var: this->variablesSequence()) {
452  _bucket_->add(*var);
453  }
454 
455  if (!this->slaves_().empty()) {
457  iter != this->slaves_().cendSafe();
458  ++iter) {
460  }
461  }
462 
463  _changed_ = true;
464  }
465 
466  template < typename GUM_SCALAR >
468  if (_bucket_) {
470 
472  delete iter.second();
473  }
474 
476  delete _bucket_;
477  _bucket_ = 0;
478  }
479  }
480 
481  template < typename GUM_SCALAR >
483  try {
487 
489  current = (GUM_SCALAR)1;
490 
493  iter != _multiDims_.endSafe();
494  ++iter) {
496  current *= iter.key()->get(*(iter.val()));
497  }
498 
499  sum += current;
500  }
501 
502  return sum;
503  } catch (NotFound& e) {
504  std::cerr << std::endl << e.errorContent() << std::endl;
505  // This happens if the bucket is empty.
506  GUM_ERROR(SizeError, "This MultiDimBucket is empty.")
507  }
508  }
509 
510  template < typename GUM_SCALAR >
512  return new MultiDimBucket< GUM_SCALAR >;
513  }
514 
515  template < typename GUM_SCALAR >
517  if (_bucket_) {
518  return *_bucket_;
519  } else {
520  GUM_ERROR(OperationNotAllowed, "bucket not used.")
521  }
522  }
523 
524  template < typename GUM_SCALAR >
526  const DiscreteVariable* y) {
529 
531  iter.first()->replace(*x, *y);
532  iter.second()->replace(*x, *y);
533  }
534 
535  if (_bucket_) _bucket_->replace(*x, *y);
536 
539  _allVarsInst_.replace(*x, *y);
540  }
541 
542  template < typename GUM_SCALAR >
545  return _multiDims_;
546  }
547 
548 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643