aGrUM 3.1.1
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 // add a new dimension, needed for updating the offsets_ & gaps_
89
90 template < typename GUM_ELEMENT >
92 Size lg = this->domainSize();
93
94 if (lg > std::numeric_limits< Idx >::max() / v.domainSize()) {
95 GUM_ERROR(OutOfBounds, "Out of bounds !")
96 }
97
99 gaps_.insert(&v, lg);
100 }
101
102 // removes a dimension, needed for updating the offsets_ & gaps_
103
104 template < typename GUM_ELEMENT >
107 Idx pos = variables.pos(&v); // throw a NotFound if necessary
108
109 if (variables.size() == 1) {
110 gaps_.clear();
111 } else {
112 // update the gaps_
113 Size v_size = v.domainSize();
114 gaps_.erase(variables[pos]);
115
116 for (Idx i = pos + 1; i < variables.size(); ++i) {
117 gaps_[variables[i]] /= v_size;
118 }
119 }
120
122 }
123
124 // listen to change in each recorded Instantiation.
125
126 template < typename GUM_ELEMENT >
128 const DiscreteVariable* const var,
129 Idx oldval,
130 Idx newval) {
131 GUM_ASSERT(offsets_.exists(&i));
132 GUM_ASSERT(offsets_[&i] < this->domainSize());
133 GUM_ASSERT(newval < var->domainSize());
134 GUM_ASSERT(oldval < var->domainSize());
135
136 if (newval >= oldval) {
137 offsets_[&i] += gaps_[var] * (newval - oldval);
138 GUM_ASSERT(offsets_[&i] < this->domainSize());
139 } else {
140 GUM_ASSERT(offsets_[&i] >= gaps_[var] * (oldval - newval));
141 offsets_[&i] -= gaps_[var] * (oldval - newval);
142 }
143 }
144
145 // listen to an assignment of a value in a Instantiation
146
147 template < typename GUM_ELEMENT >
149 GUM_ASSERT(offsets_.exists(&i));
150 offsets_[&i] = getOffs_(i);
151 }
152
153 // listen to setFirst in each recorded Instantiation.
154
155 template < typename GUM_ELEMENT >
157 GUM_ASSERT(offsets_.exists(&i));
158 offsets_[&i] = 0;
159 }
160
161 // listen to setLast in each recorded Instantiation.
162
163 template < typename GUM_ELEMENT >
165 GUM_ASSERT(offsets_.exists(&i));
166 offsets_[&i] = this->domainSize() - 1;
167 }
168
169 // listen to increment in each recorded Instantiation.
170
171 template < typename GUM_ELEMENT >
173 GUM_ASSERT(offsets_.exists(&i));
174 GUM_ASSERT(offsets_[&i] != this->domainSize() - 1);
175 ++offsets_[&i];
176 }
177
178 // listen to increment in each recorded Instantiation.
179
180 template < typename GUM_ELEMENT >
182 GUM_ASSERT(offsets_.exists(&i));
183 GUM_ASSERT(offsets_[&i] != 0);
184 --offsets_[&i];
185 }
186
187 // add a Instantiation as a slave
188
189 template < typename GUM_ELEMENT >
192 GUM_ASSERT(!offsets_.exists(&i));
193 offsets_.insert(&i, getOffs_(i));
194 return true;
195 }
196
197 return false;
198 }
199
200 // remove a registered slave instantiation
201
202 template < typename GUM_ELEMENT >
208
209 // Compute the offset of a Instantiation
215
216 template < typename GUM_ELEMENT >
218 Idx off = 0;
219
220 for (auto iter = gaps_.begin(); iter != gaps_.end(); ++iter)
221 if (i.contains(iter.key())) off += iter.val() * i.valFromPtr(iter.key());
222 else
223 GUM_ERROR(InvalidArgument, iter.key()->name() << " not present in the instantiation " << i)
224
225 return off;
226 }
227
228 /* template < typename GUM_ELEMENT >
229 Size MultiDimWithOffset< GUM_ELEMENT >::getOffs_(const Instantiation& i) const {
230 Idx off = 0;
231
232 for (HashTableConstIteratorSafe< const DiscreteVariable*, Size > iter = gaps_.beginSafe();
233 iter != gaps_.endSafe();
234 ++iter)
235 if (i.contains(iter.key()))
236 off += iter.val() * i.valFromPtr(iter.key());
237 else
238 GUM_ERROR(InvalidArgument, iter.key()->name() << " not present in the instantiation " <<
239 i)
240
241 return off;
242 }*/
243
244 // For a given indice of a value in the vector values_, this method computes
245 // the corresponding instantiation
254
255 template < typename GUM_ELEMENT >
257 Size indice) const {
258 for (Idx i = 0; i < this->nbrDim(); ++i) {
259 const DiscreteVariable& var = this->variable(i);
260 Idx domainSize = var.domainSize();
261 result.chgVal(var, indice % domainSize);
262 indice = indice / domainSize;
263 }
264
265 GUM_ASSERT(indice == 0);
266 }
267
268 // string representation of internal data about i in this.
269 template < typename GUM_ELEMENT >
271 if (i->isMaster(this)) {
272 return std::to_string(offsets_[i]);
273 } else {
274 return "--";
275 }
276 }
277
278 template < typename GUM_ELEMENT >
282
283 // set the Instantiation to the values corresponding to the offset (in this
284 // array)
285 template < typename GUM_ELEMENT >
287 Size offset) const {
288 this->computeInstantiationValue_(i, offset);
289 return i;
290 }
291
292} /* 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.
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.
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.
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