aGrUM  0.20.3
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::Discretized: {
160  const auto d = static_cast< const DiscretizedVariable< GUM_SCALAR >& >(agg_var);
161  for (Idx i = 0; i < d.domainSize(); ++i) {
162  factory.addTick(d.tick(i));
163  }
164  break;
165  }
166  case VarType::Range: {
167  const auto r = static_cast< const RangeVariable& >(agg_var);
168  factory.addMin(r.minVal());
169  factory.addMax(r.maxVal());
170  break;
171  }
172  case VarType::Continuous:
173  // Todo Error
174  break;
175  }
176 
177  const PRMAggregate< GUM_SCALAR >& agg = static_cast< const PRMAggregate< GUM_SCALAR >& >(elt);
178 
179  switch (agg.agg_type()) {
182  break;
183  }
184 
187  break;
188  }
189 
192  break;
193  }
194 
197  break;
198  }
199 
202  break;
203  }
204 
207  break;
208  }
209 
212  break;
213  }
214 
217  break;
218  }
219 
222  break;
223  }
224 
227  break;
228  }
229 
230  default:
231  GUM_ERROR(OperationNotAllowed, "Aggregator not handled yet for " << agg.name())
232  }
233 
235  }
236 
237  template < typename GUM_SCALAR >
239  BayesNetFactory< GUM_SCALAR >& factory) const {
240  for (const auto& elt: instance) {
242  elt_name << instance.name() << "." << elt.second->safeName();
244 
245  for (const auto par: instance.type().containerDag().parents(elt.second->id())) {
246  switch (instance.type().get(par).elt_type()) {
250  parent_name << instance.name() << "." << instance.get(par).safeName();
252  break;
253  }
254 
257  = static_cast< const PRMSlotChain< GUM_SCALAR >& >(instance.type().get(par))
258  .lastElt()
259  .safeName();
260 
261  try {
262  for (const auto ref: instance.getInstances(par)) {
264  sBuff << ref->name() << "." << parent_name;
266  }
267  } catch (NotFound&) {
268  // No instances for this slotchain
269  }
270 
271  break;
272  }
273 
274  default:
275  break;
276  /* nothing to do by default */
277  }
278  }
279 
281 
282  // Checking if we need to ground the Potential (only for class level
283  // attributes since
284  // aggregates Potentials are generated)
287  }
288  }
289 
290  template < typename GUM_SCALAR >
292  const PRMAttribute< GUM_SCALAR >& attr,
293  BayesNetFactory< GUM_SCALAR >& factory) const {
296  var_name << instance.name() << "." << attr.safeName();
298 
299  for (const auto parent: instance.type().containerDag().parents(attr.id())) {
300  switch (instance.type().get(parent).elt_type()) {
304  parent_name << instance.name() << "." << instance.get(parent).safeName();
307  break;
308  }
309 
312  const PRMSlotChain< GUM_SCALAR >& sc
313  = static_cast< const PRMSlotChain< GUM_SCALAR >& >(instance.type().get(parent));
314  parent_name << instance.getInstance(sc.id()).name() << "." << sc.lastElt().safeName();
318  break;
319  }
320 
321  default: {
322  GUM_ERROR(FatalError, "invalid ClassElement<GUM_SCALAR> type as parent.")
323  break;
324  }
325  }
326  }
327 
328  // Copy Potential
329  // DO NOT USE MultiDimBijArray as they will wreck havok if you delete
330  // the prm befor its grounded BN (happens a lot in pyAgrum)
331  Potential< GUM_SCALAR >* p = new Potential< GUM_SCALAR >();
332  for (auto var: attr.cpf().variablesSequence()) {
333  p->add(*(bijection.second(var)));
334  }
336  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end()); inst.inc(), jnst.inc()) {
337  p->set(jnst, attr.cpf().get(inst));
338  }
339  GUM_ASSERT(inst.end() && jnst.end());
340  factory.setVariableCPT(var_name.str(), p, false);
341  }
342 
343  template < typename GUM_SCALAR >
345  PRMInstance< GUM_SCALAR >& i) {
346  return add(array, &i);
347  }
348 
349  template < typename GUM_SCALAR >
351  return skeleton_;
352  }
353 
354  template < typename GUM_SCALAR >
356  try {
357  return *(nodeIdMap_[id]);
358  } catch (NotFound&) {
359  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id")
360  }
361  }
362 
363  template < typename GUM_SCALAR >
365  try {
366  return *(nodeIdMap_[id]);
367  } catch (NotFound&) {
368  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id")
369  }
370  }
371 
372  template < typename GUM_SCALAR >
374  try {
375  return nodeIdMap_.keyByVal(const_cast< PRMInstance< GUM_SCALAR >* >(&i));
376  } catch (NotFound&) {
377  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id")
378  }
379  }
380 
381  template < typename GUM_SCALAR >
383  return PRMObject::prm_type::SYSTEM;
384  }
385 
386  template < typename GUM_SCALAR >
388  return nodeIdMap_.size();
389  }
390 
391  template < typename GUM_SCALAR >
393  return instanceMap_.exists(const_cast< PRMClass< GUM_SCALAR >* >(&c));
394  }
395 
396  template < typename GUM_SCALAR >
397  INLINE bool PRMSystem< GUM_SCALAR >::isInstance(const std::string& name) const {
398  return nameMap_.exists(name);
399  }
400 
401  template < typename GUM_SCALAR >
402  INLINE bool PRMSystem< GUM_SCALAR >::isArray(const std::string& name) const {
403  return arrayMap_.exists(name);
404  }
405 
406  template < typename GUM_SCALAR >
408  for (auto iter = begin(); iter != end(); ++iter) {
409  (*(iter.val())).instantiate();
410  }
411  }
412 
413  template < typename GUM_SCALAR >
415  try {
416  return *(nameMap_[name]);
417  } catch (NotFound&) {
418  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given name")
419  }
420  }
421 
422  template < typename GUM_SCALAR >
423  INLINE const PRMInstance< GUM_SCALAR >&
424  PRMSystem< GUM_SCALAR >::get(const std::string& name) const {
425  try {
426  return *(nameMap_[name]);
427  } catch (NotFound&) {
428  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given name")
429  }
430  }
431 
432  template < typename GUM_SCALAR >
433  INLINE const Set< PRMInstance< GUM_SCALAR >* >&
434 
436  try {
437  return *(instanceMap_[const_cast< PRMClass< GUM_SCALAR >* >(&type)]);
438  } catch (NotFound&) {
439  GUM_ERROR(NotFound, "the given Class<GUM_SCALAR> has no instantiation in this System");
440  }
441  }
442 
443  template < typename GUM_SCALAR >
444  INLINE const Sequence< PRMInstance< GUM_SCALAR >* >&
445 
447  try {
448  return *(arrayMap_[name].second);
449  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
450  }
451 
452  template < typename GUM_SCALAR >
455  try {
456  return *(arrayMap_[name].first);
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 >
470  PRMInstance< GUM_SCALAR >* i) {
471  try {
472  if (i->type().isSubTypeOf(*(arrayMap_[array].first))) {
473  NodeId id = add(i);
475  return id;
476  } else {
478  "the given Instance<GUM_SCALAR> is of an incorrect "
479  "Class<GUM_SCALAR> type");
480  }
481  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
482  }
483 
484  template < typename GUM_SCALAR >
487  if (arrayMap_.exists(array)) {
488  GUM_ERROR(DuplicateElement, "an array '" << array << "' is already in this System")
489  }
490 
492  array,
494  }
495 
496  template < typename GUM_SCALAR >
498  return nodeIdMap_.begin();
499  }
500 
501  template < typename GUM_SCALAR >
503  return nodeIdMap_.end();
504  }
505 
506  template < typename GUM_SCALAR >
508  return nodeIdMap_.begin();
509  }
510 
511  template < typename GUM_SCALAR >
512  INLINE const typename PRMSystem< GUM_SCALAR >::const_iterator&
513  PRMSystem< GUM_SCALAR >::end() const {
514  return nodeIdMap_.end();
515  }
516 
517  template < typename GUM_SCALAR >
520  try {
521  return arrayMap_[a].second->begin();
522  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
523  }
524 
525  template < typename GUM_SCALAR >
526  INLINE const typename PRMSystem< GUM_SCALAR >::array_iterator&
528  try {
529  return arrayMap_[a].second->end();
530  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
531  }
532 
533  template < typename GUM_SCALAR >
535  PRMSystem< GUM_SCALAR >::begin(const std::string& a) const {
536  try {
537  return arrayMap_[a].second->begin();
538  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
539  }
540 
541  template < typename GUM_SCALAR >
542  INLINE const typename PRMSystem< GUM_SCALAR >::const_array_iterator&
543  PRMSystem< GUM_SCALAR >::end(const std::string& a) const {
544  try {
545  return arrayMap_[a].second->end();
546  } catch (NotFound&) { GUM_ERROR(NotFound, "found no array matching the given name") }
547  }
548 
549  template < typename GUM_SCALAR >
550  INLINE bool PRMSystem< GUM_SCALAR >::exists(const std::string& name) const {
551  return nameMap_.exists(name) || arrayMap_.exists(name);
552  }
553 
554  } /* namespace prm */
555 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)