aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
setInst_inl.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 #ifndef DOXYGEN_SHOULD_SKIP_THIS
23 
24 # include <agrum/tools/multidim/implementations/multiDimAdressable.h>
25 
26 // to ease IDE PARSER
27 # include <agrum/tools/multidim/setInst.h>
28 
29 namespace gum {
30 
31  // indicates whether a given variable belongs to the SetInst
32 
33  INLINE bool SetInst::contains(const DiscreteVariable& v) const { return _vars_.exists(&v); }
34 
35  // indicates whether a given variable belongs to the SetInst
36 
37  INLINE bool SetInst::contains(const DiscreteVariable* v) const { return _vars_.exists(v); }
38 
39  // modifies internally the value of a given variable of the sequence
40 
42  // Size oldVal = _vals_[varPos];
43  _vals_[varPos] = Idx(1) << newVal;
44 
45  // if ( _master_ )
46  // _master_->changeNotification( *this, _vars_[varPos], oldVal, newVal
47  // );
48  }
49 
50  // modifies the value of a given variable of the sequence (external function)
51 
52  INLINE SetInst& SetInst::chgVal(const DiscreteVariable& v, Idx newVal) {
53  try {
54  // check that the variable does belong to the SetInst and that the new
55  // value is possible.
56  Idx varPos = _vars_.pos(&v); // throws NotFound if v doesn't belong to this
57 
58  if (newVal >= v.domainSize()) GUM_ERROR(OutOfBounds, "")
59 
60  // if we were in overflow, indicate that we are not anymore
61  _overflow_ = false;
62 
64 
65  return *this;
66  } catch (NotFound&) {
67  std::string name = "SetInst does not contain this DiscreteVariable: ";
69  }
70  }
71 
73  try {
74  // check that the variable does belong to the SetInst and that the new
75  // value is possible.
76  Idx varPos = _vars_.pos(v); // throws NotFound if v doesn't belong to this
77 
78  if (newVal >= v->domainSize()) GUM_ERROR(OutOfBounds, "")
79 
80  // if we were in overflow, indicate that we are not anymore
81  _overflow_ = false;
82 
84 
85  return *this;
86  } catch (NotFound&) {
87  std::string name = "SetInst does not contain this DiscreteVariable: ";
89  }
90  }
91 
92  // modifies the value of a given variable of the sequence (external function)
93 
95  // check that the variable does belong to the SetInst and that the new
96  // value is possible.
97  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
98 
100 
101  // if we were in overflow, indicate that we are not anymore
102  _overflow_ = false;
103 
105 
106  return *this;
107  }
108 
109  // modifies internally the value of a given variable of the sequence
110 
111  INLINE void SetInst::_chgVals_(Idx varPos, const Size newVals) {
112  // Size oldVal = _vals_[varPos];
113  _vals_[varPos] = 0;
114  _vals_[varPos] = newVals;
115 
116  // if ( _master_ )
117  // _master_->changeNotification( *this, _vars_[varPos], oldVal, newVals
118  // );
119  }
120 
121  // modifies the value of a given variable of the sequence (external function)
122 
124  try {
125  // check that the variable does belong to the SetInst and that the new
126  // value is possible.
127  Idx varPos = _vars_.pos(&v); // throws NotFound if v doesn't belong to this
128 
129  if (newVals >= (Size)1 << v.domainSize()) GUM_ERROR(OutOfBounds, "")
130 
131  // if we were in overflow, indicate that we are not anymore
132  _overflow_ = false;
133 
135 
136  return *this;
137  } catch (NotFound&) {
138  std::string name = "SetInst does not contain this DiscreteVariable: ";
140  }
141  }
142 
144  try {
145  // check that the variable does belong to the SetInst and that the new
146  // value is possible.
147  Idx varPos = _vars_.pos(v); // throws NotFound if v doesn't belong to this
148 
149  if (newVals >= (Size)1 << v->domainSize()) GUM_ERROR(OutOfBounds, "")
150 
151  // if we were in overflow, indicate that we are not anymore
152  _overflow_ = false;
153 
155 
156  return *this;
157  } catch (NotFound&) {
158  std::string name = "SetInst does not contain this DiscreteVariable: ";
159  GUM_ERROR(NotFound, name + v->name())
160  }
161  }
162 
163  // modifies the value of a given variable of the sequence (external function)
164 
166  // check that the variable does belong to the SetInst and that the new
167  // value is possible.
168  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
169 
170  if (newVal >= (Size)1 << _vars_[varPos]->domainSize()) GUM_ERROR(OutOfBounds, "")
171 
172  // if we were in overflow, indicate that we are not anymore
173  _overflow_ = false;
174 
176 
177  return *this;
178  }
179 
181  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
182 
184 
185  _chgVals_(varPos, (Idx(1) << newVal) | _vals_[varPos]);
186  return *this;
187  }
188 
190  try {
191  // check that the variable does belong to the SetInst and that the new
192  // value is possible.
193  Idx varPos = _vars_.pos(v); // throws NotFound if v doesn't belong to this
194 
195  if (newVal >= v->domainSize()) GUM_ERROR(OutOfBounds, "")
196 
197  // if we were in overflow, indicate that we are not anymore
198  _overflow_ = false;
199 
200  addVal(varPos, newVal);
201 
202  return *this;
203  } catch (NotFound&) {
204  std::string name = "SetInst does not contain this DiscreteVariable: ";
205  GUM_ERROR(NotFound, name + v->name())
206  }
207  }
208 
210  try {
211  // check that the variable does belong to the SetInst and that the new
212  // value is possible.
213  Idx varPos = _vars_.pos(&v); // throws NotFound if v doesn't belong to this
214 
215  if (newVal >= v.domainSize()) GUM_ERROR(OutOfBounds, "")
216 
217  // if we were in overflow, indicate that we are not anymore
218  _overflow_ = false;
219 
220  addVal(varPos, newVal);
221 
222  return *this;
223  } catch (NotFound&) {
224  std::string name = "SetInst does not contain this DiscreteVariable: ";
226  }
227  }
228 
230  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
231 
232  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
233 
235  return *this;
236  }
237 
239  try {
240  // check that the variable does belong to the SetInst and that the new
241  // value is possible.
242  Idx varPos = _vars_.pos(v); // throws NotFound if v doesn't belong to this
243 
244  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
245 
246  // if we were in overflow, indicate that we are not anymore
247 
249 
250  return *this;
251  } catch (NotFound&) {
252  std::string name = "SetInst does not contain this DiscreteVariable: ";
253  GUM_ERROR(NotFound, name + v->name())
254  }
255  }
256 
258  try {
259  // check that the variable does belong to the SetInst and that the new
260  // value is possible.
261  Idx varPos = _vars_.pos(&v); // throws NotFound if v doesn't belong to this
262 
263  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
264 
265  // if we were in overflow, indicate that we are not anymore
266  _overflow_ = false;
267 
269 
270  return *this;
271  } catch (NotFound&) {
272  std::string name = "SetInst does not contain this DiscreteVariable: ";
274  }
275  }
276 
278  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
279 
281 
282  _chgVals_(varPos, ~(1 << newVal) & _vals_[varPos]);
283  return *this;
284  }
285 
287  try {
288  // check that the variable does belong to the SetInst and that the new
289  // value is possible.
290  Idx varPos = _vars_.pos(v); // throws NotFound if v doesn't belong to this
291 
292  if (newVal >= v->domainSize()) GUM_ERROR(OutOfBounds, "")
293 
294  // if we were in overflow, indicate that we are not anymore
295 
296  remVal(varPos, newVal);
297 
298  return *this;
299  } catch (NotFound&) {
300  std::string name = "SetInst does not contain this DiscreteVariable: ";
301  GUM_ERROR(NotFound, name + v->name())
302  }
303  }
304 
306  try {
307  // check that the variable does belong to the SetInst and that the new
308  // value is possible.
309  Idx varPos = _vars_.pos(&v); // throws NotFound if v doesn't belong to this
310 
311  if (newVal >= v.domainSize()) GUM_ERROR(OutOfBounds, "")
312 
313  // if we were in overflow, indicate that we are not anymore
314  _overflow_ = false;
315 
316  remVal(varPos, newVal);
317 
318  return *this;
319  } catch (NotFound&) {
320  std::string name = "SetInst does not contain this DiscreteVariable: ";
322  }
323  }
324 
326  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
327 
328  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
329 
331  return *this;
332  }
333 
335  try {
336  // check that the variable does belong to the SetInst and that the new
337  // value is possible.
338  Idx varPos = _vars_.pos(v); // throws NotFound if v doesn't belong to this
339 
340  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
341 
342  // if we were in overflow, indicate that we are not anymore
343 
345 
346  return *this;
347  } catch (NotFound&) {
348  std::string name = "SetInst does not contain this DiscreteVariable: ";
349  GUM_ERROR(NotFound, name + v->name())
350  }
351  }
352 
354  try {
355  // check that the variable does belong to the SetInst and that the new
356  // value is possible.
357  Idx varPos = _vars_.pos(&v); // throws NotFound if v doesn't belong to this
358 
359  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
360 
361  // if we were in overflow, indicate that we are not anymore
362  _overflow_ = false;
363 
365 
366  return *this;
367  } catch (NotFound&) {
368  std::string name = "SetInst does not contain this DiscreteVariable: ";
370  }
371  }
372 
374  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
375 
377 
379  return *this;
380  }
381 
383  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
384 
385  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
386 
388  return *this;
389  }
390 
392  try {
393  // check that the variable does belong to the SetInst and that the new
394  // value is possible.
395  Idx varPos = _vars_.pos(v); // throws NotFound if v doesn't belong to this
396 
397  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
398 
399  // if we were in overflow, indicate that we are not anymore
400 
402 
403  return *this;
404  } catch (NotFound&) {
405  std::string name = "SetInst does not contain this DiscreteVariable: ";
406  GUM_ERROR(NotFound, name + v->name())
407  }
408  }
409 
411  try {
412  // check that the variable does belong to the SetInst and that the new
413  // value is possible.
414  Idx varPos = _vars_.pos(&v); // throws NotFound if v doesn't belong to this
415 
416  if (newVal >= (Size(1) << _vars_[varPos]->domainSize())) GUM_ERROR(OutOfBounds, "")
417 
418  // if we were in overflow, indicate that we are not anymore
419  _overflow_ = false;
420 
422 
423  return *this;
424  } catch (NotFound&) {
425  std::string name = "SetInst does not contain this DiscreteVariable: ";
427  }
428  }
429 
431  if (_vals_.size() <= varPos) GUM_ERROR(NotFound, "")
432 
434 
435  _chgVals_(varPos, (Size(1) << newVal) & _vals_[varPos]);
436  return *this;
437  }
438 
440  try {
441  // check that the variable does belong to the SetInst and that the new
442  // value is possible.
443  Idx varPos = _vars_.pos(v); // throws NotFound if v doesn't belong to this
444 
445  if (newVal >= v->domainSize()) GUM_ERROR(OutOfBounds, "")
446 
447  // if we were in overflow, indicate that we are not anymore
448 
450 
451  return *this;
452  } catch (NotFound&) {
453  std::string name = "SetInst does not contain this DiscreteVariable: ";
454  GUM_ERROR(NotFound, name + v->name())
455  }
456  }
457 
459  try {
460  // check that the variable does belong to the SetInst and that the new
461  // value is possible.
462  Idx varPos = _vars_.pos(&v); // throws NotFound if v doesn't belong to this
463 
464  if (newVal >= v.domainSize()) GUM_ERROR(OutOfBounds, "")
465 
466  // if we were in overflow, indicate that we are not anymore
467  _overflow_ = false;
468 
470 
471  return *this;
472  } catch (NotFound&) {
473  std::string name = "SetInst does not contain this DiscreteVariable: ";
475  }
476  }
477 
478  // adds a new var to the sequence of vars
479 
480  INLINE void SetInst::add(const DiscreteVariable& v) {
481  // if _master_ : not allowed
482  // if ( _master_ ) GUM_ERROR( OperationNotAllowed, "in slave SetInst" )
483 
484  // check if the variable already belongs to the tuple of variables
485  // of the SetInst
486  if (_vars_.exists(&v))
487  GUM_ERROR(DuplicateElement, "Variable '" << v.name() << "' already exists in this SetInst")
488 
489  // actually add the new dimension
490  _add_(v);
491  }
492 
493  // removes a variable from the sequence of vars
494 
495  INLINE void SetInst::erase(const DiscreteVariable& v) {
496  // if _master_ : not allowed
497  // if ( _master_ ) GUM_ERROR( OperationNotAllowed, "in slave SetInst" )
498 
499  // check that the variable does actually belong to the SetInst
500  if (!_vars_.exists(&v)) GUM_ERROR(NotFound, "Var does not exist in this SetInst")
501 
502  // actually delete the dimension
503  _erase_(v);
504  }
505 
506  // removes everything
507  INLINE void SetInst::clear() {
508  // if ( _master_ ) GUM_ERROR( OperationNotAllowed, "in slave SetInst" )
509 
510  _vars_.clear();
511  _vals_.clear();
512  }
513 
514  /** @brief returns the product of the size of the domains of the variables
515  * belonging to the matrix */
516 
517  INLINE Size SetInst::domainSize() const {
518  Size s = 1;
519 
520  for (const auto var: _vars_)
521  s *= var->domainSize();
522 
523  return s;
524  }
525 
526  // returns the index of a var
527 
528  INLINE Idx SetInst::pos(const DiscreteVariable& k) const { return _vars_.pos(&k); }
529 
530  // Default constructor
531 
532  INLINE SetInst::SetInst() : /* _master_( 0 ),*/ _overflow_(false) { GUM_CONSTRUCTOR(SetInst); }
533 
534  // destructor
535 
536  INLINE SetInst::~SetInst() {
538  // unregister the SetInst from its _master_
539 
540  // if ( _master_ ) _master_->unregisterSlave( *this );
541  }
542 
543  // returns the number of vars in the sequence
544 
545  INLINE Idx SetInst::nbrDim() const { return _vars_.size(); }
546 
547  // returns the current value of a given variable
548 
549  INLINE Size SetInst::vals(Idx i) const {
550  if (i >= _vals_.size()) GUM_ERROR(NotFound, "")
551 
552  return _vals_[i];
553  }
554 
555  INLINE Size SetInst::vals(const DiscreteVariable& var) const { return _vals_[_vars_.pos(&var)]; }
556 
557  INLINE Size SetInst::vals(const DiscreteVariable* var) const { return _vals_[_vars_.pos(var)]; }
558 
559  INLINE Idx SetInst::val(const DiscreteVariable* var) const {
560  Idx n = 0;
562 
563  if (_vals_[_vars_.pos(var)] % 2 == 0) {
564  while (value & 1) {
565  n++;
566  value >>= 1;
567  }
568 
569  return n;
570  } else
571  GUM_ERROR(NotFound, "There is more than one value ")
572  }
573 
575  Idx n = 0;
576  Size val = _vals_[_vars_.pos(&var)];
577 
578  while (val) {
579  n += (val & 1);
580  val >>= 1;
581  }
582 
583  return n;
584  }
585 
586  INLINE Idx SetInst::val(const DiscreteVariable& var) const {
587  Idx n = 0;
588  Size value = _vals_[_vars_.pos(&var)];
589 
590  if (nbrOccurences(var) == 1) {
591  while (value > 1) {
592  n++;
593  value >>= 1;
594  }
595 
596  return n;
597  } else
598  GUM_ERROR(NotFound, "There is more than one value ")
599  }
600 
601  // returns the variable at position i in the tuple
602 
603  INLINE const DiscreteVariable& SetInst::variable(Idx i) const { return *(_vars_.atPos(i)); }
604 
605  // indicates whether the current value of the tuple is correct or not
606 
607  INLINE bool SetInst::inOverflow() const { return _overflow_; }
608 
609  // end() just is a synonym for inOverflow()
610 
611  INLINE bool SetInst::end() const { return inOverflow(); }
612 
613  // rend() just is a synonym for inOverflow()
614 
615  INLINE bool SetInst::rend() const { return inOverflow(); }
616 
617  // indicates that the current value is correct even if it should be in
618  // overflow
619 
620  INLINE void SetInst::unsetOverflow() { _overflow_ = false; }
621 
622  // alias for unsetOverflow
623 
624  INLINE void SetInst::unsetEnd() { _overflow_ = false; }
625 
626  // reorder vars in *this
627  INLINE void SetInst::reorder(const SetInst& i) { reorder(i.variablesSequence()); }
628 
629  // change values with those in i
630 
631  INLINE SetInst& SetInst::chgValIn(const SetInst& i) {
632  _overflow_ = false;
633  Idx s = i.nbrDim();
634 
635  for (Size p = 0; p < s; ++p)
636  if (contains(i.variable(p)))
637  // __vals[pos( i.variable( p ) )] = i.val( p );
639 
640  return *this;
641  }
642 
643  // returns the sequence of DiscreteVariable
644 
645  INLINE const Sequence< const DiscreteVariable* >& SetInst::variablesSequence() const {
646  return _vars_;
647  }
648 
649  // replace 2 vars in the SetInst
650 
651  INLINE void SetInst::_swap_(Idx i, Idx j) {
652  if (i == j) return;
653 
654  _vars_.swap(i, j);
655 
656  Size v;
657 
658  v = _vals_[i];
659 
660  _vals_[i] = _vals_[j];
661 
662  _vals_[j] = v;
663  }
664 
665  // reordering
666 
667  INLINE void SetInst::reorder(const Sequence< const DiscreteVariable* >& original) {
668  Idx max = original.size();
669  Idx position = 0;
670 
671  for (Idx i = 0; i < max; ++i) {
672  const DiscreteVariable* pv = original.atPos(i);
673 
674  if (contains(pv)) {
675  GUM_ASSERT(pos(*pv) >= position); // this var should not be
676  // already placed.
677  _swap_(position, pos(*pv));
678  position++;
679  }
680  }
681  }
682 
683  // adds a new var to the sequence of vars
684 
685  INLINE void SetInst::_add_(const DiscreteVariable& v) {
686  _vars_.insert(&v);
687  _vals_.push_back(1);
688  _overflow_ = false;
689  }
690 
691  // removes a variable from the sequence of vars
692 
693  INLINE void SetInst::_erase_(const DiscreteVariable& v) {
694  // get the position of the variable
695  Idx pos = _vars_.pos(&v);
696  _vars_.erase(&v);
697  _vals_.erase(_vals_.begin() + pos);
698  }
699 
700  // is this empty ?
701  INLINE bool SetInst::empty() const { return _vals_.empty(); }
702 
703  // Replace x by y.
704  INLINE void SetInst::replace_(const DiscreteVariable* x, const DiscreteVariable* y) {
706  }
707 } /* namespace gum */
708 
709 #endif // DOXYGEN_SHOULD_SKIP_THIS
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643