aGrUM  0.14.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& type,
45  PRMAttribute< GUM_SCALAR >(name),
46  __type(new PRMType(type)), __cpf(0), __formulas(impl), __class(&c) {
47  GUM_CONSTRUCTOR(PRMFormAttribute);
48  __formulas->add(__type->variable());
49  this->_safeName =
51  }
52 
53  template < typename GUM_SCALAR >
55  GUM_DESTRUCTOR(PRMFormAttribute);
56  delete __type;
57  delete __cpf;
58  delete __formulas;
59  }
60 
61  template < typename GUM_SCALAR >
63  const PRMClass< GUM_SCALAR >& c) const {
64  auto impl = static_cast< MultiDimImplementation< std::string >* >(
65  this->__formulas->newFactory());
67  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< GUM_SCALAR >* >(&source)) {
101  const auto& src =
102  static_cast< const PRMFormAttribute< GUM_SCALAR >& >(source);
103 
104  Instantiation inst(__formulas), jnst(src.__formulas);
105 
106  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
107  inst.inc(), jnst.inc()) {
108  __formulas->set(inst, src.__formulas->get(jnst));
109  }
110 
111  GUM_ASSERT(inst.end() && jnst.end());
112 
113  } else {
114  Instantiation inst(__formulas), jnst(source.cpf());
115 
116  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
117  inst.inc(), jnst.inc()) {
118  auto val = std::to_string(source.cpf().get(jnst));
119  __formulas->set(inst, val);
120  }
121 
122  GUM_ASSERT(inst.end() && jnst.end());
123  }
124 
125  if (__cpf) {
126  delete __cpf;
127  __cpf = 0;
128  }
129 
130  GUM_ASSERT(__formulas->contains(__type->variable()));
131  GUM_ASSERT(!__formulas->contains(source.type().variable()));
132  }
133 
134  template < typename GUM_SCALAR >
137  return this->prm_attribute;
138  }
139 
140  template < typename GUM_SCALAR >
142  return *__type;
143  }
144 
145  template < typename GUM_SCALAR >
147  return *__type;
148  }
149 
150  template < typename GUM_SCALAR >
152  if (__cpf == 0) { __fillCpf(); }
153  return *__cpf;
154  }
155 
156  template < typename GUM_SCALAR >
158  const PRMClassElement< GUM_SCALAR >& elt) {
159  try {
160  if (__cpf) {
161  delete __cpf;
162  __cpf = 0;
163  }
164  __formulas->add(elt.type().variable());
165  } catch (DuplicateElement&) {
167  elt.name() << " as parent of " << this->name());
168  } catch (OperationNotAllowed&) {
170  elt.name() << " of wrong type as parent of " << this->name(););
171  }
172 
173  GUM_ASSERT(__formulas->contains(__type->variable()));
174  }
175 
176  template < typename GUM_SCALAR >
178  const PRMClassElement< GUM_SCALAR >& elt) {}
179 
180  template < typename GUM_SCALAR >
184 
185  try {
186  cast =
188  } catch (NotFound&) {
190  "this ScalarAttribute can not have cast descendant");
191  }
192 
193  cast->addParent(*this);
194 
195  const DiscreteVariable& my_var = type().variable();
196  DiscreteVariable& cast_var = cast->type().variable();
197  Instantiation inst(cast->cpf());
198 
199  for (inst.setFirst(); !inst.end(); inst.inc()) {
200  if (type().label_map()[inst.val(my_var)] == inst.val(cast_var)) {
201  cast->cpf().set(inst, 1);
202  } else {
203  cast->cpf().set(inst, 0);
204  }
205  }
206 
207  GUM_ASSERT(__formulas->contains(__type->variable()));
208  return cast;
209  }
210 
211  template < typename GUM_SCALAR >
214  try {
215  type().setSuper(cast->type());
216  } catch (OperationNotAllowed&) {
218  "this ScalarAttribute can not have cast descendant");
219  } catch (WrongType&) {
220  std::stringstream msg;
221  msg << type().name() << " is not a subtype of " << cast->type().name();
222  GUM_ERROR(WrongType, msg.str());
223  }
224 
225  cast->becomeCastDescendant(type());
226  }
227 
228  template < typename GUM_SCALAR >
230  delete __formulas;
231 
233  __formulas->add(type().variable());
234  __formulas->add(subtype.variable());
235 
237 
238  for (inst.setFirst(); !inst.end(); inst.inc()) {
239  auto my_pos = inst.pos(subtype.variable());
240  if (subtype.label_map()[my_pos] == inst.pos(type().variable())) {
241  __formulas->set(inst, "1");
242  } else {
243  __formulas->set(inst, "0");
244  }
245  }
246 
247  if (__cpf) {
248  delete __cpf;
249  __cpf = nullptr;
250  }
251  }
252 
253  template < typename GUM_SCALAR >
255  const PRMFormAttribute& source) :
256  PRMAttribute< GUM_SCALAR >(source.name()) {
257  GUM_CONS_CPY(PRMFormAttribute);
258  GUM_ERROR(OperationNotAllowed, "Cannot copy FormAttribute");
259  }
260 
261  template < typename GUM_SCALAR >
264  GUM_ERROR(OperationNotAllowed, "Cannot copy FormAttribute");
265  }
266 
267  template < typename GUM_SCALAR >
269  try {
270  if (__cpf) { delete __cpf; }
271 
273 
274  for (auto var : __formulas->variablesSequence()) {
275  __cpf->add(*var);
276  }
277 
278  auto params = __class->scope();
279 
281  Instantiation jnst(__cpf);
282 
283  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
284  inst.inc(), jnst.inc()) {
285  // With CPT defined using rules, empty values can appear
286  auto val = __formulas->get(inst);
287  if (val == "") { val = "0.0"; }
288 
289  Formula f(val);
290 
291  for (auto item : params) {
292  f.variables().insert(item.first, item.second->value());
293  }
294 
295  __cpf->set(jnst, (GUM_SCALAR)f.result());
296  }
297 
298  GUM_ASSERT(inst.end() && jnst.end());
299 
300  } catch (Exception&) { GUM_ERROR(NotFound, "undefined value in cpt"); }
301  GUM_ASSERT(__formulas->contains(__type->variable()));
302  }
303 
304  template < typename GUM_SCALAR >
307  if (__cpf) {
308  delete __cpf;
309  __cpf = 0;
310  }
311  return *__formulas;
312  }
313 
314  template < typename GUM_SCALAR >
317  return *__formulas;
318  }
319 
320  template < typename GUM_SCALAR >
322  const PRMType& new_type) {
323  if (&(old_type) == __type) {
324  GUM_ERROR(OperationNotAllowed, "Cannot replace attribute own type");
325  }
326  if (old_type->domainSize() != new_type->domainSize()) {
328  "Cannot replace types with difference domain size");
329  }
330  if (!__formulas->contains(old_type.variable())) {
331  GUM_ERROR(NotFound, "could not find variable " + old_type.name());
332  }
333 
334  auto old = __formulas;
335 
337 
338  for (auto var : old->variablesSequence()) {
339  if (var != &(old_type.variable())) {
340  __formulas->add(*var);
341  } else {
342  __formulas->add(new_type.variable());
343  }
344  }
345 
346  Instantiation inst(__formulas), jnst(old);
347 
348  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
349  inst.inc(), jnst.inc()) {
350  __formulas->set(inst, old->get(jnst));
351  }
352 
353  delete old;
354 
355  if (__cpf) {
356  delete __cpf;
357  __cpf = 0;
358  }
359 
360  GUM_ASSERT(inst.end() && jnst.end());
361  GUM_ASSERT(__formulas->contains(__type->variable()));
362  GUM_ASSERT(!__formulas->contains(new_type.variable()));
363  GUM_ASSERT(__formulas->contains(new_type.variable()));
364  }
365 
366  template < typename GUM_SCALAR >
368  return __type;
369  }
370 
371  template < typename GUM_SCALAR >
373  if (__type->variable().domainSize() != t->variable().domainSize()) {
375  "Cannot replace types with difference domain size");
376  }
377  auto old = __formulas;
378 
380 
381  for (auto var : old->variablesSequence()) {
382  if (var != &(__type->variable())) {
383  __formulas->add(*var);
384  } else {
385  __formulas->add(t->variable());
386  }
387  }
388 
389  Instantiation inst(__formulas), jnst(old);
390 
391  for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end());
392  inst.inc(), jnst.inc()) {
393  __formulas->set(inst, old->get(jnst));
394  }
395 
396  delete old;
397 
398  __type = t;
399 
400  if (__cpf) {
401  delete __cpf;
402  __cpf = 0;
403  }
404 
405  GUM_ASSERT(__formulas->contains(__type->variable()));
406  GUM_ASSERT(inst.end() && jnst.end());
407  }
408 
409  } /* namespace prm */
410 } /* 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:295
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.
const std::string & name() const
Returns the name of this object.
Definition: PRMType_inl.h:65
PRMType & superType()
Returns the super type of this type.
Definition: PRMType_inl.h:33
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:77
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition: PRMType_inl.h:42
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:32
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:271
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()
Headers files for the gum::FormulaPart and gum::Formula classes.
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.
gum is the global namespace for all aGrUM entities
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:479
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: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: PRMType.h:60
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.
Headers of gum::PRMFormAttribute.
Headers of Class.
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:80
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:63
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:91
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:417
PRMAttribute is a member of a Class in a PRM.
Definition: PRMAttribute.h:58
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:77
<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:52
bool end() const
Returns true if the Instantiation reached the end.
ClassElementType
Returns true if obj_ptr is of type PRMReferenceSlot.
Headers of gum::PRMScalarAttribute.