aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
instantiation.cpp
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 gum::Instantiation.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  */
28 
29 #include <agrum/tools/multidim/implementations/multiDimAdressable.h>
30 #include <agrum/tools/multidim/instantiation.h>
31 
32 #ifdef GUM_NO_INLINE
33 # include <agrum/tools/multidim/instantiation_inl.h>
34 #endif /* GUM_NO_INLINE */
35 
36 namespace gum {
37 
38  // Default constructor
41  }
42 
43  // destructor
46  // unregister the Instantiation from its _master_
47 
48  if (_master_) _master_->unregisterSlave(*this);
49  }
50 
52  // for speed issues
53  GUM_ASSERT(master != nullptr);
54 
55  const Sequence< const DiscreteVariable* >& v = master->variablesSequence();
56  _vars_.resize(v.size());
57  _vals_.reserve(v.size());
58  // fill the instantiation
59 
60  for (const auto var: v)
61  _add_(*var);
62 
64  }
65 
66  // constructor for a Instantiation contained into a MultiDimInterface
68  // for debugging purposes
70  _init_(&d);
71  }
72 
74  // for debugging purposes
76  _init_(const_cast< MultiDimAdressable* >(&d));
77  }
78 
79  // constructor for a Instantiation contained into a MultiDimInterface
81  // for debugging purposes
83 
84  if (d) _init_(d);
85  }
86 
87  // constructor for a Instantiation contained into a MultiDimInterface this
88  // constructor is needed in order to allow creation of Instantiation(this) in
89  // MultiDimAdressable and below
91  // for debugging purposes
93 
94  if (const_d) _init_(const_cast< MultiDimAdressable* >(const_d));
95  }
96 
97  // copy constructor
99  MultiDimInterface(), _master_(0), _overflow_(false) {
100  // for debugging purposes
102  // copy the content of aI
103  _vars_ = aI._vars_;
104  _vals_ = aI._vals_;
106 
108  }
109 
110  // operator=
112  if (_master_) {
113  if (!aI.isMaster(_master_)) { // aI as the same master.
114  if (nbrDim() != aI.nbrDim()) { GUM_ERROR(OperationNotAllowed, "in slave Instantiation") }
115 
116  for (Idx i = 0; i < nbrDim(); i++) {
117  if ((!contains(aI.variable(i))) || (!aI.contains(variable(i)))) {
118  GUM_ERROR(OperationNotAllowed, "in slave Instantiation")
119  }
120  }
121  }
122 
123  setVals(aI);
124  } else {
125  // copy the content of aI
126  _vars_ = aI._vars_;
127  _vals_ = aI._vals_;
129 
131  }
132 
133  return *this;
134  }
135 
136  // Gives a string version of a Instantiation
139  // check if the value of the instantiation is correct
140 
141  if (_overflow_) { sstr << "<invalid>"; }
142 
143  sstr << "<";
144 
145  bool first = true;
146 
147  for (const auto var: _vars_) {
148  if (!first) sstr << "|";
149 
150  first = false;
151  sstr << var->name() << ":" << var->label(val(*var));
152  }
153 
154  sstr << ">";
155 
156  return sstr.str();
157  }
158 
159  // give a Id value for Hamming distance
161  Idx res = 0;
162 
163  for (const auto var: _vars_)
164  res += val(*var);
165 
166  return res;
167  }
168 
170  const HashTable< const DiscreteVariable*, const DiscreteVariable* >& map,
171  const Instantiation& external) {
172  for (const auto& elt: map) {
173  const DiscreteVariable& var = *elt.second;
174 
175  try {
176  Idx val = external.val(*elt.first);
177 
178  try {
179  chgVal(var, val);
180  } catch (NotFound&) {
181  GUM_ERROR(NotFound, var.name() << " : missing variable in instantiation")
182  }
183  } catch (NotFound&) {
184  GUM_ERROR(NotFound, var.name() << " : missing variable in external instantiation")
185  }
186  }
187  }
188 
191  }
192 
195  }
196 
198  if (_master_) _master_->setIncNotification(*this);
199  }
202  }
204  if (_master_) _master_->setDecNotification(*this);
205  }
206 
207  // deassociate the master MultiDimAdressable, if any
209  if (_master_) {
210  _master_->unregisterSlave(*this);
211  _master_ = nullptr;
212  }
213  return true;
214  }
215  // force the variables sequence order to be the same as the master one
217  if (m != _master_) { GUM_ERROR(OperationNotAllowed, "only master can do this") }
218 
220  }
221  // erase new dim by master
223  if (m != _master_) { GUM_ERROR(OperationNotAllowed, "only master can do this") }
224 
225  _erase_(v);
226 
228  }
229 
230  // tries to register the Instantiation to a MultiDimAdressable
232  // if _master_ : not allowed
233  if (_master_ != nullptr) { GUM_ERROR(OperationNotAllowed, "in slave Instantiation") }
234 
235  _master_ = &aMD;
236 
237  // perform the registration
238  if (aMD.registerSlave(*this)) {
239  return true;
240  } else {
241  _master_ = nullptr;
242  return false;
243  }
244  }
245 
246  // an operator for user-friendly displaying the content of a Instantiation
248  aStream << i.toString();
249  return aStream;
250  }
251 
252 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
std::ostream & operator<<(std::ostream &aStream, const Instantiation &i)
Print information of the instantiation in the stream.