aGrUM  0.14.2
scheduleMultiDim_tpl.h
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  ***************************************************************************/
26 #ifndef DOXYGEN_SHOULD_SKIP_THIS
27 
28 # include <sstream>
29 # include <string>
30 
31 # include <agrum/agrum.h>
32 
34 
35 namespace gum {
36 
38  template < typename GUM_SCALAR >
40  static Idx __abstract_id = 0;
41  return ++__abstract_id;
42  }
43 
45  template < typename GUM_SCALAR >
46  HashTable< Idx, const MultiDimImplementation< GUM_SCALAR >* >&
48  static HashTable< Idx, const MultiDimImplementation< GUM_SCALAR >* >
49  __multidims;
50 # ifdef GUM_DEBUG_MODE
51  // for debugging purposes, we should inform the aGrUM's debugger that
52  // the static hashtable used here will be removed at the end of the
53  // program's execution.
54  static bool first_time = true;
55 
56  if (first_time) {
57  first_time = false;
58  __debug__::__inc_deletion(
59  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__multidims);
60  }
61 
62 # endif /* GUM_DEBUG_MODE */
63  return __multidims;
64  }
65 
67  template < typename GUM_SCALAR >
68  HashTable< const MultiDimImplementation< GUM_SCALAR >*, Idx >&
70  static HashTable< const MultiDimImplementation< GUM_SCALAR >*, Idx >
71  __multidim_ids;
72 # ifdef GUM_DEBUG_MODE
73  // for debugging purposes, we should inform the aGrUM's debugger that
74  // the static hashtable used here will be removed at the end of the
75  // program's execution.
76  static bool first_time = true;
77 
78  if (first_time) {
79  first_time = false;
80  __debug__::__inc_deletion(
81  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__multidim_ids);
82  }
83 
84 # endif /* GUM_DEBUG_MODE */
85  return __multidim_ids;
86  }
87 
89  template < typename GUM_SCALAR >
91  static HashTable< Idx, Idx > __ids;
92 # ifdef GUM_DEBUG_MODE
93  // for debugging purposes, we should inform the aGrUM's debugger that
94  // the static hashtable used here will be removed at the end of the
95  // program's execution.
96  static bool first_time = true;
97 
98  if (first_time) {
99  first_time = false;
100  __debug__::__inc_deletion(
101  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__ids);
102  }
103 
104 # endif /* GUM_DEBUG_MODE */
105  return __ids;
106  }
107 
109  template < typename GUM_SCALAR >
110  HashTable< Idx, const Sequence< const DiscreteVariable* >* >&
112  static HashTable< Idx, const Sequence< const DiscreteVariable* >* > __vars;
113 # ifdef GUM_DEBUG_MODE
114  // for debugging purposes, we should inform the aGrUM's debugger that
115  // the static hashtable used here will be removed at the end of the
116  // program's execution.
117  static bool first_time = true;
118 
119  if (first_time) {
120  first_time = false;
121  __debug__::__inc_deletion(
122  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__vars);
123  }
124 
125 # endif /* GUM_DEBUG_MODE */
126  return __vars;
127  }
128 
130  template < typename GUM_SCALAR >
131  HashTable< Idx, Size >& ScheduleMultiDim< GUM_SCALAR >::__id2size() {
132  static HashTable< Idx, Size > __size;
133 # ifdef GUM_DEBUG_MODE
134  // for debugging purposes, we should inform the aGrUM's debugger that
135  // the static hashtable used here will be removed at the end of the
136  // program's execution.
137  static bool first_time = true;
138 
139  if (first_time) {
140  first_time = false;
141  __debug__::__inc_deletion(
142  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__size);
143  }
144 
145 # endif /* GUM_DEBUG_MODE */
146  return __size;
147  }
148 
150  template < typename GUM_SCALAR >
152  const MultiDimImplementation< GUM_SCALAR >& multidim) {
153  // for debugging purposes
154  GUM_CONSTRUCTOR(ScheduleMultiDim);
155 
156  // check whether the multidimImplementation has already been stored
157 
158  if (__multidim2id().exists(&multidim)) {
159  // get the id already allocated to the implementation
160  __id = __multidim2id().operator[](&multidim);
161 
162  // update the number of references of __id
163  HashTable< Idx, Idx >& refs = __id2refs();
164  ++refs[__id];
165  } else {
166  // assign a new id to the implementation
167  __id = __newId();
168 
169  // store the multidim into the set of all mappings id<->multidim
170  __id2multidim().insert(__id, &multidim);
171  __multidim2id().insert(&multidim, __id);
172 
173  // indicate that the id is currently used once
174  __id2refs().insert(__id, 1);
175 
176  // store the variables of the multidim
177  const Sequence< const DiscreteVariable* >* vars =
178  new Sequence< const DiscreteVariable* >(multidim.variablesSequence());
179  __id2vars().insert(__id, vars);
180 
181  // store the domain size of the multidim
182  __id2size().insert(__id, multidim.domainSize());
183  }
184  }
185 
187  template < typename GUM_SCALAR >
189  const MultiDimDecorator< GUM_SCALAR >& multidim) {
190  // for debugging purposes
191  GUM_CONSTRUCTOR(ScheduleMultiDim);
192 
193  const MultiDimImplementation< GUM_SCALAR >* impl = multidim.content();
194 
195  // check whether the multidimImplementation has already been stored
196 
197  if (__multidim2id().exists(impl)) {
198  // get the id already allocated to the implementation
199  __id = __multidim2id().operator[](impl);
200 
201  // update the number of references of __id
202  HashTable< Idx, Idx >& refs = __id2refs();
203  ++refs[__id];
204  } else {
205  // assign a new id to the implementation
206  __id = __newId();
207 
208  // store the multidim into the set of all mappings id<->multidim
209  __id2multidim().insert(__id, impl);
210  __multidim2id().insert(impl, __id);
211 
212  // indicate that the id is currently used once
213  __id2refs().insert(__id, 1);
214 
215  // store the variables of the multidim
216  const Sequence< const DiscreteVariable* >* vars =
217  new Sequence< const DiscreteVariable* >(multidim.variablesSequence());
218  __id2vars().insert(__id, vars);
219 
220  // store the domain size of the multidim
221  __id2size().insert(__id, multidim.domainSize());
222  }
223  }
224 
226  template < typename GUM_SCALAR >
228  const Sequence< const DiscreteVariable* >& vars) :
229  __id(__newId()) {
230  // for debugging purposes
231  GUM_CONSTRUCTOR(ScheduleMultiDim);
232 
233  // indicate that the id is currently used once
234  __id2refs().insert(__id, 1);
235 
236  // store the variables of the multidim
237  const Sequence< const DiscreteVariable* >* new_vars =
238  new Sequence< const DiscreteVariable* >(vars);
239  __id2vars().insert(__id, new_vars);
240 
241  // compute and store the domain size
242  Size size = 1;
243 
244  for (const auto var : *new_vars)
245  size *= var->domainSize();
246 
247  __id2size().insert(__id, size);
248  }
249 
251  template < typename GUM_SCALAR >
253  const ScheduleMultiDim< GUM_SCALAR >& from) :
254  __id(from.__id) {
255  // for debugging purposes
256  GUM_CONS_CPY(ScheduleMultiDim);
257 
258  // update the number of references of __id
260  ++refs[__id];
261  }
262 
264  template < typename GUM_SCALAR >
266  // for debugging purposes
267  GUM_DESTRUCTOR(ScheduleMultiDim);
268 
269  // get the number of scheduleMultiDims that reference the same id
271  Idx& nb_refs = refs[__id];
272 
273  if (nb_refs == 1) {
274  // remove the id and the multidimdecorator from the mappings
275  if (__id2multidim().exists(__id)) {
276  __multidim2id().erase(__id2multidim().operator[](__id));
277  __id2multidim().erase(__id);
278  }
279 
280  refs.erase(__id);
281 
282  delete __id2vars().operator[](__id);
283  __id2vars().erase(__id);
284  __id2size().erase(__id);
285  } else
286  --nb_refs;
287  }
288 
290  template < typename GUM_SCALAR >
291  ScheduleMultiDim< GUM_SCALAR >& ScheduleMultiDim< GUM_SCALAR >::
292  operator=(const ScheduleMultiDim< GUM_SCALAR >& from) {
293  // avoid self assignment
294  if (__id != from.__id) {
295  // remove the old id
297  Idx& nb_refs = refs[__id];
298 
299  if (nb_refs == 1) {
300  // remove the id and the multidimdecorator from the mappings
301  if (__id2multidim().exists(__id)) {
302  __multidim2id().erase(__id2multidim().operator[](__id));
303  __id2multidim().erase(__id);
304  }
305 
306  refs.erase(__id);
307 
308  delete __id2vars().operator[](__id);
309  __id2vars().erase(__id);
310  __id2size().erase(__id);
311  } else
312  --nb_refs;
313 
314  __id = from.__id;
315 
316  ++refs[__id];
317  }
318 
319  return *this;
320  }
321 
323  template < typename GUM_SCALAR >
325  operator==(const ScheduleMultiDim< GUM_SCALAR >& m) const {
326  return (__id == m.__id);
327  }
328 
330  template < typename GUM_SCALAR >
332  operator!=(const ScheduleMultiDim< GUM_SCALAR >& m) const {
333  return (__id != m.__id);
334  }
335 
338  template < typename GUM_SCALAR >
339  INLINE const MultiDimImplementation< GUM_SCALAR >&
341  return *(__id2multidim().operator[](__id));
342  }
343 
346  template < typename GUM_SCALAR >
347  INLINE bool ScheduleMultiDim< GUM_SCALAR >::isAbstract() const {
348  return !__id2multidim().exists(__id);
349  }
350 
352  template < typename GUM_SCALAR >
353  INLINE Idx ScheduleMultiDim< GUM_SCALAR >::id() const {
354  return __id;
355  }
356 
358  template < typename GUM_SCALAR >
359  INLINE const Sequence< const DiscreteVariable* >&
361  return *(__id2vars().operator[](__id));
362  }
363 
365  template < typename GUM_SCALAR >
367  return __id2size().operator[](__id);
368  }
369 
371  template < typename GUM_SCALAR >
373  const MultiDimImplementation< GUM_SCALAR >& m) {
374  // check whether the same Multidimimplementation has not already been
375  // wrapped with another ID. In this case, we shall throw a DuplicateElement
376  // exception
377  if (__multidim2id().exists(&m)) {
378  if (__multidim2id().operator[](&m) != __id) {
379  GUM_ERROR(DuplicateElement,
380  "the multidim table has already been "
381  "wrapped into a ScheduleMultidim with another id");
382  }
383  } else {
384  // here, the multidim has never been stored into a ScheduleMultiDim
385 
386  // if the current ScheduleMultiDim already contained a
387  // multidimImplementation
388  // we should remove it first and, then, add the new one
389  if (__id2multidim().exists(__id)) {
390  const MultiDimImplementation< GUM_SCALAR >* impl =
391  __id2multidim(). operator[](__id);
392 
393  if (impl == &m) return;
394 
395  __multidim2id().erase(impl);
396 
397  __id2multidim().operator[](__id) = &m;
398  } else {
399  // store the new multidim
400  __id2multidim().insert(__id, &m);
401  }
402 
403  __multidim2id().insert(&m, __id);
404 
405  // update the variables of the scheduleMultiDim
406  const Sequence< const DiscreteVariable* >& m_vars = m.variablesSequence();
407  Sequence< const DiscreteVariable* >* vars =
408  const_cast< Sequence< const DiscreteVariable* >* >(
409  __id2vars().operator[](__id));
410  *vars = m_vars;
411 
412  // update the size of the wrapper
413  __id2size().operator[](__id) = m.domainSize();
414  }
415  }
416 
418  template < typename GUM_SCALAR >
420  const MultiDimDecorator< GUM_SCALAR >& m) {
421  setMultiDim(*(m.content()));
422  }
423 
425  template < typename GUM_SCALAR >
426  std::string ScheduleMultiDim< GUM_SCALAR >::toString() const {
427  std::stringstream str;
428  str << "<";
429 
430  // get the pointer of the multidim if it exists
431 
432  try {
433  str << __id2multidim().operator[](__id);
434  } catch (NotFound&) { str << __id; }
435 
436  str << ">";
437 
438  return str.str();
439  }
440 
441 } /* namespace gum */
442 
443 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
const Sequence< const DiscreteVariable *> & variablesSequence() const
returns the set of variables involved in the multidim
static HashTable< const MultiDimImplementation< GUM_SCALAR > *, Idx > & __multidim2id()
returns the id corresponding to a given multidim
a MultiDimImplementation Wrapper used for scheduling inferences
ScheduleMultiDim(const MultiDimImplementation< GUM_SCALAR > &)
constructs a ScheduleMultiDim containing an already built implementation
std::string toString() const
displays the content of the multidim
bool isAbstract() const
returns whether the ScheduleMultiDim contains a real multiDimImplementation
Idx id() const
returns the id of the ScheduleMultiDim
void erase(const Key &key)
Removes a given element from the hash table.
Size domainSize() const
returns the domain size of the multidim
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
bool operator!=(const ScheduleMultiDim< GUM_SCALAR > &) const
checks whether two ScheduleMultiDim are related to different tables
ScheduleMultiDim< GUM_SCALAR > & operator=(const ScheduleMultiDim< GUM_SCALAR > &)
copy operator
~ScheduleMultiDim()
destructor
const MultiDimImplementation< GUM_SCALAR > & multiDim() const
returns the multiDimImplementation actually contained in the ScheduleMultiDim
static HashTable< Idx, const Sequence< const DiscreteVariable *> *> & __id2vars()
returns a table with the variables of the table corresponding to id
static HashTable< Idx, Idx > & __id2refs()
returns a table indicating how many ScheduleMultiDim have the same id
static Idx __newId()
returns a new distinct ID for each abtract scheduleMultiDim
static HashTable< Idx, Size > & __id2size()
returns a table with the domain size of the table corresponding to id
Idx __id
the unique Id of the ScheduleMultiDim
static HashTable< Idx, const MultiDimImplementation< GUM_SCALAR > *> & __id2multidim()
returns a mapping from id to multidimImplementations
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
void setMultiDim(const MultiDimImplementation< GUM_SCALAR > &)
sets a new multiDimImplementation inside the wrapper
bool operator==(const ScheduleMultiDim< GUM_SCALAR > &) const
checks whether two ScheduleMultiDim are related to the same table
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52