aGrUM  0.14.2
PRMSystem_tpl.h
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
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  ***************************************************************************/
28 
33 
34 namespace gum {
35  namespace prm {
36  template < typename GUM_SCALAR >
37  PRMSystem< GUM_SCALAR >::PRMSystem(const std::string& name) : PRMObject(name) {
38  GUM_CONSTRUCTOR(PRMSystem);
39  }
40 
41  template < typename GUM_SCALAR >
43  GUM_DESTRUCTOR(PRMSystem);
44 
45  for (const auto& elt : *this)
46  delete elt.second;
47 
48  for (const auto& elt : __instanceMap)
49  delete elt.second;
50 
51  for (const auto& elt : __arrayMap)
52  delete elt.second.second;
53  }
54 
55  template < typename GUM_SCALAR >
57  if (__nameMap.exists(i->name())) {
58  GUM_ERROR(
60  "an Instance<GUM_SCALAR> with the same is already in this System");
61  }
62 
63  NodeId id = __skeleton.addNode();
64  __nodeIdMap.insert(id, i);
65  __nameMap.insert(i->name(), i);
66 
67  try {
68  __instanceMap[&(i->type())]->insert(i);
69  } catch (NotFound&) {
70  __instanceMap.insert(&(i->type()),
71  new Set< PRMInstance< GUM_SCALAR >* >());
72  __instanceMap[&(i->type())]->insert(i);
73  }
74 
75  return id;
76  }
77 
78  template < typename GUM_SCALAR >
80  BayesNetFactory< GUM_SCALAR >& factory) const {
81  factory.startNetworkDeclaration();
82  factory.addNetworkProperty("name", name());
83  factory.endNetworkDeclaration();
84 
85  // Adding nodes
86  for (PRMSystem< GUM_SCALAR >::const_iterator iter = begin(); iter != end();
87  ++iter) {
88  __groundAttr(*(iter.val()), factory);
89  }
90 
91  // Adding arcs and filling CPTs
92  for (PRMSystem< GUM_SCALAR >::const_iterator iter = begin(); iter != end();
93  ++iter) {
94  __groundRef(*(iter.val()), factory);
95  }
96  }
97 
98  template < typename GUM_SCALAR >
100  const PRMInstance< GUM_SCALAR >& instance,
101  BayesNetFactory< GUM_SCALAR >& factory) const {
102  for (const auto node : instance.type().containerDag()) {
103  // Working a Class<GUM_SCALAR> level because PRMAggregate<GUM_SCALAR>
104  // are
105  // instantiated as PRMAttribute<GUM_SCALAR> in an
106  // PRMInstance<GUM_SCALAR>
107  switch (instance.type().get(node).elt_type()) {
109  // TODO: make a special case for noisy-or
110  std::stringstream elt_name;
111  elt_name << instance.name() << "."
112  << instance.type().get(node).safeName();
113  DiscreteVariable* var = instance.get(node).type().variable().clone();
114  var->setName(elt_name.str());
115  factory.setVariable(*var); // var is copied by the factory
116  delete var;
117  break;
118  }
119 
121  std::stringstream elt_name;
122  elt_name << instance.name() << "."
123  << instance.type().get(node).safeName();
124  __groundAgg(instance.type().get(node), elt_name.str(), factory);
125  break;
126  }
127 
128  default:
129  break;
130  /* Do nothing */;
131  }
132  }
133  }
134 
135  template < typename GUM_SCALAR >
138  const std::string& name,
139  BayesNetFactory< GUM_SCALAR >& factory) const {
140  factory.startVariableDeclaration();
141  factory.variableName(name);
142  const DiscreteVariable& agg_var = elt.type().variable();
143 
144  for (Idx i = 0; i < agg_var.domainSize(); ++i) {
145  factory.addModality(agg_var.label(i));
146  }
147 
148  const PRMAggregate< GUM_SCALAR >& agg =
149  static_cast< const PRMAggregate< GUM_SCALAR >& >(elt);
150 
151  switch (agg.agg_type()) {
155  break;
156  }
157 
161  break;
162  }
163 
167  break;
168  }
169 
173  break;
174  }
175 
179  break;
180  }
181 
185  break;
186  }
187 
191  break;
192  }
193 
196  break;
197  }
198 
202  break;
203  }
204 
205  default: {
206  GUM_ERROR(OperationNotAllowed, "Aggregator not handled yet");
207  break;
208  }
209  }
210 
211  factory.endVariableDeclaration();
212  }
213 
214  template < typename GUM_SCALAR >
216  const PRMInstance< GUM_SCALAR >& instance,
217  BayesNetFactory< GUM_SCALAR >& factory) const {
218  for (const auto& elt : instance) {
219  std::stringstream elt_name;
220  elt_name << instance.name() << "." << elt.second->safeName();
221  factory.startParentsDeclaration(elt_name.str());
222 
223  for (const auto par :
224  instance.type().containerDag().parents(elt.second->id())) {
225  switch (instance.type().get(par).elt_type()) {
228  std::stringstream parent_name;
229  parent_name << instance.name() << "."
230  << instance.get(par).safeName();
231  factory.addParent(parent_name.str());
232  break;
233  }
234 
236  std::string parent_name =
237  static_cast< const PRMSlotChain< GUM_SCALAR >& >(
238  instance.type().get(par))
239  .lastElt()
240  .safeName();
241 
242  for (const auto ref : instance.getInstances(par)) {
243  std::stringstream sBuff;
244  sBuff << ref->name() << "." << parent_name;
245  factory.addParent(sBuff.str());
246  }
247 
248  break;
249  }
250 
251  default:
252  break;
253  /* nothing to do by default */
254  }
255  }
256 
257  factory.endParentsDeclaration();
258 
259  // Checking if we need to ground the Potential (only for class level
260  // attributes since
261  // aggregates Potentials are generated)
263  instance.type().get(elt.second->safeName())))
264  __groundPotential(instance, *elt.second, factory);
265  }
266  }
267 
268  template < typename GUM_SCALAR >
270  const PRMInstance< GUM_SCALAR >& instance,
271  const PRMAttribute< GUM_SCALAR >& attr,
272  BayesNetFactory< GUM_SCALAR >& factory) const {
274  std::stringstream var_name;
275  var_name << instance.name() << "." << attr.safeName();
276  bijection.insert(&(attr.type().variable()),
277  &(factory.variable(var_name.str())));
278 
279  for (const auto parent : instance.type().containerDag().parents(attr.id())) {
280  switch (instance.type().get(parent).elt_type()) {
283  std::stringstream parent_name;
284  parent_name << instance.name() << "."
285  << instance.get(parent).safeName();
286  bijection.insert(&(instance.get(parent).type().variable()),
287  &(factory.variable(parent_name.str())));
288  break;
289  }
290 
292  std::stringstream parent_name;
293  const PRMSlotChain< GUM_SCALAR >& sc =
294  static_cast< const PRMSlotChain< GUM_SCALAR >& >(
295  instance.type().get(parent));
296  parent_name << instance.getInstance(sc.id()).name() << "."
297  << sc.lastElt().safeName();
298  bijection.insert(&(instance.getInstance(sc.id())
299  .get(sc.lastElt().safeName())
300  .type()
301  .variable()),
302  &(factory.variable(parent_name.str())));
303  break;
304  }
305 
306  default: {
308  "invalid ClassElement<GUM_SCALAR> type as parent.");
309  break;
310  }
311  }
312  }
313 
314  // Copy Potential
315  // DO NOT USE MultiDimBijArray as they will wreck havok if you delete
316  // the prm befor its grounded BN (happens a lot in pyAgrum)
318  for (auto var : attr.cpf().variablesSequence()) {
319  p->add(*(bijection.second(var)));
320  }
321  Instantiation inst(attr.cpf()), jnst(*p);
322  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
323  inst.inc(), jnst.inc()) {
324  p->set(jnst, attr.cpf().get(inst));
325  }
326  GUM_ASSERT(inst.end() && jnst.end());
327  factory.setVariableCPT(var_name.str(), p, false);
328  }
329 
330  template < typename GUM_SCALAR >
331  INLINE NodeId PRMSystem< GUM_SCALAR >::add(const std::string& array,
333  return add(array, &i);
334  }
335 
336  template < typename GUM_SCALAR >
338  return __skeleton;
339  }
340 
341  template < typename GUM_SCALAR >
343  try {
344  return *(__nodeIdMap[id]);
345  } catch (NotFound&) {
346  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id");
347  }
348  }
349 
350  template < typename GUM_SCALAR >
351  INLINE const PRMInstance< GUM_SCALAR >&
353  try {
354  return *(__nodeIdMap[id]);
355  } catch (NotFound&) {
356  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id");
357  }
358  }
359 
360  template < typename GUM_SCALAR >
361  INLINE NodeId
363  try {
364  return __nodeIdMap.keyByVal(const_cast< PRMInstance< GUM_SCALAR >* >(&i));
365  } catch (NotFound&) {
366  GUM_ERROR(NotFound, "found no Instance<GUM_SCALAR> matching the given id");
367  }
368  }
369 
370  template < typename GUM_SCALAR >
372  return PRMObject::prm_type::SYSTEM;
373  }
374 
375  template < typename GUM_SCALAR >
377  return __nodeIdMap.size();
378  }
379 
380  template < typename GUM_SCALAR >
382  const PRMClass< GUM_SCALAR >& c) const {
383  return __instanceMap.exists(const_cast< PRMClass< GUM_SCALAR >* >(&c));
384  }
385 
386  template < typename GUM_SCALAR >
387  INLINE bool
388  PRMSystem< GUM_SCALAR >::isInstance(const std::string& name) const {
389  return __nameMap.exists(name);
390  }
391 
392  template < typename GUM_SCALAR >
393  INLINE bool PRMSystem< GUM_SCALAR >::isArray(const std::string& name) const {
394  return __arrayMap.exists(name);
395  }
396 
397  template < typename GUM_SCALAR >
399  for (auto iter = begin(); iter != end(); ++iter) {
400  (*(iter.val())).instantiate();
401  }
402  }
403 
404  template < typename GUM_SCALAR >
406  PRMSystem< GUM_SCALAR >::get(const std::string& name) {
407  try {
408  return *(__nameMap[name]);
409  } catch (NotFound&) {
411  "found no Instance<GUM_SCALAR> matching the given name");
412  }
413  }
414 
415  template < typename GUM_SCALAR >
416  INLINE const PRMInstance< GUM_SCALAR >&
417  PRMSystem< GUM_SCALAR >::get(const std::string& name) const {
418  try {
419  return *(__nameMap[name]);
420  } catch (NotFound&) {
422  "found no Instance<GUM_SCALAR> matching the given name");
423  }
424  }
425 
426  template < typename GUM_SCALAR >
427  INLINE const Set< PRMInstance< GUM_SCALAR >* >&
429  try {
430  return *(__instanceMap[const_cast< PRMClass< GUM_SCALAR >* >(&type)]);
431  } catch (NotFound&) {
432  GUM_ERROR(
433  NotFound,
434  "the given Class<GUM_SCALAR> has no instantiation in this System");
435  }
436  }
437 
438  template < typename GUM_SCALAR >
439  INLINE const Sequence< PRMInstance< GUM_SCALAR >* >&
440  PRMSystem< GUM_SCALAR >::getArray(const std::string& name) const {
441  try {
442  return *(__arrayMap[name].second);
443  } catch (NotFound&) {
444  GUM_ERROR(NotFound, "found no array matching the given name");
445  }
446  }
447 
448  template < typename GUM_SCALAR >
450  PRMSystem< GUM_SCALAR >::getArrayType(const std::string& name) {
451  try {
452  return *(__arrayMap[name].first);
453  } catch (NotFound&) {
454  GUM_ERROR(NotFound, "found no array matching the given name");
455  }
456  }
457 
458  template < typename GUM_SCALAR >
460  PRMSystem< GUM_SCALAR >::getArrayType(const std::string& name) const {
461  try {
462  return *(__arrayMap[name].first);
463  } catch (NotFound&) {
464  GUM_ERROR(NotFound, "found no array matching the given name");
465  }
466  }
467 
468  template < typename GUM_SCALAR >
469  INLINE NodeId PRMSystem< GUM_SCALAR >::add(const std::string& array,
471  try {
472  if (i->type().isSubTypeOf(*(__arrayMap[array].first))) {
473  NodeId id = add(i);
474  __arrayMap[array].second->insert(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&) {
482  GUM_ERROR(NotFound, "found no array matching the given name");
483  }
484  }
485 
486  template < typename GUM_SCALAR >
488  const std::string& array, PRMClassElementContainer< GUM_SCALAR >& type) {
489  if (__arrayMap.exists(array)) {
491  "an array '" << array << "' is already in this System");
492  }
493 
494  __arrayMap.insert(array,
496  &type, new Sequence< PRMInstance< GUM_SCALAR >* >()));
497  }
498 
499  template < typename GUM_SCALAR >
500  INLINE typename PRMSystem< GUM_SCALAR >::iterator
502  return __nodeIdMap.begin();
503  }
504 
505  template < typename GUM_SCALAR >
506  INLINE const typename PRMSystem< GUM_SCALAR >::iterator&
508  return __nodeIdMap.end();
509  }
510 
511  template < typename GUM_SCALAR >
514  return __nodeIdMap.begin();
515  }
516 
517  template < typename GUM_SCALAR >
518  INLINE const typename PRMSystem< GUM_SCALAR >::const_iterator&
520  return __nodeIdMap.end();
521  }
522 
523  template < typename GUM_SCALAR >
525  PRMSystem< GUM_SCALAR >::begin(const std::string& a) {
526  try {
527  return __arrayMap[a].second->begin();
528  } catch (NotFound&) {
529  GUM_ERROR(NotFound, "found no array matching the given name");
530  }
531  }
532 
533  template < typename GUM_SCALAR >
534  INLINE const typename PRMSystem< GUM_SCALAR >::array_iterator&
535  PRMSystem< GUM_SCALAR >::end(const std::string& a) {
536  try {
537  return __arrayMap[a].second->end();
538  } catch (NotFound&) {
539  GUM_ERROR(NotFound, "found no array matching the given name");
540  }
541  }
542 
543  template < typename GUM_SCALAR >
545  PRMSystem< GUM_SCALAR >::begin(const std::string& a) const {
546  try {
547  return __arrayMap[a].second->begin();
548  } catch (NotFound&) {
549  GUM_ERROR(NotFound, "found no array matching the given name");
550  }
551  }
552 
553  template < typename GUM_SCALAR >
554  INLINE const typename PRMSystem< GUM_SCALAR >::const_array_iterator&
555  PRMSystem< GUM_SCALAR >::end(const std::string& a) const {
556  try {
557  return __arrayMap[a].second->end();
558  } catch (NotFound&) {
559  GUM_ERROR(NotFound, "found no array matching the given name");
560  }
561  }
562 
563  template < typename GUM_SCALAR >
564  INLINE bool PRMSystem< GUM_SCALAR >::exists(const std::string& name) const {
565  return __nameMap.exists(name) || __arrayMap.exists(name);
566  }
567 
568  } /* namespace prm */
569 } /* 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:57
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:2462
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:32
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:60
void setVariable(const DiscreteVariable &var) final
Define a variable.
or aggregator
Definition: or.h:53
Unsafe Iterators for hashtablesHashTableIterator provides a fast but unsafe way to parse HashTables...
Definition: hashTable.h:2747
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1019
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.
forall aggregator
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.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
min aggregator
PRMSystem(const std::string &name)
Default constructor.
Definition: PRMSystem_tpl.h:37
forall aggregator
Definition: forall.h:52
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:162
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:66
And aggregator.
Definition: and.h:52
void inc()
Operator increment.
exists aggregator
Definition: exists.h:51
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.
forall aggregator
Base class for all oriented graphs.
Definition: diGraph.h:108
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
Definition: PRMObject.h:226
max aggregator
Sequence< PRMInstance< GUM_SCALAR > *>::iterator array_iterator
Iterator over the PRMInstance in an array in this PRMSystem.
Definition: PRMSystem.h:233
void instantiate()
Instantiate all the PRMInstance in this PRMSystem.
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1803
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.
Headers of PRMSystem.
A PRMSlotChain represents a sequence of gum::prm::PRMClassElement<GUM_SCALAR> where the n-1 first gum...
Definition: PRMObject.h:218
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:290
Abstract base class for any element defined in a PRM.
Definition: PRMObject.h:53
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
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:247
<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:63
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:50
void endNetworkDeclaration() final
Tells the factory that we&#39;re out of a network declaration.
max aggregator
Definition: max.h:51
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:58
median aggregator
Definition: median.h:57
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
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:52
Idx label() const
Returns the label&#39;s index on which this aggregate applies.
Size NodeId
Type for node ids.
Definition: graphElements.h:97
min aggregator
Definition: min.h:50
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
A factory class to ease BayesNet construction.
Definition: BayesNet.h:43
bool end() const
Returns true if the Instantiation reached the end.
count aggregator
Definition: count.h:54