aGrUM  0.16.0
PRMFormAttribute_tpl.h
Go to the documentation of this file.
1 
29 #include <iostream>
30 
32 
35 
36 // to ease IDE parser
38 
39 namespace gum {
40  namespace prm {
41 
42  template < typename GUM_SCALAR >
44  const PRMClass< GUM_SCALAR >& c,
45  const std::string& name,
46  const PRMType& type,
48  PRMAttribute< GUM_SCALAR >(name),
49  __type(new PRMType(type)), __cpf(0), __formulas(impl), __class(&c) {
50  GUM_CONSTRUCTOR(PRMFormAttribute);
51  __formulas->add(__type->variable());
52  this->_safeName =
54  }
55 
56  template < typename GUM_SCALAR >
58  GUM_DESTRUCTOR(PRMFormAttribute);
59  delete __type;
60  delete __cpf;
61  delete __formulas;
62  }
63 
64  template < typename GUM_SCALAR >
66  const PRMClass< GUM_SCALAR >& c) const {
67  auto impl = static_cast< MultiDimImplementation< std::string >* >(
68  this->__formulas->newFactory());
70  c, this->name(), this->type(), impl);
71  }
72 
73  template < typename GUM_SCALAR >
76  auto copy =
77  new PRMFormAttribute< GUM_SCALAR >(*__class, this->name(), this->type());
78  for (auto var : __formulas->variablesSequence()) {
79  if (var != &(__type->variable())) { copy->__formulas->add(*var); }
80  }
81 
82  Instantiation inst(*(copy->__formulas)), jnst(*__formulas);
83  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
84  inst.inc(), jnst.inc()) {
85  copy->__formulas->set(inst, __formulas->get(jnst));
86  }
87 
88  GUM_ASSERT(copy->__formulas->contains(copy->__type->variable()));
89  return copy;
90  }
91 
92  template < typename GUM_SCALAR >
95  const PRMAttribute< GUM_SCALAR >& source) {
96  delete __formulas;
98 
99  for (const auto& var : source.cpf().variablesSequence()) {
100  __formulas->add(*(bij.second(var)));
101  }
102 
103  if (dynamic_cast< const PRMFormAttribute< GUM_SCALAR >* >(&source)) {
104  const auto& src =
105  static_cast< const PRMFormAttribute< GUM_SCALAR >& >(source);
106 
107  Instantiation inst(__formulas), jnst(src.__formulas);
108 
109  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
110  inst.inc(), jnst.inc()) {
111  __formulas->set(inst, src.__formulas->get(jnst));
112  }
113 
114  GUM_ASSERT(inst.end() && jnst.end());
115 
116  } else {
117  Instantiation inst(__formulas), jnst(source.cpf());
118 
119  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
120  inst.inc(), jnst.inc()) {
121  auto val = std::to_string(source.cpf().get(jnst));
122  __formulas->set(inst, val);
123  }
124 
125  GUM_ASSERT(inst.end() && jnst.end());
126  }
127 
128  if (__cpf) {
129  delete __cpf;
130  __cpf = 0;
131  }
132 
133  GUM_ASSERT(__formulas->contains(__type->variable()));
134  GUM_ASSERT(!__formulas->contains(source.type().variable()));
135  }
136 
137  template < typename GUM_SCALAR >
140  return this->prm_attribute;
141  }
142 
143  template < typename GUM_SCALAR >
145  return *__type;
146  }
147 
148  template < typename GUM_SCALAR >
150  return *__type;
151  }
152 
153  template < typename GUM_SCALAR >
155  if (__cpf == 0) { __fillCpf(); }
156  return *__cpf;
157  }
158 
159  template < typename GUM_SCALAR >
161  const PRMClassElement< GUM_SCALAR >& elt) {
162  try {
163  if (__cpf) {
164  delete __cpf;
165  __cpf = 0;
166  }
167  __formulas->add(elt.type().variable());
168  } catch (DuplicateElement&) {
170  elt.name() << " as parent of " << this->name());
171  } catch (OperationNotAllowed&) {
173  elt.name() << " of wrong type as parent of " << this->name(););
174  }
175 
176  GUM_ASSERT(__formulas->contains(__type->variable()));
177  }
178 
179  template < typename GUM_SCALAR >
181  const PRMClassElement< GUM_SCALAR >& elt) {}
182 
183  template < typename GUM_SCALAR >
187 
188  try {
189  cast =
191  } catch (NotFound&) {
193  "this ScalarAttribute can not have cast descendant");
194  }
195 
196  cast->addParent(*this);
197 
198  const DiscreteVariable& my_var = type().variable();
199  DiscreteVariable& cast_var = cast->type().variable();
200  Instantiation inst(cast->cpf());
201 
202  for (inst.setFirst(); !inst.end(); inst.inc()) {
203  if (type().label_map()[inst.val(my_var)] == inst.val(cast_var)) {
204  cast->cpf().set(inst, 1);
205  } else {
206  cast->cpf().set(inst, 0);
207  }
208  }
209 
210  GUM_ASSERT(__formulas->contains(__type->variable()));
211  return cast;
212  }
213 
214  template < typename GUM_SCALAR >
217  try {
218  type().setSuper(cast->type());
219  } catch (OperationNotAllowed&) {
221  "this ScalarAttribute can not have cast descendant");
222  } catch (WrongType&) {
223  std::stringstream msg;
224  msg << type().name() << " is not a subtype of " << cast->type().name();
225  GUM_ERROR(WrongType, msg.str());
226  }
227 
228  cast->becomeCastDescendant(type());
229  }
230 
231  template < typename GUM_SCALAR >
233  delete __formulas;
234 
236  __formulas->add(type().variable());
237  __formulas->add(subtype.variable());
238 
240 
241  for (inst.setFirst(); !inst.end(); inst.inc()) {
242  auto my_pos = inst.pos(subtype.variable());
243  if (subtype.label_map()[my_pos] == inst.pos(type().variable())) {
244  __formulas->set(inst, "1");
245  } else {
246  __formulas->set(inst, "0");
247  }
248  }
249 
250  if (__cpf) {
251  delete __cpf;
252  __cpf = nullptr;
253  }
254  }
255 
256  template < typename GUM_SCALAR >
258  const PRMFormAttribute& source) :
259  PRMAttribute< GUM_SCALAR >(source.name()) {
260  GUM_CONS_CPY(PRMFormAttribute);
261  GUM_ERROR(OperationNotAllowed, "Cannot copy FormAttribute");
262  }
263 
264  template < typename GUM_SCALAR >
267  GUM_ERROR(OperationNotAllowed, "Cannot copy FormAttribute");
268  }
269 
270  template < typename GUM_SCALAR >
272  try {
273  if (__cpf) { delete __cpf; }
274 
276 
277  for (auto var : __formulas->variablesSequence()) {
278  __cpf->add(*var);
279  }
280 
281  auto params = __class->scope();
282 
284  Instantiation jnst(__cpf);
285 
286  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
287  inst.inc(), jnst.inc()) {
288  // With CPT defined using rules, empty values can appear
289  auto val = __formulas->get(inst);
290  if (val == "") { val = "0.0"; }
291 
292  Formula f(val);
293 
294  for (auto item : params) {
295  f.variables().insert(item.first, item.second->value());
296  }
297 
298  __cpf->set(jnst, (GUM_SCALAR)f.result());
299  }
300 
301  GUM_ASSERT(inst.end() && jnst.end());
302 
303  } catch (Exception&) { GUM_ERROR(NotFound, "undefined value in cpt"); }
304  GUM_ASSERT(__formulas->contains(__type->variable()));
305  }
306 
307  template < typename GUM_SCALAR >
310  if (__cpf) {
311  delete __cpf;
312  __cpf = 0;
313  }
314  return *__formulas;
315  }
316 
317  template < typename GUM_SCALAR >
320  return *__formulas;
321  }
322 
323  template < typename GUM_SCALAR >
325  const PRMType& new_type) {
326  if (&(old_type) == __type) {
327  GUM_ERROR(OperationNotAllowed, "Cannot replace attribute own type");
328  }
329  if (old_type->domainSize() != new_type->domainSize()) {
331  "Cannot replace types with difference domain size");
332  }
333  if (!__formulas->contains(old_type.variable())) {
334  GUM_ERROR(NotFound, "could not find variable " + old_type.name());
335  }
336 
337  auto old = __formulas;
338 
340 
341  for (auto var : old->variablesSequence()) {
342  if (var != &(old_type.variable())) {
343  __formulas->add(*var);
344  } else {
345  __formulas->add(new_type.variable());
346  }
347  }
348 
349  Instantiation inst(__formulas), jnst(old);
350 
351  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
352  inst.inc(), jnst.inc()) {
353  __formulas->set(inst, old->get(jnst));
354  }
355 
356  delete old;
357 
358  if (__cpf) {
359  delete __cpf;
360  __cpf = 0;
361  }
362 
363  GUM_ASSERT(inst.end() && jnst.end());
364  GUM_ASSERT(__formulas->contains(__type->variable()));
365  GUM_ASSERT(!__formulas->contains(new_type.variable()));
366  GUM_ASSERT(__formulas->contains(new_type.variable()));
367  }
368 
369  template < typename GUM_SCALAR >
371  return __type;
372  }
373 
374  template < typename GUM_SCALAR >
376  if (__type->variable().domainSize() != t->variable().domainSize()) {
378  "Cannot replace types with difference domain size");
379  }
380  auto old = __formulas;
381 
383 
384  for (auto var : old->variablesSequence()) {
385  if (var != &(__type->variable())) {
386  __formulas->add(*var);
387  } else {
388  __formulas->add(t->variable());
389  }
390  }
391 
392  Instantiation inst(__formulas), jnst(old);
393 
394  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
395  inst.inc(), jnst.inc()) {
396  __formulas->set(inst, old->get(jnst));
397  }
398 
399  delete old;
400 
401  __type = t;
402 
403  if (__cpf) {
404  delete __cpf;
405  __cpf = 0;
406  }
407 
408  GUM_ASSERT(__formulas->contains(__type->variable()));
409  GUM_ASSERT(inst.end() && jnst.end());
410  }
411 
412  } /* namespace prm */
413 } /* namespace gum */
virtual void addParent(const PRMClassElement< GUM_SCALAR > &elt)
See gum::prm::PRMAttribute.
Potential< GUM_SCALAR > * __cpf
A pointer on the Potential of this attribute.
double result() const
Returns the result of this gum::Formula.
Definition: formula.cpp:301
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.
const std::string & name() const
Returns the name of this object.
Definition: PRMType_inl.h:68
PRMType & superType()
Returns the super type of this type.
Definition: PRMType_inl.h:36
MultiDimImplementation< std::string > * __formulas
A pointer on the Potential of this attribute.
void setSuper(PRMType &t)
Changes the PRMType of this PRMType super.
Definition: PRMType_inl.h:80
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition: PRMType_inl.h:45
Idx pos(const DiscreteVariable &v) const final
Returns the position of the variable v.
virtual void setAsCastDescendant(PRMAttribute< GUM_SCALAR > *attr)
See gum::prm::PRMAttribute.
const std::string & name() const
Returns the name of this object.
Definition: PRMObject_inl.h:35
virtual void swap(const PRMType &old_type, const PRMType &new_type)
Swap old_type with new_type in the PRMClassElement cpt.
Evaluates a string as a algebraic formula.
Definition: formula.h:274
virtual PRMType & type()=0
See gum::PRMClassElement::type().
virtual PRMAttribute< GUM_SCALAR > * newFactory(const PRMClass< GUM_SCALAR > &c) const
See gum::prm::PRMAttribute.
Abstract class representing an element of PRM class.
virtual PRMClassElement< GUM_SCALAR >::ClassElementType elt_type() const
See gum::prm::PRMAttribute.
virtual MultiDimImplementation< std::string > & formulas()
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Base class for discrete random variable.
virtual PRMType & type()
See gum::PRMClassElement::type().
virtual void copyCpf(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bif, const PRMAttribute< GUM_SCALAR > &source)
See gum::prm::PRMAttribute.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
PRMFormAttribute & operator=(const PRMFormAttribute &source)
virtual PRMAttribute< GUM_SCALAR > * getCastDescendant() const
See gum::prm::PRMAttribute.
virtual void becomeCastDescendant(PRMType &subtype)=0
Change this attribute to be a cast descendant of a an attribute with type subtype.
virtual std::string cast(const PRMType &t) const
Returns the name of the cast descendant with PRMType t of this PRMClassElement.
virtual Size domainSize() const =0
virtual const Potential< GUM_SCALAR > & cpf() const
See gum::PRMClassElement::cpf().
virtual void set(const Instantiation &i, const GUM_SCALAR &value) const
Changes the value pointed by i.
virtual const Potential< GUM_SCALAR > & cpf() const
See gum::prm::PRMAttribute.
PRMFormAttribute(const PRMClass< GUM_SCALAR > &c, const std::string &name, const PRMType &type, MultiDimImplementation< std::string > *impl=new MultiDimArray< std::string >())
std::string to_string(const Formula &f)
Definition: formula_inl.h:499
void inc()
Operator increment.
virtual const Potential< GUM_SCALAR > & cpf() const =0
See gum::PRMClassElement::cpf().
virtual void addChild(const PRMClassElement< GUM_SCALAR > &elt)
See gum::prm::PRMAttribute.
Base class for all aGrUM&#39;s exceptions.
Definition: exceptions.h:106
Multidimensional matrix stored as an array in memory.
Definition: multiDimArray.h:54
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1805
This is a decoration of the DiscreteVariable class.
Definition: PRMType.h:63
virtual void add(const DiscreteVariable &v) override
Adds a new var to the variables of the multidimensional matrix.
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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
virtual PRMAttribute< GUM_SCALAR > * copy(Bijection< const DiscreteVariable *, const DiscreteVariable * > bij) const
See gum::prm::PRMAttribute.
PRMType * __type
The random variable type of this attribute.
virtual const Sequence< const DiscreteVariable *> & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:83
static std::string LEFT_CAST()
Enumeration of the different types of objects handled by a PRM.
Definition: PRMObject.h:79
const PRMClass< GUM_SCALAR > * __class
A pointe toward the class of this attribute.
A PRMClass is an object of a PRM representing a fragment of a Bayesian Network which can be instantia...
Definition: PRMClass.h:66
void setFirst()
Assign the first values to the tuple of the Instantiation.
const std::vector< Idx > & label_map() const
Returns the vector in which the i-th element is the Idx of the super type&#39;s label for the i-th label ...
Definition: PRMType_inl.h:94
virtual void becomeCastDescendant(PRMType &subtype)
Change this attribute to be a cast descendant of a an attribute with type subtype.
HashTable< std::string, double > & variables()
Returns the variables used by this gum::Formula.
Definition: formula_inl.h:437
PRMAttribute is a member of a Class in a PRM.
Definition: PRMAttribute.h:61
virtual GUM_SCALAR get(const Instantiation &i) const
Returns the value pointed by i.
virtual bool contains(const DiscreteVariable &v) const override
Returns true if var is in *this.
virtual void addParent(const PRMClassElement< GUM_SCALAR > &elt)
See gum::PRMClassElement::_addParent().
virtual MultiDimContainer< GUM_SCALAR > * newFactory() const override=0
Creates an empty clone of this MultiDimContainer.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const std::string & name() const
returns the name of the variable
static std::string RIGHT_CAST()
Enumeration of the different types of objects handled by a PRM.
Definition: PRMObject.h:80
<agrum/PRM/elements/formAttribute.h>
<agrum/PRM/elements/scalarAttribute.h>
virtual PRMType & type()
See gum::prm::PRMAttribute.
std::string _safeName
The safe name of this PRMClassElement.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
bool end() const
Returns true if the Instantiation reached the end.
ClassElementType
Returns true if obj_ptr is of type PRMReferenceSlot.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.