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