aGrUM  0.18.1
a C++ library for (probabilistic) graphical models
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 >
266  const PRMFormAttribute< GUM_SCALAR >& source) {
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.
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
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-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
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-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
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
std::string safeName_
The safe name of this PRMClassElement.
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.
const PRMClass< GUM_SCALAR > * class__
A pointe toward the class of this attribute.
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.
MultiDimImplementation< std::string > * formulas__
A pointer on the Potential of this attribute.
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-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
virtual PRMAttribute< GUM_SCALAR > * copy(Bijection< const DiscreteVariable *, const DiscreteVariable * > bij) const
See gum::prm::PRMAttribute.
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
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
Potential< GUM_SCALAR > * cpf__
A pointer on the Potential of this attribute.
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.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
PRMType * type__
The random variable type of this attribute.
bool end() const
Returns true if the Instantiation reached the end.
ClassElementType
Returns true if obj_ptr is of type PRMReferenceSlot.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.