aGrUM  0.13.2
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  // the object that casts correctly the discrete variable sequences
37  // within the hash table of instantiations
40 
41  // Default constructor
42  Instantiation::Instantiation() : __master(nullptr), __overflow(false) {
43  GUM_CONSTRUCTOR(Instantiation);
44  }
45 
46  // destructor
48  GUM_DESTRUCTOR(Instantiation);
49  // unregister the Instantiation from its __master
50 
51  if (__master) __master->unregisterSlave(*this);
52  }
53 
55  // for speed issues
56  assert(master != nullptr);
57 
59  __vars.resize(v.size());
60  __vals.reserve(v.size());
61  // fill the instantiation
62 
63  for (const auto var : v)
64  __add(*var);
65 
66  actAsSlave(master->getMasterRef());
67  }
68 
69  // constructor for a Instantiation contained into a MultiDimInterface
71  __master(0), __overflow(false) {
72  // for debugging purposes
73  GUM_CONSTRUCTOR(Instantiation);
74  __init(&d);
75  }
76 
78  __master(0), __overflow(false) {
79  // for debugging purposes
80  GUM_CONSTRUCTOR(Instantiation);
81  __init(const_cast< MultiDimAdressable* >(&d));
82  }
83 
84  // constructor for a Instantiation contained into a MultiDimInterface
86  __master(0), __overflow(false) {
87  // for debugging purposes
88  GUM_CONSTRUCTOR(Instantiation);
89 
90  if (d) __init(d);
91  }
92 
93  // constructor for a Instantiation contained into a MultiDimInterface this
94  // constructor is needed in order to allow creation of Instantiation(this) in
95  // MultiDimAdressable and below
97  __master(0), __overflow(false) {
98  // for debugging purposes
99  GUM_CONSTRUCTOR(Instantiation);
100 
101  if (const_d) __init(const_cast< MultiDimAdressable* >(const_d));
102  }
103 
104  // copy constructor
105  Instantiation::Instantiation(const Instantiation& aI, const bool notifyMaster) :
106  MultiDimInterface(), __master(0), __overflow(false) {
107  // for debugging purposes
108  GUM_CONS_CPY(Instantiation);
109  // copy the content of aI
110  __vars = aI.__vars;
111  __vals = aI.__vals;
112  __overflow = aI.__overflow;
113 
114  if (aI.__master && notifyMaster) actAsSlave(*aI.__master);
115  }
116 
117  // operator=
119  if (__master) {
120  if (!aI.isMaster(__master)) { // aI as the same master.
121  if (nbrDim() != aI.nbrDim()) {
122  GUM_ERROR(OperationNotAllowed, "in slave Instantiation");
123  }
124 
125  for (Idx i = 0; i < nbrDim(); i++) {
126  if ((!contains(aI.variable(i))) || (!aI.contains(variable(i)))) {
127  GUM_ERROR(OperationNotAllowed, "in slave Instantiation");
128  }
129  }
130  }
131 
132  setVals(aI);
133  } else {
134  // copy the content of aI
135  __vars = aI.__vars;
136  __vals = aI.__vals;
137  __overflow = aI.__overflow;
138 
139  if (aI.__master) actAsSlave(*aI.__master);
140  }
141 
142  return *this;
143  }
144 
145  // Gives a string version of a Instantiation
146  std::string Instantiation::toString() const {
147  std::stringstream sstr;
148  // check if the value of the instantiation is correct
149 
150  if (__overflow) { sstr << "<invalid>"; }
151 
152  sstr << "<";
153 
154  bool first = true;
155 
156  for (const auto var : __vars) {
157  if (!first) sstr << "|";
158 
159  first = false;
160  sstr << var->name() << ":" << var->label(val(*var));
161  }
162 
163  sstr << ">";
164 
165  return sstr.str();
166  }
167 
168  // give a Id value for Hamming distance
170  Idx res = 0;
171 
172  for (const auto var : __vars)
173  res += val(*var);
174 
175  return res;
176  }
177 
180  const Instantiation& external) {
181  for (const auto& elt : map) {
182  const DiscreteVariable& var = *elt.second;
183 
184  try {
185  Idx val = external.val(*elt.first);
186 
187  try {
188  chgVal(var, val);
189  } catch (NotFound&) {
191  var.name() << " : missing variable in instantiation");
192  }
193  } catch (NotFound&) {
195  var.name() << " : missing variable in external instantiation");
196  }
197  }
198  }
199 
201  Idx newVal,
202  Idx oldVal) const {
203  if (__master)
204  __master->changeNotification(*this, __vars[varPos], oldVal, newVal);
205  }
206 
209  }
210 
212  if (__master) __master->setIncNotification(*this);
213  }
216  }
218  if (__master) __master->setDecNotification(*this);
219  }
220 
221  // deassociate the master MultiDimAdressable, if any
223  if (__master) {
224  __master->unregisterSlave(*this);
225  __master = nullptr;
226  }
227  return true;
228  }
229  // force the variables sequence order to be the same as the master one
231  if (m != __master) {
232  GUM_ERROR(OperationNotAllowed, "only master can do this");
233  }
234 
236  }
237  // erase new dim by master
239  const DiscreteVariable& v) {
240  if (m != __master) {
241  GUM_ERROR(OperationNotAllowed, "only master can do this");
242  }
243 
244  __erase(v);
245 
247  }
248 
249  // tries to register the Instantiation to a MultiDimAdressable
251  // if __master : not allowed
252  if (__master != nullptr) {
253  GUM_ERROR(OperationNotAllowed, "in slave Instantiation");
254  }
255 
256  __master = &aMD;
257 
258  // perform the registration
259  if (aMD.registerSlave(*this)) {
260  return true;
261  } else {
262  __master = nullptr;
263  return false;
264  }
265  }
266 
267  // an operator for user-friendly displaying the content of a Instantiation
268  std::ostream& operator<<(std::ostream& aStream, const Instantiation& i) {
269  aStream << i.toString();
270  return aStream;
271  }
272 
273 } /* 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.
~Instantiation()
Destructor.
Idx nbrDim() const final
Returns the number of variables in the Instantiation.
Size size() const noexcept
Returns the size of the sequence.
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.
Idx hamming() const
Returns the hamming distance of this instantiation.
virtual void setChangeNotification(const Instantiation &i)=0
Listen to an assignment of a value in a Instantiation.
virtual bool registerSlave(Instantiation &i)=0
Register i as a slave of this MultiDimAdressable.
void __masterFirstNotification() const
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
void __masterIncNotification() const
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.
bool isMaster(const MultiDimAdressable *m) const
Indicates whether m is the master of this instantiation.
The class for generic Hash Tables.
Definition: hashTable.h:676
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:573
void __masterDecNotification() const
virtual bool unregisterSlave(Instantiation &i)=0
Unregister i as a slave of this MultiDimAdressable.
void __masterLastNotification() const
Header files of gum::Instantiation.
void __reorder(const Sequence< const DiscreteVariable * > &v)
Reorder vars of this instantiation giving the order in v.
static HashFuncCastKey< const DiscreteVariable * >::type __caster
virtual void setLastNotification(const Instantiation &i)=0
Listen to setLast in a given Instantiation.
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.
std::string toString() const
Give a string version of 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...
typename std::conditional< sizeof(T)< sizeof(long), HashFuncSmallCastKey< T >, typename std::conditional< sizeof(T)==2 *sizeof(long), HashFuncLargeCastKey< T >, HashFuncMediumCastKey< T > >::type >::type type
The type used by this class.
Definition: hashFunc.h:522
void synchronizeWithMaster(const MultiDimAdressable *m)
Force the variables sequence to be the same as the master one.
void __masterChangeNotification(Idx varPos, Idx newVal, Idx oldVal) const
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*.
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.
unsigned long Idx
Type for indexes.
Definition: types.h:43
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.
Idx val(Idx i) const
Returns the current value of the variable at position i.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:66
std::vector< Idx > __vals
The current instantiation: the value of the tuple.