aGrUM  0.21.0
a C++ library for (probabilistic) graphical models
PRMSystem_tpl.h
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 Inline implementation of PRMSystem.
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  *
28  */
29 #include <agrum/PRM/elements/PRMSystem.h>
30 
31 #include <agrum/PRM/elements/PRMInstance.h>
32 
33 #include <agrum/tools/multidim/aggregators/exists.h>
34 #include <agrum/tools/multidim/aggregators/forall.h>
35 #include <agrum/tools/multidim/aggregators/max.h>
36 #include <agrum/tools/multidim/aggregators/min.h>
37 
38 namespace gum {
39  namespace prm {
40  template < typename GUM_SCALAR >
41  PRMSystem< GUM_SCALAR >::PRMSystem(const std::string& name) : PRMObject(name) {
42  GUM_CONSTRUCTOR(PRMSystem);
43  }
44 
45  template < typename GUM_SCALAR >
48 
49  for (const auto& elt: *this)
50  delete elt.second;
51 
52  for (const auto& elt: instanceMap_)
53  delete elt.second;
54 
55  for (const auto& elt: arrayMap_)
56  delete elt.second.second;
57  }
58 
59  template < typename GUM_SCALAR >
64  }
65 
66  template < typename GUM_SCALAR >
68  if (nameMap_.exists(i->name())) {
70  "an Instance<GUM_SCALAR> with the same is already in this System");
71  }
72 
75  nameMap_.insert(i->name(), i);
76 
77  try {
78  instanceMap_[&(i->type())]->insert(i);
79  } catch (NotFound&) {
80  instanceMap_.insert(&(i->type()), new Set< PRMInstance< GUM_SCALAR >* >());
81  instanceMap_[&(i->type())]->insert(i);
82  }
83 
84  return id;
85  }
86 
87  template < typename GUM_SCALAR >
90  factory.addNetworkProperty("name", name());
92 
93  // Adding nodes
94  for (PRMSystem< GUM_SCALAR >::const_iterator iter = begin(); iter != end(); ++iter) {
96  }
97 
98  // Adding arcs and filling CPTs
99  for (PRMSystem< GUM_SCALAR >::const_iterator iter = begin(); iter != end(); ++iter) {
100  _groundRef_(*(iter.val()), factory);
101  }
102  }
103 
104  template < typename GUM_SCALAR >
106  BayesNetFactory< GUM_SCALAR >& factory) const {
107  for (const auto node: instance.type().containerDag()) {
108  // Working a Class<GUM_SCALAR> level because PRMAggregate<GUM_SCALAR>
109  // are
110  // instantiated as PRMAttribute<GUM_SCALAR> in an
111  // PRMInstance<GUM_SCALAR>
112  switch (instance.type().get(node).elt_type()) {
114  // TODO: make a special case for noisy-or
116  elt_name << instance.name() << "." << instance.type().get(node).safeName();
118  var->setName(elt_name.str());
119  factory.setVariable(*var); // var is copied by the factory
120  delete var;
121  break;
122  }
123 
126  elt_name << instance.name() << "." << instance.type().get(node).safeName();
128  break;
129  }
130 
131  default:
132  break;
133  /* Do nothing */;
134  }
135  }
136  }
137 
138  template < typename GUM_SCALAR >
140  const std::string& name,
141  BayesNetFactory< GUM_SCALAR >& factory) const {
144 
146 
148 
150 
151  switch (var_type) {
152  case VarType::Labelized: {
153  const auto l = static_cast< const LabelizedVariable& >(agg_var);
154  for (Idx i = 0; i < l.domainSize(); ++i) {
156  }
157  break;
158  }
159  case VarType::Integer: {
160  const auto l = static_cast< const IntegerVariable& >(agg_var);
161  for (Idx i = 0; i < l.domainSize(); ++i) {
163  }
164  break;
165  }
166  case VarType::Discretized: {
167  const auto d = static_cast< const DiscretizedVariable< GUM_SCALAR >& >(agg_var);
168  for (Idx i = 0; i < d.domainSize(); ++i) {
169  factory.addTick(d.tick(i));
170  }
171  break;
172  }
173  case VarType::Range: {
174  const auto r = static_cast< const RangeVariable& >(agg_var);
175  factory.addMin(r.minVal());
176  factory.addMax(r.maxVal());
177  break;
178  }
179  default:
181  "PRM aggregator grounding does not support yet such variables");
182  break;
183  }
184 
185  const PRMAggregate< GUM_SCALAR >& agg = static_cast< const PRMAggregate< GUM_SCALAR >& >(elt);
186 
187  switch (agg.agg_type()) {
190  break;
191  }
192 
195  break;
196  }
197 
200  break;
201  }
202 
205  break;
206  }
207 
210  break;
211  }
212 
215  break;
216  }
217 
220  break;
221  }
222 
225  break;
226  }
227 
230  break;
231  }
232 
235  break;
236  }
237 
238  default:
239  GUM_ERROR(OperationNotAllowed, "Aggregator not handled yet for " << agg.name())
240  }
241 
243  }
244 
245  template < typename GUM_SCALAR >
247  BayesNetFactory< GUM_SCALAR >& factory) const {
248  for (const auto& elt: instance) {
250  elt_name << instance.name() << "." << elt.second->safeName();
252 
253  for (const auto par: instance.type().containerDag().parents(elt.second->id())) {
254  switch (instance.type().get(par).elt_type()) {
258  parent_name << instance.name() << "." << instance.get(par).safeName();
260  break;
261  }
262 
265  = static_cast< const PRMSlotChain< GUM_SCALAR >& >(instance.type().get(par))
266  .lastElt()
267  .safeName();
268 
269  try {
270  for (const auto ref: instance.getInstances(par)) {
272  sBuff << ref->name() << "." << parent_name;
274  }
275  } catch (NotFound&) {
276  // No instances for this slotchain
277  }
278 
279  break;
280  }
281 
282  default:
283  break;
284  /* nothing to do by default */
285  }
286  }
287 
289 
290  // Checking if we need to ground the Potential (only for class level
291  // attributes since
292  // aggregates Potentials are generated)
295  }
296  }
297 
298  template < typename GUM_SCALAR >
300  const PRMAttribute< GUM_SCALAR >& attr,
301  BayesNetFactory< GUM_SCALAR >& factory) const {
304  var_name << instance.name() << "." << attr.safeName();
306 
307  for (const auto parent: instance.type().containerDag().parents(attr.id())) {
308  switch (instance.type().get(parent).elt_type()) {
312  parent_name << instance.name() << "." << instance.get(parent).safeName();
315  break;
316  }
317 
320  const PRMSlotChain< GUM_SCALAR >& sc
321  = static_cast< const PRMSlotChain< GUM_SCALAR >& >(instance.type().get(parent));
322  parent_name << instance.getInstance(sc.id()).name() << "." << sc.lastElt().safeName();
326  break;
327  }
328 
329  default: {
330  GUM_ERROR(FatalError, "invalid ClassElement<GUM_SCALAR> type as parent.")
331  break;
332  }
333  }
334  }
335 
336  // Copy Potential
337  // DO NOT USE MultiDimBijArray as they will wreck havok if you delete
338  // the prm befor its grounded BN (happens a lot in pyAgrum)
339  Potential< GUM_SCALAR >* p = new Potential< GUM_SCALAR >();
340  for (auto var: attr.cpf().variablesSequence()) {
341  p->add(*(bijection.second(var)));
342  }
344  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end()); inst.inc(), jnst.inc()) {
345  p->set(jnst, attr.cpf().get(inst));
346  }
347  GUM_ASSERT(inst.end() && jnst.end());
348  factory.setVariableCPT(var_name.str(), p, false);
349  }
350 
351  template < typename GUM_SCALAR >
353  PRMInstance< GUM_SCALAR >& i) {
354  return add(array, &i);
355  }
356 
357  template < typename GUM_SCALAR >
359  return skeleton_;
360  }
361 
362  template < typename GUM_SCALAR >
364  try {
365  return *(nodeIdMap_[id]);
366  } catch (NotFound&) {
367  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id")
368  }
369  }
370 
371  template < typename GUM_SCALAR >
373  try {
374  return *(nodeIdMap_[id]);
375  } catch (NotFound&) {
376  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id")
377  }
378  }
379 
380  template < typename GUM_SCALAR >
382  try {
383  return nodeIdMap_.keyByVal(const_cast< PRMInstance< GUM_SCALAR >* >(&i));
384  } catch (NotFound&) {
385  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id")
386  }
387  }
388 
389  template < typename GUM_SCALAR >
391  return PRMObject::prm_type::SYSTEM;
392  }
393 
394  template < typename GUM_SCALAR >
396  return nodeIdMap_.size();
397  }
398 
399  template < typename GUM_SCALAR >
401  return instanceMap_.exists(const_cast< PRMClass< GUM_SCALAR >* >(&c));
402  }
403 
404  template < typename GUM_SCALAR >
405  INLINE bool PRMSystem< GUM_SCALAR >::isInstance(const std::string& name) const {
406  return nameMap_.exists(name);
407  }
408 
409  template < typename GUM_SCALAR >
410  INLINE bool PRMSystem< GUM_SCALAR >::isArray(const std::string& name) const {
411  return arrayMap_.exists(name);
412  }
413 
414  template < typename GUM_SCALAR >
416  for (auto iter = begin(); iter != end(); ++iter) {
417  (*(iter.val())).instantiate();
418  }
419  }
420 
421  template < typename GUM_SCALAR >
423  try {
424  return *(nameMap_[name]);
425  } catch (NotFound&) {
426  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given name")
427  }
428  }
429 
430  template < typename GUM_SCALAR >
431  INLINE const PRMInstance< GUM_SCALAR >&
432  PRMSystem< GUM_SCALAR >::get(const std::string& name) const {
433  try {
434  return *(nameMap_[name]);
435  } catch (NotFound&) {
436  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given name")
437  }
438  }
439 
440  template < typename GUM_SCALAR >
441  INLINE const Set< PRMInstance< GUM_SCALAR >* >&
442 
444  try {
445  return *(instanceMap_[const_cast< PRMClass< GUM_SCALAR >* >(&type)]);
446  } catch (NotFound&) {
447  GUM_ERROR(NotFound, "the given Class<GUM_SCALAR> has no instantiation in this System");
448  }
449  }
450 
451  template < typename GUM_SCALAR >
452  INLINE const Sequence< PRMInstance< GUM_SCALAR >* >&
453 
455  try {
456  return *(arrayMap_[name].second);
457  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
458  }
459 
460  template < typename GUM_SCALAR >
463  try {
464  return *(arrayMap_[name].first);
465  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
466  }
467 
468  template < typename GUM_SCALAR >
471  try {
472  return *(arrayMap_[name].first);
473  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
474  }
475 
476  template < typename GUM_SCALAR >
478  PRMInstance< GUM_SCALAR >* i) {
479  try {
480  if (i->type().isSubTypeOf(*(arrayMap_[array].first))) {
481  NodeId id = add(i);
483  return id;
484  } else {
486  "the given Instance<GUM_SCALAR> is of an incorrect "
487  "Class<GUM_SCALAR> type");
488  }
489  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
490  }
491 
492  template < typename GUM_SCALAR >
495  if (arrayMap_.exists(array)) {
496  GUM_ERROR(DuplicateElement, "an array '" << array << "' is already in this System")
497  }
498 
500  array,
502  }
503 
504  template < typename GUM_SCALAR >
506  return nodeIdMap_.begin();
507  }
508 
509  template < typename GUM_SCALAR >
511  return nodeIdMap_.end();
512  }
513 
514  template < typename GUM_SCALAR >
516  return nodeIdMap_.begin();
517  }
518 
519  template < typename GUM_SCALAR >
520  INLINE const typename PRMSystem< GUM_SCALAR >::const_iterator&
521  PRMSystem< GUM_SCALAR >::end() const {
522  return nodeIdMap_.end();
523  }
524 
525  template < typename GUM_SCALAR >
528  try {
529  return arrayMap_[a].second->begin();
530  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
531  }
532 
533  template < typename GUM_SCALAR >
534  INLINE const typename PRMSystem< GUM_SCALAR >::array_iterator&
536  try {
537  return arrayMap_[a].second->end();
538  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
539  }
540 
541  template < typename GUM_SCALAR >
543  PRMSystem< GUM_SCALAR >::begin(const std::string& a) const {
544  try {
545  return arrayMap_[a].second->begin();
546  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
547  }
548 
549  template < typename GUM_SCALAR >
550  INLINE const typename PRMSystem< GUM_SCALAR >::const_array_iterator&
551  PRMSystem< GUM_SCALAR >::end(const std::string& a) const {
552  try {
553  return arrayMap_[a].second->end();
554  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
555  }
556 
557  template < typename GUM_SCALAR >
558  INLINE bool PRMSystem< GUM_SCALAR >::exists(const std::string& name) const {
559  return nameMap_.exists(name) || arrayMap_.exists(name);
560  }
561 
562  } /* namespace prm */
563 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)