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