aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
multiDimArray_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
52
53namespace gum {
54
55 // Default constructor: creates an empty null dimensional matrix
56 template < typename GUM_SCALAR >
58 // for debugging purposes
59 GUM_CONSTRUCTOR(MultiDimArray);
60 }
61
62 // copy constructor
63 template < typename GUM_SCALAR >
65 MultiDimWithOffset< GUM_SCALAR >(src), values_(src.values_) {
66 // for debugging purposes
67 GUM_CONS_CPY(MultiDimArray);
68 }
69
70 // destructor
71 template < typename GUM_SCALAR >
73 // for debugging purposes
74 GUM_DESTRUCTOR(MultiDimArray);
75 // no need to unregister all slaves as it will be done by MultiDimWithOffset
76 }
77
78 template < typename GUM_SCALAR >
80 auto mda = dynamic_cast< const MultiDimArray< GUM_SCALAR >* >(&src);
81
82 if (mda == nullptr) {
84 } else {
85 values_ = mda->values_;
86 }
87 }
88
89 template < typename GUM_SCALAR >
90 void MultiDimArray< GUM_SCALAR >::apply(std::function< GUM_SCALAR(GUM_SCALAR) > f) const {
91 std::transform(values_.begin(), values_.end(), values_.begin(), f);
92 }
93
94 template < typename GUM_SCALAR >
95 GUM_SCALAR
96 MultiDimArray< GUM_SCALAR >::reduce(std::function< GUM_SCALAR(GUM_SCALAR, GUM_SCALAR) > f,
97 GUM_SCALAR base) const {
98 return std::accumulate(values_.begin(), values_.end(), base, f);
99 }
100
101 // data access operator
102 template < typename GUM_SCALAR >
103 INLINE GUM_SCALAR& MultiDimArray< GUM_SCALAR >::get_(const Instantiation& i) const {
104 if (i.isMaster(this)) {
105 return values_[this->offsets_[&i]];
106 } else {
107 return values_[this->getOffs_(i)];
108 }
109 }
110
111 // add a new dimension, needed for updating the offsets_ & gaps_
112 template < typename GUM_SCALAR >
119
120 // removes a dimension, needed for updating the offsets_ & gaps_
121 template < typename GUM_SCALAR >
124 Idx pos = variables.pos(&v); // throw a NotFound if necessary
125
126 if (variables.size() == 1) {
127 if (!this->isInMultipleChangeMethod_()) values_.clear();
128 } else {
129 Size v_size = v.domainSize();
130 Size size = this->domainSize();
131 // here, the variable does belong to the array.
132 // => if pos = variables.size() - 1 then we just have to extract the
133 // beginning of the array (actually the first gap of variable v)
134 // if pos = 0, then copy every element whose index is a multiple of |v|
135 // Assume now that pos != 0 and pos != variables.size() - 1, then
136 // let w be the next variable in the set of variables of the array.
137 // Then we must copy |gap(v)| elements every |gap(w)| elements
138
139 if (!this->isInMultipleChangeMethod_()) {
140 if (pos != variables.size() - 1) {
141 Size gap_v = this->gaps_[variables[pos]];
142 Size gap_w = this->gaps_[variables[pos + 1]];
143
144 for (Idx i = 0, j = 0; i < size; i += gap_w) {
145 Idx last = i + gap_v;
146
147 for (Idx k = i; k < last; ++k, ++j)
148 values_[j] = values_[k];
149 }
150 }
151
152 // shrink values_
153 values_.resize(size / v_size);
154 }
155 }
156
158 }
159
160 template < typename GUM_SCALAR >
162 return this->domainSize();
163 }
164
165 // synchronise content after MultipleChanges
166 template < typename GUM_SCALAR >
172
173 // synchronise content after MultipleChanges
174 template < typename GUM_SCALAR >
180
181 // fill the array with the arg
182 template < typename GUM_SCALAR >
183 INLINE void MultiDimArray< GUM_SCALAR >::fill(const GUM_SCALAR& d) const {
184 if (!this->empty()) std::fill(values_.begin(), values_.end(), d);
185 }
186
187 // virtual constructor
188 template < typename GUM_SCALAR >
192
193 // returns the element stored in the multidimArray at a given offset
194 template < typename GUM_SCALAR >
195 INLINE const GUM_SCALAR& MultiDimArray< GUM_SCALAR >::unsafeGet(Idx offset) const {
196 return values_[offset];
197 }
198
199 template < typename GUM_SCALAR >
200 INLINE void MultiDimArray< GUM_SCALAR >::unsafeSet(Idx offset, const GUM_SCALAR& val) {
201 values_[offset] = val;
202 }
203
204 // returns the element stored in the multidimArray at a given offset
205 template < typename GUM_SCALAR >
206 INLINE const GUM_SCALAR& MultiDimArray< GUM_SCALAR >::getByOffset(Idx offset) const {
207 if (offset >= values_.size()) { GUM_ERROR(OutOfBounds, "offset too large") }
208
209 return values_[offset];
210 }
211
212 template < typename GUM_SCALAR >
213 INLINE void MultiDimArray< GUM_SCALAR >::setByOffset(Idx offset, const GUM_SCALAR& data) {
214 if (offset >= values_.size()) { GUM_ERROR(OutOfBounds, "offset too large") }
215
216 values_[offset] = data;
217 }
218
219 // returns the name of the implementation
220 template < typename GUM_SCALAR >
221 const std::string& MultiDimArray< GUM_SCALAR >::name() const {
222 // Here, this initialization is thread-safe due to Meyer’s Singleton property
223 static const std::string str("MultiDimArray");
224 return str;
225 }
226
227 template < typename GUM_SCALAR >
232} /* namespace gum */
Base class for discrete random variable.
virtual Size domainSize() const =0
Class for assigning/browsing values to tuples of discrete variables.
bool isMaster(const MultiDimAdressable *m) const
Indicates whether m is the master of this instantiation.
const GUM_SCALAR & getByOffset(Idx offset) const
Returns the element stored in the multidimArray at a given offset.
virtual void erase(const DiscreteVariable &v)
Removes a variable.
void commitMultipleChanges_() final
Synchronize content after MultipleChanges.
const GUM_SCALAR & unsafeGet(Idx offset) const
Returns the element stored in the multidimArray at a given offset.
virtual void copyFrom(const MultiDimContainer< GUM_SCALAR > &src) const
Copy from a other MultiDimContainer.
virtual ~MultiDimArray()
Copy operator.
virtual void apply(std::function< GUM_SCALAR(GUM_SCALAR) > f) const
Apply a function on every element of the container.
std::vector< GUM_SCALAR > values_
The true data : the values is mutable since we can change the value / in a const multiDimArray.
void setByOffset(Idx offset, const GUM_SCALAR &val)
Modifies the element stored in the multidimArray at a given offset.
virtual void fill(const GUM_SCALAR &d) const
Fills the MultiDimArray with the given value.
virtual GUM_SCALAR reduce(std::function< GUM_SCALAR(GUM_SCALAR, GUM_SCALAR) > f, GUM_SCALAR base) const
compute lfold for this container
MultiDimArray()
Default constructor.
virtual Size realSize() const
Returns the real size of this MultiDimArray.
void replace_(const DiscreteVariable *x, const DiscreteVariable *y) final
Replace variable x by y.
GUM_SCALAR & get_(const Instantiation &i) const final
Return a data, given a Instantiation.
virtual const std::string & name() const
Returns the MultiDimArray name.
void unsafeSet(Idx offset, const GUM_SCALAR &val)
Modifies the element stored in the multidimArray at a given offset.
virtual void add(const DiscreteVariable &v)
Adds a variable.
virtual MultiDimContainer< GUM_SCALAR > * newFactory() const
Default constructor.
Abstract base class for all multi dimensionnal containers.
virtual void copyFrom(const MultiDimContainer< GUM_SCALAR > &src) const
Basic copy of a MultiDimContainer.
virtual bool empty() const override
Returns true if no var is in *this.
virtual Size domainSize() const override
Returns the product of the variables domain size.
virtual void replace_(const DiscreteVariable *x, const DiscreteVariable *y) override
Replace variable x by y.
virtual const Sequence< const DiscreteVariable * > & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
virtual Idx pos(const DiscreteVariable &v) const override
Returns the index of a variable.
bool isInMultipleChangeMethod_() const
Get the actual change method of this MultiDimImplementation.
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.
MultiDimWithOffset()
Class constructor.
Size getOffs_(const Instantiation &i) const
Compute the offset of a Instantiation.
virtual void add(const DiscreteVariable &v)
Adds a new var to the variables of the multidimensional matrix.
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
Header of the MultiDimArray class.
Headers of the MultiDimWithOffset class.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46