aGrUM 3.2.0
a C++ library for (probabilistic) graphical models
multiDimWithOffset_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
51#include <limits>
52
53// to ease IDE parsers...
56
57namespace gum {
58
59 // Default constructor: creates an empty null dimensional matrix
60
61 template < typename GUM_ELEMENT >
63 MultiDimImplementation< GUM_ELEMENT >() {
64 // for debugging purposes
65 GUM_CONSTRUCTOR(MultiDimWithOffset);
66 }
67
68 // copy constructor
69
70 template < typename GUM_ELEMENT >
73 MultiDimImplementation< GUM_ELEMENT >(from), gaps_(from.gaps_) {
74 // for debugging purposes
75 GUM_CONS_CPY(MultiDimWithOffset);
76 }
77
78 // destructor
79
80 template < typename GUM_ELEMENT >
82 // for debugging purposes
83 GUM_DESTRUCTOR(MultiDimWithOffset);
84 // no need to unregister all slaves as it will be done by
85 // MultiDimImplementation
86 }
87
88 // copy operator
89
90 template < typename GUM_ELEMENT >
93 // for debugging purposes
94 GUM_OP_CPY(MultiDimWithOffset);
96 gaps_ = from.gaps_;
97 return *this;
98 }
99
100 // add a new dimension, needed for updating the offsets_ & gaps_
101
102 template < typename GUM_ELEMENT >
104 Size lg = this->domainSize();
105
106 if (lg > std::numeric_limits< Idx >::max() / v.domainSize()) {
107 GUM_ERROR(OutOfBounds, "Out of bounds !")
108 }
109
111 gaps_.insert(&v, lg);
112 }
113
114 // removes a dimension, needed for updating the offsets_ & gaps_
115
116 template < typename GUM_ELEMENT >
119 Idx pos = variables.pos(&v); // throw a NotFound if necessary
120
121 if (variables.size() == 1) {
122 gaps_.clear();
123 } else {
124 // update the gaps_
125 Size v_size = v.domainSize();
126 gaps_.erase(variables[pos]);
127
128 for (Idx i = pos + 1; i < variables.size(); ++i) {
129 gaps_[variables[i]] /= v_size;
130 }
131 }
132
134 }
135
136 // listen to change in each recorded Instantiation.
137
138 template < typename GUM_ELEMENT >
140 const DiscreteVariable* const var,
141 Idx oldval,
142 Idx newval) {
143 GUM_ASSERT(offsets_.exists(&i));
144 GUM_ASSERT(offsets_[&i] < this->domainSize());
145 GUM_ASSERT(newval < var->domainSize());
146 GUM_ASSERT(oldval < var->domainSize());
147
148 if (newval >= oldval) {
149 offsets_[&i] += gaps_[var] * (newval - oldval);
150 GUM_ASSERT(offsets_[&i] < this->domainSize());
151 } else {
152 GUM_ASSERT(offsets_[&i] >= gaps_[var] * (oldval - newval));
153 offsets_[&i] -= gaps_[var] * (oldval - newval);
154 }
155 }
156
157 // listen to an assignment of a value in a Instantiation
158
159 template < typename GUM_ELEMENT >
161 GUM_ASSERT(offsets_.exists(&i));
162 offsets_[&i] = getOffs_(i);
163 }
164
165 // listen to setFirst in each recorded Instantiation.
166
167 template < typename GUM_ELEMENT >
169 GUM_ASSERT(offsets_.exists(&i));
170 offsets_[&i] = 0;
171 }
172
173 // listen to setLast in each recorded Instantiation.
174
175 template < typename GUM_ELEMENT >
177 GUM_ASSERT(offsets_.exists(&i));
178 offsets_[&i] = this->domainSize() - 1;
179 }
180
181 // listen to increment in each recorded Instantiation.
182
183 template < typename GUM_ELEMENT >
185 GUM_ASSERT(offsets_.exists(&i));
186 GUM_ASSERT(offsets_[&i] != this->domainSize() - 1);
187 ++offsets_[&i];
188 }
189
190 // listen to increment in each recorded Instantiation.
191
192 template < typename GUM_ELEMENT >
194 GUM_ASSERT(offsets_.exists(&i));
195 GUM_ASSERT(offsets_[&i] != 0);
196 --offsets_[&i];
197 }
198
199 // add a Instantiation as a slave
200
201 template < typename GUM_ELEMENT >
204 GUM_ASSERT(!offsets_.exists(&i));
205 offsets_.insert(&i, getOffs_(i));
206 return true;
207 }
208
209 return false;
210 }
211
212 // remove a registered slave instantiation
213
214 template < typename GUM_ELEMENT >
220
221 // Compute the offset of a Instantiation
227
228 template < typename GUM_ELEMENT >
230 Idx off = 0;
231
232 for (auto iter = gaps_.begin(); iter != gaps_.end(); ++iter)
233 if (i.contains(iter.key())) off += iter.val() * i.valFromPtr(iter.key());
234 else
235 GUM_ERROR(InvalidArgument, iter.key()->name() << " not present in the instantiation " << i)
236
237 return off;
238 }
239
240 /* template < typename GUM_ELEMENT >
241 Size MultiDimWithOffset< GUM_ELEMENT >::getOffs_(const Instantiation& i) const {
242 Idx off = 0;
243
244 for (HashTableConstIteratorSafe< const DiscreteVariable*, Size > iter = gaps_.beginSafe();
245 iter != gaps_.endSafe();
246 ++iter)
247 if (i.contains(iter.key()))
248 off += iter.val() * i.valFromPtr(iter.key());
249 else
250 GUM_ERROR(InvalidArgument, iter.key()->name() << " not present in the instantiation " <<
251 i)
252
253 return off;
254 }*/
255
256 // For a given indice of a value in the vector values_, this method computes
257 // the corresponding instantiation
266
267 template < typename GUM_ELEMENT >
269 Size indice) const {
270 for (Idx i = 0; i < this->nbrDim(); ++i) {
271 const DiscreteVariable& var = this->variable(i);
272 Idx domainSize = var.domainSize();
273 result.chgVal(var, indice % domainSize);
274 indice = indice / domainSize;
275 }
276
277 GUM_ASSERT(indice == 0);
278 }
279
280 // string representation of internal data about i in this.
281 template < typename GUM_ELEMENT >
283 if (i->isMaster(this)) {
284 return std::to_string(offsets_[i]);
285 } else {
286 return "--";
287 }
288 }
289
290 template < typename GUM_ELEMENT >
294
295 // set the Instantiation to the values corresponding to the offset (in this
296 // array)
297 template < typename GUM_ELEMENT >
299 Size offset) const {
300 this->computeInstantiationValue_(i, offset);
301 return i;
302 }
303
304} /* namespace gum */
Base class for discrete random variable.
virtual Size domainSize() const =0
Class for assigning/browsing values to tuples of discrete variables.
Instantiation & chgVal(const DiscreteVariable &v, Idx newval)
Assign newval to variable v in the Instantiation.
bool isMaster(const MultiDimAdressable *m) const
Indicates whether m is the master of this instantiation.
bool contains(const DiscreteVariable &v) const final
Indicates whether a given variable belongs to the Instantiation.
Idx valFromPtr(const DiscreteVariable *pvar) const
Returns the current value of a given variable.
Exception: at least one argument passed to a function is not what was expected.
MultiDimAdressable & operator=(const MultiDimAdressable &from)
Default constructor.
virtual std::string toString() const
Returns a representation of this MultiDimContainer.
Idx pos(const DiscreteVariable &v) const override
Returns the index of a variable.
void erase(const DiscreteVariable &v) override
Removes a var from the variables of the multidimensional matrix.
Size domainSize() const override
Returns the product of the variables domain size.
const Sequence< const DiscreteVariable * > & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
void add(const DiscreteVariable &v) override
Adds a new var to the variables of the multidimensional matrix.
const DiscreteVariable & variable(Idx i) const override
Returns a const ref to the ith var.
MultiDimImplementation()
Default constructor.
bool registerSlave(Instantiation &slave) override
Register i as a slave of this MultiDimAdressable.
bool unregisterSlave(Instantiation &slave) override
Unregister i as a slave of this MultiDimAdressable.
Idx nbrDim() const override
Returns the number of vars in the multidimensional container.
Abstract class for Multidimensional matrix stored as an array in memory and with an offset associated...
Size getOffs_(const Instantiation &i) const
Compute the offset of a Instantiation.
void erase(const DiscreteVariable &v) override
Removes a var from the variables of the multidimensional matrix.
~MultiDimWithOffset() override
Class destrucor.
void setFirstNotification(const Instantiation &i) override
Listen to setFirst in a given Instantiation.
MultiDimWithOffset()
Class constructor.
void setLastNotification(const Instantiation &i) override
Listen to setLast in a given Instantiation.
bool registerSlave(Instantiation &i) override
Register i as a slave of this MultiDimAdressable.
void setIncNotification(const Instantiation &i) override
Listen to increment in a given Instantiation.
HashTable< const DiscreteVariable *, Size > gaps_
The gaps between consecutive values of a given variable.
void setDecNotification(const Instantiation &i) override
Listen to increment in each recorded Instantiation.
void setChangeNotification(const Instantiation &i) override
Listen to an assignment of a value in a Instantiation.
MultiDimWithOffset< GUM_ELEMENT > & operator=(const MultiDimWithOffset< GUM_ELEMENT > &from)
Copy operator.
bool unregisterSlave(Instantiation &i) override
Unregister i as a slave of this MultiDimAdressable.
void changeNotification(const Instantiation &i, const DiscreteVariable *const var, Idx oldval, Idx newval) override
Listen to changes in a given Instantiation.
HashTable< const Instantiation *, Size > offsets_
The position in the array of each slave Instantiation.
Size toOffset(const Instantiation &i) const
Compute offset from an Instantiation (in this array).
void computeInstantiationValue_(Instantiation &result, Size indice) const
For a given index of a value in the vector values, this method computes the corresponding instantiati...
void add(const DiscreteVariable &v) override
Adds a new var to the variables of the multidimensional matrix.
Instantiation & fromOffset(Instantiation &i, Size offset) const
Set the Instantiation to the values corresponding to the offset (in this array).
Exception : out of bound.
Idx pos(const Key &key) const
Returns the position of the object passed in argument (if it exists).
Size size() const noexcept
Returns the size of the sequence.
The generic class for storing (ordered) sequences of objects.
Definition sequence.h:994
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size Idx
Type for indexes.
Definition types.h:79
Headers of gum::MultiDimImplementation.
Headers of the MultiDimWithOffset class.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46