aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
multiDimArray_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Implementation of the MultiDimArray class.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  */
28 
29 #include <agrum/tools/multidim/implementations/multiDimArray.h>
30 #include <agrum/tools/multidim/implementations/multiDimWithOffset.h>
31 
32 namespace gum {
33 
34  // Default constructor: creates an empty null dimensional matrix
35  template < typename GUM_SCALAR >
36  MultiDimArray< GUM_SCALAR >::MultiDimArray() :
37  MultiDimWithOffset< GUM_SCALAR >() {
38  // for debugging purposes
39  GUM_CONSTRUCTOR(MultiDimArray);
40  }
41 
42  // copy constructor
43  template < typename GUM_SCALAR >
45  const MultiDimArray< GUM_SCALAR >& src) :
48  // for debugging purposes
50  }
51 
52  // destructor
53  template < typename GUM_SCALAR >
55  // for debugging purposes
57  // no need to unregister all slaves as it will be done by MultiDimWithOffset
58  }
59 
60  template < typename GUM_SCALAR >
62  const MultiDimContainer< GUM_SCALAR >& src) const {
63  auto mda = dynamic_cast< const MultiDimArray< GUM_SCALAR >* >(&src);
64 
65  if (mda == nullptr) {
67  } else {
68  values_ = mda->values_;
69  }
70  }
71 
72  template < typename GUM_SCALAR >
74  std::function< GUM_SCALAR(GUM_SCALAR) > f) const {
76  }
77 
78  template < typename GUM_SCALAR >
81  GUM_SCALAR base) const {
82  return std::accumulate(values_.begin(), values_.end(), base, f);
83  }
84 
85 
86  // data access operator
87  template < typename GUM_SCALAR >
90  if (i.isMaster(this)) {
91  return values_[this->offsets_[&i]];
92  } else {
93  return values_[this->getOffs_(i)];
94  }
95  }
96 
97  // add a new dimension, needed for updating the offsets_ & gaps_
98  template < typename GUM_SCALAR >
102 
103  if (!this->isInMultipleChangeMethod_()) {
105  }
106  }
107 
108  // removes a dimension, needed for updating the offsets_ & gaps_
109  template < typename GUM_SCALAR >
112  Idx pos = variables.pos(&v); // throw a NotFound if necessary
113 
114  if (variables.size() == 1) {
115  if (!this->isInMultipleChangeMethod_()) values_.clear();
116  } else {
117  Size v_size = v.domainSize();
118  Size size = this->domainSize();
119  // here, the variable does belong to the array.
120  // => if pos = variables.size() - 1 then we just have to extract the
121  // beginning of the array (actually the first gap of variable v)
122  // if pos = 0, then copy every element whose index is a multiple of |v|
123  // Assume now that pos != 0 and pos != variables.size() - 1, then
124  // let w be the next variable in the set of variables of the array.
125  // Then we must copy |gap(v)| elements every |gap(w)| elements
126 
127  if (!this->isInMultipleChangeMethod_()) {
128  if (pos != variables.size() - 1) {
129  Size gap_v = this->gaps_[variables[pos]];
130  Size gap_w = this->gaps_[variables[pos + 1]];
131 
132  for (Idx i = 0, j = 0; i < size; i += gap_w) {
133  Idx last = i + gap_v;
134 
135  for (Idx k = i; k < last; ++k, ++j)
136  values_[j] = values_[k];
137  }
138  }
139 
140  // shrink values_
142  }
143  }
144 
146  }
147 
148  template < typename GUM_SCALAR >
150  return this->domainSize();
151  }
152 
153  // synchronise content after MultipleChanges
154  template < typename GUM_SCALAR >
158  }
159  }
160 
161  // synchronise content after MultipleChanges
162  template < typename GUM_SCALAR >
163  INLINE void
167  }
168  }
169 
170  // fill the array with the arg
171  template < typename GUM_SCALAR >
172  INLINE void MultiDimArray< GUM_SCALAR >::fill(const GUM_SCALAR& d) const {
173  if (!this->empty()) std::fill(values_.begin(), values_.end(), d);
174  }
175 
176  // virtual constructor
177  template < typename GUM_SCALAR >
180  return new MultiDimArray< GUM_SCALAR >;
181  }
182 
183  // returns the element stored in the multidimArray at a given offset
184  template < typename GUM_SCALAR >
185  INLINE const GUM_SCALAR&
187  return values_[offset];
188  }
189 
190  template < typename GUM_SCALAR >
192  const GUM_SCALAR& data) {
193  values_[offset] = data;
194  }
195 
196  // returns the element stored in the multidimArray at a given offset
197  template < typename GUM_SCALAR >
198  INLINE const GUM_SCALAR&
200  if (offset >= values_.size()) { GUM_ERROR(OutOfBounds, "offset too large"); }
201 
202  return values_[offset];
203  }
204 
205  template < typename GUM_SCALAR >
207  const GUM_SCALAR& data) {
208  if (offset >= values_.size()) { GUM_ERROR(OutOfBounds, "offset too large"); }
209 
210  values_[offset] = data;
211  }
212 
213  // returns the name of the implementation
214  template < typename GUM_SCALAR >
216  static const std::string str = "MultiDimArray";
217  return str;
218  }
219 
220  template < typename GUM_SCALAR >
222  const DiscreteVariable* y) {
224  }
225 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669