aGrUM 3.1.1
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-2026 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-2026 *
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
41#pragma once
42
43
50
52#include <agrum/PRM/elements/PRMScalarAttribute.h> // to ease IDE parser
54
55#include <agrum/PRM/utils_prm.h>
56
57namespace gum {
58 namespace prm {
59
60 template < GUM_Numeric GUM_SCALAR >
62 std::string_view 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
70 this->safeName_
71 = (PRMObject::LEFT_CAST() + _type_->name() + PRMObject::RIGHT_CAST()).append(name);
72 }
73
74 template < GUM_Numeric GUM_SCALAR >
77 PRMAttribute< GUM_SCALAR >(source), _type_(0), _cpf_(0) {
78 GUM_CONS_CPY(PRMScalarAttribute);
79 GUM_ERROR(FatalError, "Illegal call to the copy constructor of gum::ScalarAttribute")
80 }
81
82 template < GUM_Numeric GUM_SCALAR >
88
89 template < GUM_Numeric GUM_SCALAR >
92 auto impl = static_cast< MultiDimImplementation< GUM_SCALAR >* >(
93 this->cpf().content()->newFactory());
94 return new PRMScalarAttribute< GUM_SCALAR >(this->name(), this->type(), impl);
95 }
96
97 template < GUM_Numeric GUM_SCALAR >
100 auto copy = new PRMScalarAttribute< GUM_SCALAR >(this->name(), this->type());
101
102 if (!bij.existsFirst(&(type().variable()))) {
103 bij.insert(&(type().variable()), &(copy->type().variable()));
104 }
105
106 delete copy->_cpf_;
107 copy->_cpf_ = copyTensor(bij, cpf());
108
109 return copy;
110 }
111
112 template < GUM_Numeric GUM_SCALAR >
115 const PRMAttribute< GUM_SCALAR >& source) {
116 delete _cpf_;
117 _cpf_ = new Tensor< GUM_SCALAR >();
118
119 for (auto var: source.cpf().variablesSequence()) {
120 _cpf_->add(*(bij.second(var)));
121 }
122
123 Instantiation inst(*_cpf_), jnst(source.cpf());
124
125 for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end()); inst.inc(), jnst.inc()) {
126 _cpf_->set(inst, source.cpf().get(jnst));
127 }
128
129 GUM_ASSERT(inst.end() && jnst.end());
130 GUM_ASSERT(_cpf_->contains(_type_->variable()));
131 GUM_ASSERT(!_cpf_->contains(source.type().variable()));
132 }
133
134 template < GUM_Numeric GUM_SCALAR >
137 GUM_ERROR(FatalError, "Illegal call to the copy operator of gum::ScalarAttribute")
138 }
139
140 template < GUM_Numeric GUM_SCALAR >
145
146 template < GUM_Numeric GUM_SCALAR >
150
151 template < GUM_Numeric GUM_SCALAR >
153 return *_type_;
154 }
155
156 template < GUM_Numeric GUM_SCALAR >
157 const Tensor< GUM_SCALAR >& PRMScalarAttribute< GUM_SCALAR >::cpf() const {
158 return *_cpf_;
159 }
160
161 template < GUM_Numeric GUM_SCALAR >
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 < GUM_Numeric GUM_SCALAR >
175
176 template < GUM_Numeric GUM_SCALAR >
178 if (!type().isSubType()) {
179 GUM_ERROR(OperationNotAllowed, "this ScalarAttribute can not have cast descendant")
180 }
181 auto cast = new PRMScalarAttribute< GUM_SCALAR >(this->name(), type().superType());
182
183 cast->addParent(*this);
184 const DiscreteVariable& my_var = type().variable();
185 DiscreteVariable& cast_var = cast->type().variable();
186 Instantiation inst(cast->cpf());
187
188 for (inst.setFirst(); !inst.end(); inst.inc()) {
189 if (type().label_map()[inst.val(my_var)] == inst.val(cast_var)) {
190 cast->cpf().set(inst, 1);
191 } else {
192 cast->cpf().set(inst, 0);
193 }
194 }
195
196 return cast;
197 }
198
199 template < GUM_Numeric GUM_SCALAR >
201 try {
202 type().setSuper(cast->type());
203 } catch (OperationNotAllowed const&) {
204 GUM_ERROR(OperationNotAllowed, "this ScalarAttribute can not have cast descendant")
205 } catch (TypeError const&) {
207 std::format("{} is not a subtype of {}", type().name(), cast->type().name()))
208 }
209 cast->becomeCastDescendant(type());
210 }
211
212 template < GUM_Numeric GUM_SCALAR >
214 delete _cpf_;
215 _cpf_ = new Tensor< GUM_SCALAR >();
216 _cpf_->add(type().variable());
217 _cpf_->add(subtype.variable());
218
219 Instantiation inst(*_cpf_);
220
221 for (inst.setFirst(); !inst.end(); inst.inc()) {
222 auto my_pos = inst.pos(subtype.variable());
223 if (subtype.label_map()[my_pos] == inst.pos(type().variable())) {
224 _cpf_->set(inst, 1);
225 } else {
226 _cpf_->set(inst, 0);
227 }
228 }
229 }
230
231 template < GUM_Numeric GUM_SCALAR >
232 void PRMScalarAttribute< GUM_SCALAR >::swap(const PRMType& old_type, const PRMType& new_type) {
233 if (&(old_type) == _type_) {
234 GUM_ERROR(OperationNotAllowed, "Cannot replace attribute own type")
235 }
236 if (old_type->domainSize() != new_type->domainSize()) {
237 GUM_ERROR(OperationNotAllowed, "Cannot replace types with difference domain size")
238 }
239 if (!_cpf_->contains(old_type.variable())) {
240 GUM_ERROR(NotFound, "could not find variable " + old_type.name())
241 }
242
243 auto old = _cpf_;
244
245 _cpf_ = new Tensor< GUM_SCALAR >();
246
247 for (auto var: old->variablesSequence()) {
248 if (var != &(old_type.variable())) {
249 _cpf_->add(*var);
250 } else {
251 _cpf_->add(new_type.variable());
252 }
253 }
254
255 Instantiation inst(_cpf_), jnst(old);
256
257 for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end()); inst.inc(), jnst.inc()) {
258 _cpf_->set(inst, old->get(jnst));
259 }
260
261 delete old;
262
263 GUM_ASSERT(inst.end() && jnst.end());
264 GUM_ASSERT(_cpf_->contains(_type_->variable()));
265 GUM_ASSERT(_cpf_->contains(new_type.variable()));
266 GUM_ASSERT(!_cpf_->contains(old_type.variable()));
267 }
268
269 template < GUM_Numeric GUM_SCALAR >
273
274 template < GUM_Numeric GUM_SCALAR >
276 if (_type_->variable().domainSize() != t->variable().domainSize()) {
277 GUM_ERROR(OperationNotAllowed, "Cannot replace types with difference domain size")
278 }
279 auto old = _cpf_;
280
281 _cpf_ = new Tensor< GUM_SCALAR >();
282
283 for (auto var: old->variablesSequence()) {
284 if (var != &(_type_->variable())) {
285 _cpf_->add(*var);
286 } else {
287 _cpf_->add(t->variable());
288 }
289 }
290
291 Instantiation inst(_cpf_), jnst(old);
292
293 for (inst.setFirst(), jnst.setFirst(); !(inst.end() || jnst.end()); inst.inc(), jnst.inc()) {
294 _cpf_->set(inst, old->get(jnst));
295 }
296
297 delete old;
298
299 _type_ = t;
300
301 GUM_ASSERT(_cpf_->contains(_type_->variable()));
302 GUM_ASSERT(inst.end() && jnst.end());
303 }
304
305 } /* namespace prm */
306} /* namespace gum */
Headers of gum::PRMAttribute.
Headers of gum::PRMScalarAttribute.
Headers of Class.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
bool existsFirst(const T1 &first) const
Returns true if first is the first element in a pair in the gum::Bijection.
Set of pairs of elements with fast search for both elements.
Definition bijection.h:1640
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.
void inc()
Operator increment.
Idx pos(const DiscreteVariable &v) const final
Returns the position of the variable v.
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.
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.
PRMAttribute(std::string_view name)
Destructor.
const Tensor< GUM_SCALAR > & cpf() const override=0
See gum::PRMClassElement::cpf().
PRMType & type() override=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:77
const std::string & name() const
Returns the name of this object.
static std::string RIGHT_CAST()
Enumeration of the different types of objects handled by a PRM.
static std::string LEFT_CAST()
Enumeration of the different types of objects handled by a PRM.
<agrum/PRM/elements/scalarAttribute.h>
void swap(const PRMType &old_type, const PRMType &new_type) override
Swap old_type with new_type in the PRMClassElement cpt.
~PRMScalarAttribute() override
Destructor.
void addParent(const PRMClassElement< GUM_SCALAR > &elt) override
See gum::PRMClassElement::addParent_().
void copyCpf(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bif, const PRMAttribute< GUM_SCALAR > &source) override
See gum::PRMClassElement::elt_type().
PRMType * _type_
The random variable type of this attribute.
Tensor< GUM_SCALAR > * _cpf_
A pointer on the Tensor of this attribute.
void addChild(const PRMClassElement< GUM_SCALAR > &elt) override
See gum::PRMClassElement::addChild_().
PRMType & type() override
See gum::PRMClassElement::type().
void becomeCastDescendant(PRMType &subtype) override
See gum::PRMClassElement::elt_type().
const Tensor< GUM_SCALAR > & cpf() const override
See gum::PRMClassElement::cpf().
void setAsCastDescendant(PRMAttribute< GUM_SCALAR > *attr) override
See gum::PRMClassElement::elt_type().
PRMClassElement< GUM_SCALAR >::ClassElementType elt_type() const override
See gum::PRMClassElement::elt_type().
PRMAttribute< GUM_SCALAR > * getCastDescendant() const override
See gum::PRMClassElement::elt_type().
PRMAttribute< GUM_SCALAR > * newFactory(const PRMClass< GUM_SCALAR > &c) const override
See gum::PRMClassElement::elt_type().
PRMScalarAttribute & operator=(const PRMScalarAttribute &from)
Copy operator. Don't use it.
PRMScalarAttribute(std::string_view name, const PRMType &type, MultiDimImplementation< GUM_SCALAR > *impl=new MultiDimArray< GUM_SCALAR >())
Constructor used by gum::Class.
PRMAttribute< GUM_SCALAR > * copy(Bijection< const DiscreteVariable *, const DiscreteVariable * > bij) const override
See gum::PRMClassElement::elt_type().
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:65
const std::string & name() const
Returns the name of this object.
Definition PRMType_inl.h:79
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
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