aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
PRMScalarAttribute_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
49
50#include <sstream>
51
54
55#include <agrum/PRM/utils_prm.h>
56
57namespace gum {
58 namespace prm {
59
60 template < typename GUM_SCALAR >
62 const std::string& name,
63 const PRMType& type,
65 PRMAttribute< GUM_SCALAR >(name), _type_(new PRMType(type)),
66 _cpf_(new Tensor< GUM_SCALAR >(impl)) {
67 GUM_CONSTRUCTOR(PRMScalarAttribute);
68 _cpf_->add(_type_->variable());
69
71 }
72
73 template < typename GUM_SCALAR >
76 PRMAttribute< GUM_SCALAR >(source), _type_(0), _cpf_(0) {
77 GUM_CONS_CPY(PRMScalarAttribute);
78 GUM_ERROR(FatalError, "Illegal call to the copy constructor of gum::ScalarAttribute")
79 }
80
81 template < typename GUM_SCALAR >
87
88 template < typename GUM_SCALAR >
91 auto impl = static_cast< MultiDimImplementation< GUM_SCALAR >* >(
92 this->cpf().content()->newFactory());
93 return new PRMScalarAttribute< GUM_SCALAR >(this->name(), this->type(), impl);
94 }
95
96 template < typename GUM_SCALAR >
99 auto copy = new PRMScalarAttribute< GUM_SCALAR >(this->name(), this->type());
100
101 if (!bij.existsFirst(&(type().variable()))) {
102 bij.insert(&(type().variable()), &(copy->type().variable()));
103 }
104
105 delete copy->_cpf_;
106 copy->_cpf_ = copyTensor(bij, cpf());
107
108 return copy;
109 }
110
111 template < typename GUM_SCALAR >
114 const PRMAttribute< GUM_SCALAR >& source) {
115 delete _cpf_;
116 _cpf_ = new Tensor< GUM_SCALAR >();
117
118 for (auto var: source.cpf().variablesSequence()) {
119 _cpf_->add(*(bij.second(var)));
120 }
121
122 Instantiation inst(*_cpf_), jnst(source.cpf());
123
124 for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end()); inst.inc(), jnst.inc()) {
125 _cpf_->set(inst, source.cpf().get(jnst));
126 }
127
128 GUM_ASSERT(inst.end() && jnst.end());
129 GUM_ASSERT(_cpf_->contains(_type_->variable()));
130 GUM_ASSERT(!_cpf_->contains(source.type().variable()));
131 }
132
133 template < typename GUM_SCALAR >
136 GUM_ERROR(FatalError, "Illegal call to the copy operator of gum::ScalarAttribute")
137 }
138
139 template < typename GUM_SCALAR >
144
145 template < typename GUM_SCALAR >
149
150 template < typename GUM_SCALAR >
152 return *_type_;
153 }
154
155 template < typename GUM_SCALAR >
156 INLINE const Tensor< GUM_SCALAR >& PRMScalarAttribute< GUM_SCALAR >::cpf() const {
157 return *_cpf_;
158 }
159
160 template < typename GUM_SCALAR >
161 INLINE void
163 try {
164 _cpf_->add(elt.type().variable());
165 } catch (DuplicateElement const&) {
166 GUM_ERROR(DuplicateElement, elt.name() << " as parent of " << this->name())
167 } catch (OperationNotAllowed const&) {
168 GUM_ERROR(OperationNotAllowed, elt.name() << " of wrong type as parent of " << this->name())
169 }
170 }
171
172 // See gum::PRMClassElement<GUM_SCALAR>::addChild_().
173 template < typename GUM_SCALAR >
174 INLINE void
176
177 template < typename GUM_SCALAR >
180
181 try {
182 cast = new PRMScalarAttribute< GUM_SCALAR >(this->name(), type().superType());
183 } catch (NotFound const&) {
184 GUM_ERROR(OperationNotAllowed, "this ScalarAttribute can not have cast descendant")
185 }
186
187 cast->addParent(*this);
188 const DiscreteVariable& my_var = type().variable();
189 DiscreteVariable& cast_var = cast->type().variable();
190 Instantiation inst(cast->cpf());
191
192 for (inst.setFirst(); !inst.end(); inst.inc()) {
193 if (type().label_map()[inst.val(my_var)] == inst.val(cast_var)) {
194 cast->cpf().set(inst, 1);
195 } else {
196 cast->cpf().set(inst, 0);
197 }
198 }
199
200 return cast;
201 }
202
203 template < typename GUM_SCALAR >
205 try {
206 type().setSuper(cast->type());
207 } catch (OperationNotAllowed const&) {
208 GUM_ERROR(OperationNotAllowed, "this ScalarAttribute can not have cast descendant")
209 } catch (TypeError const&) {
210 std::stringstream msg;
211 msg << type().name() << " is not a subtype of " << cast->type().name();
212 GUM_ERROR(TypeError, msg.str())
213 }
214 cast->becomeCastDescendant(type());
215 }
216
217 template < typename GUM_SCALAR >
219 delete _cpf_;
220 _cpf_ = new Tensor< GUM_SCALAR >();
221 _cpf_->add(type().variable());
222 _cpf_->add(subtype.variable());
223
224 Instantiation inst(*_cpf_);
225
226 for (inst.setFirst(); !inst.end(); inst.inc()) {
227 auto my_pos = inst.pos(subtype.variable());
228 if (subtype.label_map()[my_pos] == inst.pos(type().variable())) {
229 _cpf_->set(inst, 1);
230 } else {
231 _cpf_->set(inst, 0);
232 }
233 }
234 }
235
236 template < typename GUM_SCALAR >
237 void PRMScalarAttribute< GUM_SCALAR >::swap(const PRMType& old_type, const PRMType& new_type) {
238 if (&(old_type) == _type_) {
239 GUM_ERROR(OperationNotAllowed, "Cannot replace attribute own type")
240 }
241 if (old_type->domainSize() != new_type->domainSize()) {
242 GUM_ERROR(OperationNotAllowed, "Cannot replace types with difference domain size")
243 }
244 if (!_cpf_->contains(old_type.variable())) {
245 GUM_ERROR(NotFound, "could not find variable " + old_type.name())
246 }
247
248 auto old = _cpf_;
249
250 _cpf_ = new Tensor< GUM_SCALAR >();
251
252 for (auto var: old->variablesSequence()) {
253 if (var != &(old_type.variable())) {
254 _cpf_->add(*var);
255 } else {
256 _cpf_->add(new_type.variable());
257 }
258 }
259
260 Instantiation inst(_cpf_), jnst(old);
261
262 for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end()); inst.inc(), jnst.inc()) {
263 _cpf_->set(inst, old->get(jnst));
264 }
265
266 delete old;
267
268 GUM_ASSERT(inst.end() && jnst.end());
269 GUM_ASSERT(_cpf_->contains(_type_->variable()));
270 GUM_ASSERT(_cpf_->contains(new_type.variable()));
271 GUM_ASSERT(!_cpf_->contains(old_type.variable()));
272 }
273
274 template < typename GUM_SCALAR >
278
279 template < typename GUM_SCALAR >
281 if (_type_->variable().domainSize() != t->variable().domainSize()) {
282 GUM_ERROR(OperationNotAllowed, "Cannot replace types with difference domain size")
283 }
284 auto old = _cpf_;
285
286 _cpf_ = new Tensor< GUM_SCALAR >();
287
288 for (auto var: old->variablesSequence()) {
289 if (var != &(_type_->variable())) {
290 _cpf_->add(*var);
291 } else {
292 _cpf_->add(t->variable());
293 }
294 }
295
296 Instantiation inst(_cpf_), jnst(old);
297
298 for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end()); inst.inc(), jnst.inc()) {
299 _cpf_->set(inst, old->get(jnst));
300 }
301
302 delete old;
303
304 _type_ = t;
305
306 GUM_ASSERT(_cpf_->contains(_type_->variable()));
307 GUM_ASSERT(inst.end() && jnst.end());
308 }
309
310 } /* namespace prm */
311} /* namespace gum */
Headers of gum::PRMAttribute.
Headers of Class.
bool existsFirst(const T1 &first) const
Returns true if first is the first element in a pair in the gum::Bijection.
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
Set of pairs of elements with fast search for both elements.
Definition bijection.h:1594
Base class for discrete random variable.
virtual Size domainSize() const =0
Exception : a similar element already exists.
Exception : fatal (unknown ?) error.
Class for assigning/browsing values to tuples of discrete variables.
bool end() const
Returns true if the Instantiation reached the end.
Idx pos(const DiscreteVariable &v) const final
Returns the position of the variable v.
void inc()
Operator increment.
Idx val(Idx i) const
Returns the current value of the variable at position i.
void setFirst()
Assign the first values to the tuple of the Instantiation.
<agrum/base/multidim/multiDimImplementation.h>
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
aGrUM's Tensor is a multi-dimensional array with tensor operators.
Definition tensor.h:85
Exception : wrong type for this operation.
PRMAttribute is a member of a Class in a PRM.
virtual const Tensor< GUM_SCALAR > & cpf() const =0
See gum::PRMClassElement::cpf().
PRMAttribute(const std::string &name)
Destructor.
virtual PRMType & type()=0
See gum::PRMClassElement::type().
Abstract class representing an element of PRM class.
virtual std::string cast(const PRMType &t) const
Returns the name of the cast descendant with PRMType t of this PRMClassElement.
ClassElementType
Returns true if obj_ptr is of type PRMReferenceSlot.
virtual PRMType & type()=0
Return a reference over the gum::PRMType of this class element.
std::string safeName_
The safe name of this PRMClassElement.
A PRMClass is an object of a PRM representing a fragment of a Bayesian network which can be instantia...
Definition PRMClass.h:75
const std::string & name() const
Returns the name of this object.
static std::string LEFT_CAST()
Enumeration of the different types of objects handled by a PRM.
Definition PRMObject.h:90
static std::string RIGHT_CAST()
Enumeration of the different types of objects handled by a PRM.
Definition PRMObject.h:92
<agrum/PRM/elements/scalarAttribute.h>
virtual void swap(const PRMType &old_type, const PRMType &new_type)
Swap old_type with new_type in the PRMClassElement cpt.
virtual PRMAttribute< GUM_SCALAR > * newFactory(const PRMClass< GUM_SCALAR > &c) const
See gum::PRMClassElement::elt_type().
virtual const Tensor< GUM_SCALAR > & cpf() const
See gum::PRMClassElement::cpf().
PRMType * _type_
The random variable type of this attribute.
Tensor< GUM_SCALAR > * _cpf_
A pointer on the Tensor of this attribute.
virtual PRMClassElement< GUM_SCALAR >::ClassElementType elt_type() const
See gum::PRMClassElement::elt_type().
virtual PRMAttribute< GUM_SCALAR > * copy(Bijection< const DiscreteVariable *, const DiscreteVariable * > bij) const
See gum::PRMClassElement::elt_type().
virtual void becomeCastDescendant(PRMType &subtype)
See gum::PRMClassElement::elt_type().
virtual PRMAttribute< GUM_SCALAR > * getCastDescendant() const
See gum::PRMClassElement::elt_type().
virtual void setAsCastDescendant(PRMAttribute< GUM_SCALAR > *attr)
See gum::PRMClassElement::elt_type().
virtual void addChild(const PRMClassElement< GUM_SCALAR > &elt)
See gum::PRMClassElement::addChild_().
virtual void copyCpf(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bif, const PRMAttribute< GUM_SCALAR > &source)
See gum::PRMClassElement::elt_type().
PRMScalarAttribute(const std::string &name, const PRMType &type, MultiDimImplementation< GUM_SCALAR > *impl=new MultiDimArray< GUM_SCALAR >())
Constructor used by gum::Class.
PRMScalarAttribute & operator=(const PRMScalarAttribute &from)
Copy operator. Don't use it.
virtual PRMType & type()
See gum::PRMClassElement::type().
virtual ~PRMScalarAttribute()
Destructor.
virtual void addParent(const PRMClassElement< GUM_SCALAR > &elt)
See gum::PRMClassElement::addParent_().
This is a decoration of the DiscreteVariable class.
Definition PRMType.h:78
const std::vector< Idx > & label_map() const
Returns the vector in which the i-th element is the Idx of the super type's label for the i-th label ...
Definition PRMType_inl.h:98
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition PRMType_inl.h:64
const std::string & name() const
Returns the name of this object.
Definition PRMType_inl.h:78
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
namespace for all probabilistic relational models entities
Definition agrum.h:68
Tensor< GUM_SCALAR > * copyTensor(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bij, const Tensor< GUM_SCALAR > &source)
Returns a copy of a Tensor after applying a bijection over the variables in source.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46