aGrUM  0.14.3
instantiation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
29 
30 #ifdef GUM_NO_INLINE
32 #endif /* GUM_NO_INLINE */
33 
34 namespace gum {
35 
36  // Default constructor
37  Instantiation::Instantiation() : __master(nullptr), __overflow(false) {
38  GUM_CONSTRUCTOR(Instantiation);
39  }
40 
41  // destructor
43  GUM_DESTRUCTOR(Instantiation);
44  // unregister the Instantiation from its __master
45 
46  if (__master) __master->unregisterSlave(*this);
47  }
48 
50  // for speed issues
51  GUM_ASSERT(master != nullptr);
52 
54  __vars.resize(v.size());
55  __vals.reserve(v.size());
56  // fill the instantiation
57 
58  for (const auto var : v)
59  __add(*var);
60 
61  actAsSlave(master->getMasterRef());
62  }
63 
64  // constructor for a Instantiation contained into a MultiDimInterface
66  __master(0), __overflow(false) {
67  // for debugging purposes
68  GUM_CONSTRUCTOR(Instantiation);
69  __init(&d);
70  }
71 
73  __master(0), __overflow(false) {
74  // for debugging purposes
75  GUM_CONSTRUCTOR(Instantiation);
76  __init(const_cast< MultiDimAdressable* >(&d));
77  }
78 
79  // constructor for a Instantiation contained into a MultiDimInterface
81  __master(0), __overflow(false) {
82  // for debugging purposes
83  GUM_CONSTRUCTOR(Instantiation);
84 
85  if (d) __init(d);
86  }
87 
88  // constructor for a Instantiation contained into a MultiDimInterface this
89  // constructor is needed in order to allow creation of Instantiation(this) in
90  // MultiDimAdressable and below
92  __master(0), __overflow(false) {
93  // for debugging purposes
94  GUM_CONSTRUCTOR(Instantiation);
95 
96  if (const_d) __init(const_cast< MultiDimAdressable* >(const_d));
97  }
98 
99  // copy constructor
100  Instantiation::Instantiation(const Instantiation& aI, const bool notifyMaster) :
101  MultiDimInterface(), __master(0), __overflow(false) {
102  // for debugging purposes
103  GUM_CONS_CPY(Instantiation);
104  // copy the content of aI
105  __vars = aI.__vars;
106  __vals = aI.__vals;
107  __overflow = aI.__overflow;
108 
109  if (aI.__master && notifyMaster) actAsSlave(*aI.__master);
110  }
111 
112  // operator=
114  if (__master) {
115  if (!aI.isMaster(__master)) { // aI as the same master.
116  if (nbrDim() != aI.nbrDim()) {
117  GUM_ERROR(OperationNotAllowed, "in slave Instantiation");
118  }
119 
120  for (Idx i = 0; i < nbrDim(); i++) {
121  if ((!contains(aI.variable(i))) || (!aI.contains(variable(i)))) {
122  GUM_ERROR(OperationNotAllowed, "in slave Instantiation");
123  }
124  }
125  }
126 
127  setVals(aI);
128  } else {
129  // copy the content of aI
130  __vars = aI.__vars;
131  __vals = aI.__vals;
132  __overflow = aI.__overflow;
133 
134  if (aI.__master) actAsSlave(*aI.__master);
135  }
136 
137  return *this;
138  }
139 
140  // Gives a string version of a Instantiation
141  std::string Instantiation::toString() const {
142  std::stringstream sstr;
143  // check if the value of the instantiation is correct
144 
145  if (__overflow) { sstr << "<invalid>"; }
146 
147  sstr << "<";
148 
149  bool first = true;
150 
151  for (const auto var : __vars) {
152  if (!first) sstr << "|";
153 
154  first = false;
155  sstr << var->name() << ":" << var->label(val(*var));
156  }
157 
158  sstr << ">";
159 
160  return sstr.str();
161  }
162 
163  // give a Id value for Hamming distance
165  Idx res = 0;
166 
167  for (const auto var : __vars)
168  res += val(*var);
169 
170  return res;
171  }
172 
175  const Instantiation& external) {
176  for (const auto& elt : map) {
177  const DiscreteVariable& var = *elt.second;
178 
179  try {
180  Idx val = external.val(*elt.first);
181 
182  try {
183  chgVal(var, val);
184  } catch (NotFound&) {
186  var.name() << " : missing variable in instantiation");
187  }
188  } catch (NotFound&) {
190  var.name() << " : missing variable in external instantiation");
191  }
192  }
193  }
194 
196  Idx newVal,
197  Idx oldVal) const {
198  if (__master)
199  __master->changeNotification(*this, __vars[varPos], oldVal, newVal);
200  }
201 
204  }
205 
207  if (__master) __master->setIncNotification(*this);
208  }
211  }
213  if (__master) __master->setDecNotification(*this);
214  }
215 
216  // deassociate the master MultiDimAdressable, if any
218  if (__master) {
219  __master->unregisterSlave(*this);
220  __master = nullptr;
221  }
222  return true;
223  }
224  // force the variables sequence order to be the same as the master one
226  if (m != __master) {
227  GUM_ERROR(OperationNotAllowed, "only master can do this");
228  }
229 
231  }
232  // erase new dim by master
234  const DiscreteVariable& v) {
235  if (m != __master) {
236  GUM_ERROR(OperationNotAllowed, "only master can do this");
237  }
238 
239  __erase(v);
240 
242  }
243 
244  // tries to register the Instantiation to a MultiDimAdressable
246  // if __master : not allowed
247  if (__master != nullptr) {
248  GUM_ERROR(OperationNotAllowed, "in slave Instantiation");
249  }
250 
251  __master = &aMD;
252 
253  // perform the registration
254  if (aMD.registerSlave(*this)) {
255  return true;
256  } else {
257  __master = nullptr;
258  return false;
259  }
260  }
261 
262  // an operator for user-friendly displaying the content of a Instantiation
263  std::ostream& operator<<(std::ostream& aStream, const Instantiation& i) {
264  aStream << i.toString();
265  return aStream;
266  }
267 
268 } /* namespace gum */
void __erase(const DiscreteVariable &v)
Removes a variable from the sequence of vars.
void __init(MultiDimAdressable *master)
Initialize this Instantiation.
bool __overflow
Indicates whether the current value of the tuple is valid when we loop sufficiently over values of th...
virtual void setFirstNotification(const Instantiation &i)=0
Listen to setFirst in a given Instantiation.
void __masterDecNotification() const
~Instantiation()
Destructor.
Idx nbrDim() const final
Returns the number of variables in the Instantiation.
Size size() const noexcept
Returns the size of the sequence.
Definition: sequence_tpl.h:35
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1019
Sequence< const DiscreteVariable *> __vars
The tuple of variables to be instantiated.
bool forgetMaster()
Deassociate the master MultiDimAdressable, if any.
virtual void setChangeNotification(const Instantiation &i)=0
Listen to an assignment of a value in a Instantiation.
void __masterIncNotification() const
virtual bool registerSlave(Instantiation &i)=0
Register i as a slave of this MultiDimAdressable.
Instantiation & chgVal(const DiscreteVariable &v, Idx newval)
Assign newval to variable v in the Instantiation.
Interface for all classes addressing in a multiDim fashion.
Base class for discrete random variable.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
Instantiation & setVals(const Instantiation &i)
Assign the values from i in the Instantiation.
virtual void setIncNotification(const Instantiation &i)=0
Listen to increment in a given Instantiation.
The class for generic Hash Tables.
Definition: hashTable.h:676
Idx val(Idx i) const
Returns the current value of the variable at position i.
std::ostream & operator<<(std::ostream &output, const BayesNet< GUM_SCALAR > &bn)
Prints map&#39;s DAG in output using the Graphviz-dot format.
Definition: BayesNet_tpl.h:583
virtual bool unregisterSlave(Instantiation &i)=0
Unregister i as a slave of this MultiDimAdressable.
Header files of gum::Instantiation.
std::string toString() const
Give a string version of instantiation.
void __reorder(const Sequence< const DiscreteVariable * > &v)
Reorder vars of this instantiation giving the order in v.
Idx hamming() const
Returns the hamming distance of this instantiation.
void __masterFirstNotification() const
virtual void setLastNotification(const Instantiation &i)=0
Listen to setLast in a given Instantiation.
void __masterLastNotification() const
MultiDimAdressable * __master
The master, if any, contains precisely the set of variables to be instantiated.
Abstract base class for all multi dimensionnal addressable.
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
bool contains(const DiscreteVariable &v) const final
Indicates whether a given variable belongs to the Instantiation.
void setValsFrom(const HashTable< const DiscreteVariable *, const DiscreteVariable * > &map, const Instantiation &external)
Assign the values of external in *this, using map as a bijection between external and this variables...
bool isMaster(const MultiDimAdressable *m) const
Indicates whether m is the master of this instantiation.
void synchronizeWithMaster(const MultiDimAdressable *m)
Force the variables sequence to be the same as the master one.
Instantiation & operator=(const Instantiation &aI)
Copy operator.
Instantiation()
Default constructor: creates an empty tuple.
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:50
virtual void setDecNotification(const Instantiation &i)=0
Listen to increment in each recorded Instantiation.
Inline implemenation of gum::Instantiation.
virtual void changeNotification(const Instantiation &i, const DiscreteVariable *const var, Idx oldval, Idx newval)=0
Listen to changes in a given Instantiation.
bool actAsSlave(MultiDimAdressable &aMD)
Tries to register the Instantiation to a MultiDimAdressable.
const std::string & name() const
returns the name of the variable
const DiscreteVariable & variable(Idx i) const final
Returns the variable at position i in the tuple.
void __add(const DiscreteVariable &v)
Adds a new var to the sequence of vars.
virtual MultiDimAdressable & getMasterRef()=0
In order to insure the dereference for decorators, we need to virtualize the access to master pointer...
void eraseWithMaster(const MultiDimAdressable *m, const DiscreteVariable &v)
Call Instantiation::__erase(const DiscreteVariable&) by master.
Headers for the abstract base class for all multi dimensionnal containers.
void __masterChangeNotification(Idx varPos, Idx newVal, Idx oldVal) const
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
std::vector< Idx > __vals
The current instantiation: the value of the tuple.