aGrUM  0.13.2
PRMFormAttribute_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  ***************************************************************************/
26 #include <iostream>
27 
29 
32 
33 // to ease IDE parser
35 
36 namespace gum {
37  namespace prm {
38 
39  template < typename GUM_SCALAR >
41  const PRMClass< GUM_SCALAR >& c,
42  const std::string& name,
43  const PRMType< GUM_SCALAR >& type,
45  PRMAttribute< GUM_SCALAR >(name),
46  __type(new PRMType< GUM_SCALAR >(type)), __cpf(0), __formulas(impl),
47  __class(&c) {
48  GUM_CONSTRUCTOR(PRMFormAttribute);
49  __formulas->add(__type->variable());
50  this->_safeName =
52  }
53 
54  template < typename GUM_SCALAR >
56  GUM_DESTRUCTOR(PRMFormAttribute);
57  delete __type;
58  delete __cpf;
59  delete __formulas;
60  }
61 
62  template < typename GUM_SCALAR >
64  const PRMClass< GUM_SCALAR >& c) const {
65  auto impl = static_cast< MultiDimImplementation< std::string >* >(
66  this->__formulas->newFactory());
67  return new PRMFormAttribute(c, this->name(), this->type(), impl);
68  }
69 
70  template < typename GUM_SCALAR >
73  auto copy =
74  new PRMFormAttribute< GUM_SCALAR >(*__class, this->name(), this->type());
75  for (auto var : __formulas->variablesSequence()) {
76  if (var != &(__type->variable())) { copy->__formulas->add(*var); }
77  }
78 
79  Instantiation inst(*(copy->__formulas)), jnst(*__formulas);
80  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
81  inst.inc(), jnst.inc()) {
82  copy->__formulas->set(inst, __formulas->get(jnst));
83  }
84 
85  GUM_ASSERT(copy->__formulas->contains(copy->__type->variable()));
86  return copy;
87  }
88 
89  template < typename GUM_SCALAR >
92  const PRMAttribute< GUM_SCALAR >& source) {
93  delete __formulas;
95 
96  for (const auto& var : source.cpf().variablesSequence()) {
97  __formulas->add(*(bij.second(var)));
98  }
99 
100  if (dynamic_cast< const PRMFormAttribute* >(&source)) {
101  const auto& src = static_cast< const PRMFormAttribute& >(source);
102 
103  Instantiation inst(__formulas), jnst(src.__formulas);
104 
105  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
106  inst.inc(), jnst.inc()) {
107  __formulas->set(inst, src.__formulas->get(jnst));
108  }
109 
110  GUM_ASSERT(inst.end() && jnst.end());
111 
112  } else {
113  Instantiation inst(__formulas), jnst(source.cpf());
114 
115  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
116  inst.inc(), jnst.inc()) {
117  auto val = std::to_string(source.cpf().get(jnst));
118  __formulas->set(inst, val);
119  }
120 
121  GUM_ASSERT(inst.end() && jnst.end());
122  }
123 
124  if (__cpf) {
125  delete __cpf;
126  __cpf = 0;
127  }
128 
129  GUM_ASSERT(__formulas->contains(__type->variable()));
130  GUM_ASSERT(!__formulas->contains(source.type().variable()));
131  }
132 
133  template < typename GUM_SCALAR >
136  return this->prm_attribute;
137  }
138 
139  template < typename GUM_SCALAR >
141  return *__type;
142  }
143 
144  template < typename GUM_SCALAR >
146  return *__type;
147  }
148 
149  template < typename GUM_SCALAR >
151  if (__cpf == 0) { __fillCpf(); }
152  return *__cpf;
153  }
154 
155  template < typename GUM_SCALAR >
157  const PRMClassElement< GUM_SCALAR >& elt) {
158  try {
159  if (__cpf) {
160  delete __cpf;
161  __cpf = 0;
162  }
163  __formulas->add(elt.type().variable());
164  } catch (DuplicateElement&) {
165  std::stringstream msg;
166  msg << ": " << elt.name() << " as parent of " << this->name();
167  GUM_ERROR(DuplicateElement, msg.str());
168  } catch (OperationNotAllowed&) {
169  std::stringstream msg;
170  msg << ": " << elt.name() << " of wrong type as parent of "
171  << this->name();
172  GUM_ERROR(OperationNotAllowed, msg.str());
173  }
174 
175  GUM_ASSERT(__formulas->contains(__type->variable()));
176  }
177 
178  template < typename GUM_SCALAR >
180  const PRMClassElement< GUM_SCALAR >& elt) {}
181 
182  template < typename GUM_SCALAR >
186 
187  try {
188  cast =
189  new PRMScalarAttribute< GUM_SCALAR >(this->name(), type().superType());
190  } catch (NotFound&) {
192  "this ScalarAttribute can not have cast descendant");
193  }
194 
195  cast->addParent(*this);
196 
197  const DiscreteVariable& my_var = type().variable();
198  DiscreteVariable& cast_var = cast->type().variable();
199  Instantiation inst(cast->cpf());
200 
201  for (inst.setFirst(); !inst.end(); inst.inc()) {
202  if (type().label_map()[inst.val(my_var)] == inst.val(cast_var)) {
203  cast->cpf().set(inst, 1);
204  } else {
205  cast->cpf().set(inst, 0);
206  }
207  }
208 
209  GUM_ASSERT(__formulas->contains(__type->variable()));
210  return cast;
211  }
212 
213  template < typename GUM_SCALAR >
216  try {
217  type().setSuper(cast->type());
218  } catch (OperationNotAllowed&) {
220  "this ScalarAttribute can not have cast descendant");
221  } catch (WrongType&) {
222  std::stringstream msg;
223  msg << type().name() << " is not a subtype of " << cast->type().name();
224  GUM_ERROR(WrongType, msg.str());
225  }
226 
227  cast->becomeCastDescendant(type());
228  }
229 
230  template < typename GUM_SCALAR >
232  PRMType< GUM_SCALAR >& subtype) {
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  operator=(const PRMFormAttribute& 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 >
324  void
326  const PRMType< GUM_SCALAR >& new_type) {
327  if (&(old_type) == __type) {
328  GUM_ERROR(OperationNotAllowed, "Cannot replace attribute own type");
329  }
330  if (old_type->domainSize() != new_type->domainSize()) {
332  "Cannot replace types with difference domain size");
333  }
334  if (!__formulas->contains(old_type.variable())) {
335  GUM_ERROR(NotFound, "could not find variable " + old_type.name());
336  }
337 
338  auto old = __formulas;
339 
341 
342  for (auto var : old->variablesSequence()) {
343  if (var != &(old_type.variable())) {
344  __formulas->add(*var);
345  } else {
346  __formulas->add(new_type.variable());
347  }
348  }
349 
350  Instantiation inst(__formulas), jnst(old);
351 
352  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
353  inst.inc(), jnst.inc()) {
354  __formulas->set(inst, old->get(jnst));
355  }
356 
357  delete old;
358 
359  if (__cpf) {
360  delete __cpf;
361  __cpf = 0;
362  }
363 
364  GUM_ASSERT(inst.end() && jnst.end());
365  GUM_ASSERT(__formulas->contains(__type->variable()));
366  GUM_ASSERT(!__formulas->contains(new_type.variable()));
367  GUM_ASSERT(__formulas->contains(new_type.variable()));
368  }
369 
370  template < typename GUM_SCALAR >
372  return __type;
373  }
374 
375  template < typename GUM_SCALAR >
377  if (__type->variable().domainSize() != t->variable().domainSize()) {
379  "Cannot replace types with difference domain size");
380  }
381  auto old = __formulas;
382 
384 
385  for (auto var : old->variablesSequence()) {
386  if (var != &(__type->variable())) {
387  __formulas->add(*var);
388  } else {
389  __formulas->add(t->variable());
390  }
391  }
392 
393  Instantiation inst(__formulas), jnst(old);
394 
395  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
396  inst.inc(), jnst.inc()) {
397  __formulas->set(inst, old->get(jnst));
398  }
399 
400  delete old;
401 
402  __type = t;
403 
404  if (__cpf) {
405  delete __cpf;
406  __cpf = 0;
407  }
408 
409  GUM_ASSERT(__formulas->contains(__type->variable()));
410  GUM_ASSERT(inst.end() && jnst.end());
411  }
412 
413  } /* namespace prm */
414 } /* namespace gum */
virtual void addParent(const PRMClassElement< GUM_SCALAR > &elt)
See gum::prm::PRMAttribute.
const std::string & name() const
Returns the name of this object.
Definition: PRMType_tpl.h:170
Potential< GUM_SCALAR > * __cpf
A pointer on the Potential of this attribute.
aGrUM&#39;s Potential is a multi-dimensional array with tensor operators.
Definition: potential.h:57
virtual void becomeCastDescendant(PRMType< GUM_SCALAR > &subtype)=0
Change this attribute to be a cast descendant of a an attribute with type subtype.
MultiDimImplementation< std::string > * __formulas
A pointer on the Potential of this attribute.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
double result() const
Returns the result of this gum::Formula.
Definition: formula.cpp:295
PRMFormAttribute(const PRMClass< GUM_SCALAR > &c, const std::string &name, const PRMType< GUM_SCALAR > &type, MultiDimImplementation< std::string > *impl=new MultiDimArray< std::string >())
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.
virtual PRMAttribute< GUM_SCALAR > * copy(Bijection< const DiscreteVariable *, const DiscreteVariable * > bij) const
See gum::prm::PRMAttribute.
Evaluates a string as a algebraic formula.
Definition: formula.h:271
PRMType< GUM_SCALAR > * __type
The random variable type of this attribute.
Abstract class representing an element of PRM class.
virtual MultiDimImplementation< std::string > & formulas()
virtual const Potential< GUM_SCALAR > & cpf() const
See gum::PRMClassElement::cpf().
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition: PRMType_tpl.h:135
Headers files for the gum::FormulaPart and gum::Formula classes.
Base class for discrete random variable.
virtual void copyCpf(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bif, const PRMAttribute< GUM_SCALAR > &source)
See gum::prm::PRMAttribute.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
virtual PRMClassElement< GUM_SCALAR >::ClassElementType elt_type() const
See gum::prm::PRMAttribute.
const std::string & name() const
Returns the name of this object.
Definition: PRMObject_inl.h:32
virtual PRMType< GUM_SCALAR > * _type()
virtual std::string cast(const PRMType< GUM_SCALAR > &t) const
Returns the name of the cast descendant with PRMType t of this PRMClassElement.
PRMFormAttribute & operator=(const PRMFormAttribute &source)
virtual PRMType< GUM_SCALAR > & type()
See gum::prm::PRMAttribute.
std::string to_string(const Formula &f)
Definition: formula_inl.h:479
void inc()
Operator increment.
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.
virtual void becomeCastDescendant(PRMType< GUM_SCALAR > &subtype)
Change this attribute to be a cast descendant of a an attribute with type subtype.
virtual const Potential< GUM_SCALAR > & cpf() const =0
See gum::PRMClassElement::cpf().
virtual void addChild(const PRMClassElement< GUM_SCALAR > &elt)
See gum::prm::PRMAttribute.
virtual PRMAttribute< GUM_SCALAR > * newFactory(const PRMClass< GUM_SCALAR > &c) const
See gum::prm::PRMAttribute.
Base class for all aGrUM&#39;s exceptions.
Definition: exceptions.h:103
Multidimensional matrix stored as an array in memory.
Definition: multiDimArray.h:51
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1803
This is a decoration of the DiscreteVariable class.
Definition: PRMObject.h:207
virtual void add(const DiscreteVariable &v) override
Adds a new var to the variables of the multidimensional matrix.
virtual PRMType< GUM_SCALAR > & type()=0
See gum::PRMClassElement::type().
bool end() const
Returns true if the Instantiation reached the end.
virtual const Sequence< const DiscreteVariable * > & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
Headers of gum::PRMFormAttribute.
Headers of Class.
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
virtual void swap(const PRMType< GUM_SCALAR > &old_type, const PRMType< GUM_SCALAR > &new_type)
Swap old_type with new_type in the PRMClassElement cpt.
static std::string LEFT_CAST()
Enumeration of the different types of objects handled by a PRM.
Definition: PRMObject.h:76
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:58
void setFirst()
Assign the first values to the tuple of the Instantiation.
virtual PRMAttribute< GUM_SCALAR > * getCastDescendant() const
See gum::prm::PRMAttribute.
HashTable< std::string, double > & variables()
Returns the variables used by this gum::Formula.
Definition: formula_inl.h:417
PRMAttribute is a member of a Class in a PRM.
Definition: PRMAttribute.h:59
virtual PRMType< GUM_SCALAR > & type()
See gum::PRMClassElement::type().
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.
static std::string RIGHT_CAST()
Enumeration of the different types of objects handled by a PRM.
Definition: PRMObject.h:77
<agrum/PRM/elements/formAttribute.h>
<agrum/PRM/elements/scalarAttribute.h>
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_tpl.h:198
std::string _safeName
The safe name of this PRMClassElement.
virtual PRMType< GUM_SCALAR > & type()=0
Return a reference over the gum::PRMType of this class element.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:66
ClassElementType
Returns true if obj_ptr is of type PRMReferenceSlot.
virtual GUM_SCALAR get(const Instantiation &i) const
Returns the value pointed by i.
Headers of gum::PRMScalarAttribute.