aGrUM 2.3.2
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-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 <limits>
51
52// to ease IDE parsers...
55
56namespace gum {
57
58 // Default constructor: creates an empty null dimensional matrix
59
60 template < typename GUM_SCALAR >
62 // for debugging purposes
63 GUM_CONSTRUCTOR(MultiDimWithOffset);
64 }
65
66 // copy constructor
67
68 template < typename GUM_SCALAR >
71 MultiDimImplementation< GUM_SCALAR >(from), gaps_(from.gaps_) {
72 // for debugging purposes
73 GUM_CONS_CPY(MultiDimWithOffset);
74 }
75
76 // destructor
77
78 template < typename GUM_SCALAR >
80 // for debugging purposes
81 GUM_DESTRUCTOR(MultiDimWithOffset);
82 // no need to unregister all slaves as it will be done by
83 // MultiDimImplementation
84 }
85
86 // add a new dimension, needed for updating the offsets_ & gaps_
87
88 template < typename GUM_SCALAR >
90 Size lg = this->domainSize();
91
92 if (lg > std::numeric_limits< Idx >::max() / v.domainSize()) {
93 GUM_ERROR(OutOfBounds, "Out of bounds !")
94 }
95
97 gaps_.insert(&v, lg);
98 }
99
100 // removes a dimension, needed for updating the offsets_ & gaps_
101
102 template < typename GUM_SCALAR >
105 Idx pos = variables.pos(&v); // throw a NotFound if necessary
106
107 if (variables.size() == 1) {
108 gaps_.clear();
109 } else {
110 // update the gaps_
111 Size v_size = v.domainSize();
112 gaps_.erase(variables[pos]);
113
114 for (Idx i = pos + 1; i < variables.size(); ++i) {
115 gaps_[variables[i]] /= v_size;
116 }
117 }
118
120 }
121
122 // listen to change in each recorded Instantiation.
123
124 template < typename GUM_SCALAR >
125 INLINE void
127 const DiscreteVariable* const var,
128 Idx oldval,
129 Idx newval) {
130 GUM_ASSERT(offsets_.exists(&i));
131 GUM_ASSERT(offsets_[&i] < this->domainSize());
132 GUM_ASSERT(newval < var->domainSize());
133 GUM_ASSERT(oldval < var->domainSize());
134
135 if (newval >= oldval) {
136 offsets_[&i] += gaps_[var] * (newval - oldval);
137 GUM_ASSERT(offsets_[&i] < this->domainSize());
138 } else {
139 GUM_ASSERT(offsets_[&i] >= gaps_[var] * (oldval - newval));
140 offsets_[&i] -= gaps_[var] * (oldval - newval);
141 }
142 }
143
144 // listen to an assignment of a value in a Instantiation
145
146 template < typename GUM_SCALAR >
148 GUM_ASSERT(offsets_.exists(&i));
149 offsets_[&i] = getOffs_(i);
150 }
151
152 // listen to setFirst in each recorded Instantiation.
153
154 template < typename GUM_SCALAR >
156 GUM_ASSERT(offsets_.exists(&i));
157 offsets_[&i] = 0;
158 }
159
160 // listen to setLast in each recorded Instantiation.
161
162 template < typename GUM_SCALAR >
164 GUM_ASSERT(offsets_.exists(&i));
165 offsets_[&i] = this->domainSize() - 1;
166 }
167
168 // listen to increment in each recorded Instantiation.
169
170 template < typename GUM_SCALAR >
172 GUM_ASSERT(offsets_.exists(&i));
173 GUM_ASSERT(offsets_[&i] != this->domainSize() - 1);
174 ++offsets_[&i];
175 }
176
177 // listen to increment in each recorded Instantiation.
178
179 template < typename GUM_SCALAR >
181 GUM_ASSERT(offsets_.exists(&i));
182 GUM_ASSERT(offsets_[&i] != 0);
183 --offsets_[&i];
184 }
185
186 // add a Instantiation as a slave
187
188 template < typename GUM_SCALAR >
191 GUM_ASSERT(!offsets_.exists(&i));
192 offsets_.insert(&i, getOffs_(i));
193 return true;
194 }
195
196 return false;
197 }
198
199 // remove a registered slave instantiation
200
201 template < typename GUM_SCALAR >
207
208 // Compute the offset of a Instantiation
215
216 template < typename GUM_SCALAR >
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_SCALAR >
229 INLINE Size MultiDimWithOffset< GUM_SCALAR >::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_SCALAR >
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_SCALAR >
271 if (i->isMaster(this)) {
272 std::stringstream s;
273 s << offsets_[i];
274 std::string res;
275 s >> res;
276 return res;
277 } else {
278 return "--";
279 }
280 }
281
282 template < typename GUM_SCALAR >
284 return getOffs_(i);
285 }
286
287 // set the Instantiation to the values corresponding to the offset (in this
288 // array)
289 template < typename GUM_SCALAR >
291 Size offset) const {
292 this->computeInstantiationValue_(i, offset);
293 return i;
294 }
295
296} /* 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.
MultiDimImplementation()
Default constructor.
virtual Idx nbrDim() const override
Returns the number of vars in the multidimensional container.
virtual void add(const DiscreteVariable &v) override
Adds a new var to the variables of the multidimensional matrix.
virtual Size domainSize() const override
Returns the product of the variables domain size.
virtual const Sequence< const DiscreteVariable * > & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
virtual void erase(const DiscreteVariable &v) override
Removes a var from the variables of the multidimensional matrix.
virtual bool registerSlave(Instantiation &slave) override
Register i as a slave of this MultiDimAdressable.
const DiscreteVariable & variable(Idx i) const override
Returns a const ref to the ith var.
virtual bool unregisterSlave(Instantiation &slave) override
Unregister i as a slave of this MultiDimAdressable.
virtual Idx pos(const DiscreteVariable &v) const override
Returns the index of a variable.
HashTable< const Instantiation *, Size > offsets_
The position in the array of each slave Instantiation.
virtual void erase(const DiscreteVariable &v)
Removes a var from the variables of the multidimensional matrix.
HashTable< const DiscreteVariable *, Size > gaps_
The gaps between consecutive values of a given variable.
void setIncNotification(const Instantiation &i)
Listen to increment in a given Instantiation.
virtual void setChangeNotification(const Instantiation &i)
Listen to an assignment of a value in a Instantiation.
void setDecNotification(const Instantiation &i)
Listen to increment in each recorded Instantiation.
virtual void setLastNotification(const Instantiation &i)
Listen to setLast in a given Instantiation.
virtual bool unregisterSlave(Instantiation &i)
Unregister i as a slave of this MultiDimAdressable.
virtual void changeNotification(const Instantiation &i, const DiscreteVariable *const var, Idx oldval, Idx newval)
Listen to changes in a given Instantiation.
MultiDimWithOffset()
Class constructor.
Size getOffs_(const Instantiation &i) const
Compute the offset of a Instantiation.
void computeInstantiationValue_(Instantiation &result, Size indice) const
For a given index of a value in the vector values, this method computes the corresponding instantiati...
virtual void add(const DiscreteVariable &v)
Adds a new var to the variables of the multidimensional matrix.
virtual void setFirstNotification(const Instantiation &i)
Listen to setFirst in a given Instantiation.
virtual bool registerSlave(Instantiation &i)
Register i as a slave of this MultiDimAdressable.
Instantiation & fromOffset(Instantiation &i, Size offset) const
Set the Instantiation to the values corresponding to the offset (in this array).
Size toOffset(const Instantiation &i) const
Compute offset from an Instantiation (in this array).
virtual ~MultiDimWithOffset()
Class destrucor.
Exception : out of bound.
Size size() const noexcept
Returns the size of the sequence.
Idx pos(const Key &key) const
Returns the position of the object passed in argument (if it exists).
The generic class for storing (ordered) sequences of objects.
Definition sequence.h:972
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
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