aGrUM  0.16.0
PRMSystem_tpl.h
Go to the documentation of this file.
1 
31 
36 
37 namespace gum {
38  namespace prm {
39  template < typename GUM_SCALAR >
40  PRMSystem< GUM_SCALAR >::PRMSystem(const std::string& name) : PRMObject(name) {
41  GUM_CONSTRUCTOR(PRMSystem);
42  }
43 
44  template < typename GUM_SCALAR >
46  GUM_DESTRUCTOR(PRMSystem);
47 
48  for (const auto& elt : *this)
49  delete elt.second;
50 
51  for (const auto& elt : __instanceMap)
52  delete elt.second;
53 
54  for (const auto& elt : __arrayMap)
55  delete elt.second.second;
56  }
57 
58  template < typename GUM_SCALAR >
60  if (__nameMap.exists(i->name())) {
61  GUM_ERROR(
63  "an Instance<GUM_SCALAR> with the same is already in this System");
64  }
65 
66  NodeId id = __skeleton.addNode();
67  __nodeIdMap.insert(id, i);
68  __nameMap.insert(i->name(), i);
69 
70  try {
71  __instanceMap[&(i->type())]->insert(i);
72  } catch (NotFound&) {
73  __instanceMap.insert(&(i->type()),
74  new Set< PRMInstance< GUM_SCALAR >* >());
75  __instanceMap[&(i->type())]->insert(i);
76  }
77 
78  return id;
79  }
80 
81  template < typename GUM_SCALAR >
83  BayesNetFactory< GUM_SCALAR >& factory) const {
84  factory.startNetworkDeclaration();
85  factory.addNetworkProperty("name", name());
86  factory.endNetworkDeclaration();
87 
88  // Adding nodes
89  for (PRMSystem< GUM_SCALAR >::const_iterator iter = begin(); iter != end();
90  ++iter) {
91  __groundAttr(*(iter.val()), factory);
92  }
93 
94  // Adding arcs and filling CPTs
95  for (PRMSystem< GUM_SCALAR >::const_iterator iter = begin(); iter != end();
96  ++iter) {
97  __groundRef(*(iter.val()), factory);
98  }
99  }
100 
101  template < typename GUM_SCALAR >
103  const PRMInstance< GUM_SCALAR >& instance,
104  BayesNetFactory< GUM_SCALAR >& factory) const {
105  for (const auto node : instance.type().containerDag()) {
106  // Working a Class<GUM_SCALAR> level because PRMAggregate<GUM_SCALAR>
107  // are
108  // instantiated as PRMAttribute<GUM_SCALAR> in an
109  // PRMInstance<GUM_SCALAR>
110  switch (instance.type().get(node).elt_type()) {
112  // TODO: make a special case for noisy-or
113  std::stringstream elt_name;
114  elt_name << instance.name() << "."
115  << instance.type().get(node).safeName();
116  DiscreteVariable* var = instance.get(node).type().variable().clone();
117  var->setName(elt_name.str());
118  factory.setVariable(*var); // var is copied by the factory
119  delete var;
120  break;
121  }
122 
124  std::stringstream elt_name;
125  elt_name << instance.name() << "."
126  << instance.type().get(node).safeName();
127  __groundAgg(instance.type().get(node), elt_name.str(), factory);
128  break;
129  }
130 
131  default:
132  break;
133  /* Do nothing */;
134  }
135  }
136  }
137 
138  template < typename GUM_SCALAR >
141  const std::string& name,
142  BayesNetFactory< GUM_SCALAR >& factory) const {
143  factory.startVariableDeclaration();
144  factory.variableName(name);
145  const DiscreteVariable& agg_var = elt.type().variable();
146 
147  for (Idx i = 0; i < agg_var.domainSize(); ++i) {
148  factory.addModality(agg_var.label(i));
149  }
150 
151  const PRMAggregate< GUM_SCALAR >& agg =
152  static_cast< const PRMAggregate< GUM_SCALAR >& >(elt);
153 
154  switch (agg.agg_type()) {
158  break;
159  }
160 
164  break;
165  }
166 
170  break;
171  }
172 
176  break;
177  }
178 
182  break;
183  }
184 
188  break;
189  }
190 
194  break;
195  }
196 
199  break;
200  }
201 
205  break;
206  }
207 
208  default: {
209  GUM_ERROR(OperationNotAllowed, "Aggregator not handled yet");
210  break;
211  }
212  }
213 
214  factory.endVariableDeclaration();
215  }
216 
217  template < typename GUM_SCALAR >
219  const PRMInstance< GUM_SCALAR >& instance,
220  BayesNetFactory< GUM_SCALAR >& factory) const {
221  for (const auto& elt : instance) {
222  std::stringstream elt_name;
223  elt_name << instance.name() << "." << elt.second->safeName();
224  factory.startParentsDeclaration(elt_name.str());
225 
226  for (const auto par :
227  instance.type().containerDag().parents(elt.second->id())) {
228  switch (instance.type().get(par).elt_type()) {
231  std::stringstream parent_name;
232  parent_name << instance.name() << "."
233  << instance.get(par).safeName();
234  factory.addParent(parent_name.str());
235  break;
236  }
237 
239  std::string parent_name =
240  static_cast< const PRMSlotChain< GUM_SCALAR >& >(
241  instance.type().get(par))
242  .lastElt()
243  .safeName();
244 
245  for (const auto ref : instance.getInstances(par)) {
246  std::stringstream sBuff;
247  sBuff << ref->name() << "." << parent_name;
248  factory.addParent(sBuff.str());
249  }
250 
251  break;
252  }
253 
254  default:
255  break;
256  /* nothing to do by default */
257  }
258  }
259 
260  factory.endParentsDeclaration();
261 
262  // Checking if we need to ground the Potential (only for class level
263  // attributes since
264  // aggregates Potentials are generated)
266  instance.type().get(elt.second->safeName())))
267  __groundPotential(instance, *elt.second, factory);
268  }
269  }
270 
271  template < typename GUM_SCALAR >
273  const PRMInstance< GUM_SCALAR >& instance,
274  const PRMAttribute< GUM_SCALAR >& attr,
275  BayesNetFactory< GUM_SCALAR >& factory) const {
277  std::stringstream var_name;
278  var_name << instance.name() << "." << attr.safeName();
279  bijection.insert(&(attr.type().variable()),
280  &(factory.variable(var_name.str())));
281 
282  for (const auto parent : instance.type().containerDag().parents(attr.id())) {
283  switch (instance.type().get(parent).elt_type()) {
286  std::stringstream parent_name;
287  parent_name << instance.name() << "."
288  << instance.get(parent).safeName();
289  bijection.insert(&(instance.get(parent).type().variable()),
290  &(factory.variable(parent_name.str())));
291  break;
292  }
293 
295  std::stringstream parent_name;
296  const PRMSlotChain< GUM_SCALAR >& sc =
297  static_cast< const PRMSlotChain< GUM_SCALAR >& >(
298  instance.type().get(parent));
299  parent_name << instance.getInstance(sc.id()).name() << "."
300  << sc.lastElt().safeName();
301  bijection.insert(&(instance.getInstance(sc.id())
302  .get(sc.lastElt().safeName())
303  .type()
304  .variable()),
305  &(factory.variable(parent_name.str())));
306  break;
307  }
308 
309  default: {
311  "invalid ClassElement<GUM_SCALAR> type as parent.");
312  break;
313  }
314  }
315  }
316 
317  // Copy Potential
318  // DO NOT USE MultiDimBijArray as they will wreck havok if you delete
319  // the prm befor its grounded BN (happens a lot in pyAgrum)
321  for (auto var : attr.cpf().variablesSequence()) {
322  p->add(*(bijection.second(var)));
323  }
324  Instantiation inst(attr.cpf()), jnst(*p);
325  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
326  inst.inc(), jnst.inc()) {
327  p->set(jnst, attr.cpf().get(inst));
328  }
329  GUM_ASSERT(inst.end() && jnst.end());
330  factory.setVariableCPT(var_name.str(), p, false);
331  }
332 
333  template < typename GUM_SCALAR >
334  INLINE NodeId PRMSystem< GUM_SCALAR >::add(const std::string& array,
336  return add(array, &i);
337  }
338 
339  template < typename GUM_SCALAR >
341  return __skeleton;
342  }
343 
344  template < typename GUM_SCALAR >
346  try {
347  return *(__nodeIdMap[id]);
348  } catch (NotFound&) {
349  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id");
350  }
351  }
352 
353  template < typename GUM_SCALAR >
354  INLINE const PRMInstance< 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 >
364  INLINE NodeId
366  try {
367  return __nodeIdMap.keyByVal(const_cast< PRMInstance< GUM_SCALAR >* >(&i));
368  } catch (NotFound&) {
369  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id");
370  }
371  }
372 
373  template < typename GUM_SCALAR >
375  return PRMObject::prm_type::SYSTEM;
376  }
377 
378  template < typename GUM_SCALAR >
380  return __nodeIdMap.size();
381  }
382 
383  template < typename GUM_SCALAR >
385  const PRMClass< GUM_SCALAR >& c) const {
386  return __instanceMap.exists(const_cast< PRMClass< GUM_SCALAR >* >(&c));
387  }
388 
389  template < typename GUM_SCALAR >
390  INLINE bool
391  PRMSystem< GUM_SCALAR >::isInstance(const std::string& name) const {
392  return __nameMap.exists(name);
393  }
394 
395  template < typename GUM_SCALAR >
396  INLINE bool PRMSystem< GUM_SCALAR >::isArray(const std::string& name) const {
397  return __arrayMap.exists(name);
398  }
399 
400  template < typename GUM_SCALAR >
402  for (auto iter = begin(); iter != end(); ++iter) {
403  (*(iter.val())).instantiate();
404  }
405  }
406 
407  template < typename GUM_SCALAR >
409  PRMSystem< GUM_SCALAR >::get(const std::string& name) {
410  try {
411  return *(__nameMap[name]);
412  } catch (NotFound&) {
414  "found no Instance<GUM_SCALAR> matching the given name");
415  }
416  }
417 
418  template < typename GUM_SCALAR >
419  INLINE const PRMInstance< GUM_SCALAR >&
420  PRMSystem< GUM_SCALAR >::get(const std::string& name) const {
421  try {
422  return *(__nameMap[name]);
423  } catch (NotFound&) {
425  "found no Instance<GUM_SCALAR> matching the given name");
426  }
427  }
428 
429  template < typename GUM_SCALAR >
430  INLINE const Set< PRMInstance< GUM_SCALAR >* >&
432  try {
433  return *(__instanceMap[const_cast< PRMClass< GUM_SCALAR >* >(&type)]);
434  } catch (NotFound&) {
435  GUM_ERROR(
436  NotFound,
437  "the given Class<GUM_SCALAR> has no instantiation in this System");
438  }
439  }
440 
441  template < typename GUM_SCALAR >
442  INLINE const Sequence< PRMInstance< GUM_SCALAR >* >&
443  PRMSystem< GUM_SCALAR >::getArray(const std::string& name) const {
444  try {
445  return *(__arrayMap[name].second);
446  } catch (NotFound&) {
447  GUM_ERROR(NotFound, "found no array matching the given name");
448  }
449  }
450 
451  template < typename GUM_SCALAR >
453  PRMSystem< GUM_SCALAR >::getArrayType(const std::string& name) {
454  try {
455  return *(__arrayMap[name].first);
456  } catch (NotFound&) {
457  GUM_ERROR(NotFound, "found no array matching the given name");
458  }
459  }
460 
461  template < typename GUM_SCALAR >
463  PRMSystem< GUM_SCALAR >::getArrayType(const std::string& name) const {
464  try {
465  return *(__arrayMap[name].first);
466  } catch (NotFound&) {
467  GUM_ERROR(NotFound, "found no array matching the given name");
468  }
469  }
470 
471  template < typename GUM_SCALAR >
472  INLINE NodeId PRMSystem< GUM_SCALAR >::add(const std::string& array,
474  try {
475  if (i->type().isSubTypeOf(*(__arrayMap[array].first))) {
476  NodeId id = add(i);
477  __arrayMap[array].second->insert(i);
478  return id;
479  } else {
481  "the given Instance<GUM_SCALAR> is of an incorrect "
482  "Class<GUM_SCALAR> type");
483  }
484  } catch (NotFound&) {
485  GUM_ERROR(NotFound, "found no array matching the given name");
486  }
487  }
488 
489  template < typename GUM_SCALAR >
491  const std::string& array, PRMClassElementContainer< GUM_SCALAR >& type) {
492  if (__arrayMap.exists(array)) {
494  "an array '" << array << "' is already in this System");
495  }
496 
497  __arrayMap.insert(array,
499  &type, new Sequence< PRMInstance< GUM_SCALAR >* >()));
500  }
501 
502  template < typename GUM_SCALAR >
503  INLINE typename PRMSystem< GUM_SCALAR >::iterator
505  return __nodeIdMap.begin();
506  }
507 
508  template < typename GUM_SCALAR >
509  INLINE const typename PRMSystem< GUM_SCALAR >::iterator&
511  return __nodeIdMap.end();
512  }
513 
514  template < typename GUM_SCALAR >
517  return __nodeIdMap.begin();
518  }
519 
520  template < typename GUM_SCALAR >
521  INLINE const typename PRMSystem< GUM_SCALAR >::const_iterator&
523  return __nodeIdMap.end();
524  }
525 
526  template < typename GUM_SCALAR >
528  PRMSystem< GUM_SCALAR >::begin(const std::string& a) {
529  try {
530  return __arrayMap[a].second->begin();
531  } catch (NotFound&) {
532  GUM_ERROR(NotFound, "found no array matching the given name");
533  }
534  }
535 
536  template < typename GUM_SCALAR >
537  INLINE const typename PRMSystem< GUM_SCALAR >::array_iterator&
538  PRMSystem< GUM_SCALAR >::end(const std::string& a) {
539  try {
540  return __arrayMap[a].second->end();
541  } catch (NotFound&) {
542  GUM_ERROR(NotFound, "found no array matching the given name");
543  }
544  }
545 
546  template < typename GUM_SCALAR >
548  PRMSystem< GUM_SCALAR >::begin(const std::string& a) const {
549  try {
550  return __arrayMap[a].second->begin();
551  } catch (NotFound&) {
552  GUM_ERROR(NotFound, "found no array matching the given name");
553  }
554  }
555 
556  template < typename GUM_SCALAR >
557  INLINE const typename PRMSystem< GUM_SCALAR >::const_array_iterator&
558  PRMSystem< GUM_SCALAR >::end(const std::string& a) const {
559  try {
560  return __arrayMap[a].second->end();
561  } catch (NotFound&) {
562  GUM_ERROR(NotFound, "found no array matching the given name");
563  }
564  }
565 
566  template < typename GUM_SCALAR >
567  INLINE bool PRMSystem< GUM_SCALAR >::exists(const std::string& name) const {
568  return __nameMap.exists(name) || __arrayMap.exists(name);
569  }
570 
571  } /* namespace prm */
572 } /* namespace gum */
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
aGrUM&#39;s Potential is a multi-dimensional array with tensor operators.
Definition: potential.h:60
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
void setName(const std::string &theValue)
sets the name of the variable
const PRMInstance< GUM_SCALAR > & getInstance(NodeId id) const
Fast access to the first instance in a PRMReferenceSlot or PRMSlotChain<GUM_SCALAR>.
void variableName(const std::string &name) final
Tells the factory the current variable&#39;s name.
Unsafe Const Iterators for hashtablesHashTableConstIterator provides a fast but unsafe way to parse H...
Definition: hashTable.h:2465
PRMAttribute< GUM_SCALAR > & get(NodeId id)
Getter on an PRMAttribute<GUM_SCALAR> of this PRMInstance<GUM_SCALAR>.
void setVariableCPTImplementation(MultiDimAdressable *adressable) final
Defines the implementation to use for var&#39;s Potential.
const std::string & name() const
Returns the name of this object.
Definition: PRMObject_inl.h:35
iterator begin()
Returns an iterator over the instances in this system.
void addParent(const std::string &var) final
Tells the factory for which variable we&#39;re declaring parents.
virtual PRMType & type()=0
See gum::PRMClassElement::type().
An PRMInstance is a Bayesian Network fragment defined by a Class and used in a PRMSystem.
Definition: PRMInstance.h:63
void setVariable(const DiscreteVariable &var) final
Define a variable.
or aggregator
Definition: or.h:56
Unsafe Iterators for hashtablesHashTableIterator provides a fast but unsafe way to parse HashTables...
Definition: hashTable.h:2750
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1022
PRMClass< GUM_SCALAR > & type()
Returns the type of this instance.
void addNetworkProperty(const std::string &propName, const std::string &propValue) final
Tells the factory to add a property to the current network.
void startParentsDeclaration(const std::string &var) final
Tells the factory that we&#39;re declaring parents for some variable.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Abstract class representing an element of PRM class.
void endParentsDeclaration() final
Tells the factory that we&#39;ve finished declaring parents for some variable.
Base class for discrete random variable.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
PRMSystem(const std::string &name)
Default constructor.
Definition: PRMSystem_tpl.h:40
forall aggregator
Definition: forall.h:55
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
const std::string & safeName() const
Returns the safe name of this PRMClassElement, if any.
virtual Size domainSize() const =0
prm_type
Enumeration of the different types of objects handled by a PRM.
Definition: PRMObject.h:69
And aggregator.
Definition: and.h:55
void inc()
Operator increment.
exists aggregator
Definition: exists.h:54
void startNetworkDeclaration() final
Tells the factory that we&#39;re in a network declaration.
virtual std::string label(Idx i) const =0
get the indice-th label. This method is pure virtual.
AggregateType agg_type() const
Returns the aggregate of *this.
virtual const Potential< GUM_SCALAR > & cpf() const =0
See gum::PRMClassElement::cpf().
void startVariableDeclaration() final
Tells the factory that we&#39;re in a variable declaration.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Base class for all oriented graphs.
Definition: diGraph.h:111
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
Definition: PRMObject.h:229
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Sequence< PRMInstance< GUM_SCALAR > *>::iterator array_iterator
Iterator over the PRMInstance in an array in this PRMSystem.
Definition: PRMSystem.h:236
void instantiate()
Instantiate all the PRMInstance in this PRMSystem.
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1805
NodeId endVariableDeclaration() final
Tells the factory that we&#39;re out of a variable declaration.
virtual PRMType & type()=0
Return a reference over the gum::PRMType of this class element.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
A PRMSlotChain represents a sequence of gum::prm::PRMClassElement<GUM_SCALAR> where the n-1 first gum...
Definition: PRMObject.h:221
std::pair< PRMClassElementContainer< GUM_SCALAR > *, Sequence< PRMInstance< GUM_SCALAR > *> *> model_pair
Typedef of the pair of a Class<GUM_SCALAR> and the sequence of it&#39;s instantiation.
Definition: PRMSystem.h:293
Abstract base class for any element defined in a PRM.
Definition: PRMObject.h:56
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:83
void setVariableCPT(const std::string &varName, MultiDimAdressable *table, bool redefineParents) final
Define a variable&#39;s CPT.
virtual void add(const DiscreteVariable &v) final
Adds a new var to the variables of the multidimensional matrix.
Sequence< PRMInstance< GUM_SCALAR > *>::const_iterator const_array_iterator
Iterator over the PRMInstance in an array in this PRMSystem.
Definition: PRMSystem.h:250
<agrum/PRM/classElementContainer.h>
NodeId id() const
Returns the NodeId of this element in it&#39;s class DAG.
bool exists(const std::string &name) const
Retruns true either if name is an instance or an array in this PRMSystem.
A PRMClass is an object of a PRM representing a fragment of a Bayesian Network which can be instantia...
Definition: PRMClass.h:66
Size size() const
Returns the number of PRMInstance in this PRMSystem.
virtual void set(const Instantiation &i, const GUM_SCALAR &value) const final
Default implementation of MultiDimContainer::set().
void setFirst()
Assign the first values to the tuple of the Instantiation.
Size Idx
Type for indexes.
Definition: types.h:53
void endNetworkDeclaration() final
Tells the factory that we&#39;re out of a network declaration.
max aggregator
Definition: max.h:54
const DiscreteVariable & variable(const std::string &name) const
Returns a constant reference on a variable given it&#39;s name.
void addModality(const std::string &name) final
Adds a modality to the current variable.
PRMAttribute is a member of a Class in a PRM.
Definition: PRMAttribute.h:61
median aggregator
Definition: median.h:60
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
const iterator & end()
Returns a iterator at the end of the set of PRMInstance in this PRMSystem.
PRMClassElement< GUM_SCALAR > & lastElt()
Returns the last element of the slot chain, typically this is an gum::PRMAttribute or a gum::PRMAggre...
amplitude aggregator
Definition: amplitude.h:55
Idx label() const
Returns the label&#39;s index on which this aggregate applies.
Size NodeId
Type for node ids.
Definition: graphElements.h:98
min aggregator
Definition: min.h:53
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
A factory class to ease BayesNet construction.
Definition: BayesNet.h:45
bool end() const
Returns true if the Instantiation reached the end.
count aggregator
Definition: count.h:57