aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
multiDimContainer.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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 Headers of the MultiDimContainer class.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  */
28 
29 #ifndef GUM_MULTIDIM_CONTAINER_H
30 #define GUM_MULTIDIM_CONTAINER_H
31 
32 #include <functional>
33 #include <initializer_list>
34 #include <iostream>
35 #include <vector>
36 
37 #include <agrum/agrum.h>
38 #include <agrum/tools/core/math/math_utils.h>
39 
40 #include <agrum/tools/multidim/implementations/multiDimAdressable.h>
41 
42 namespace gum {
43  // needed for content()
44  template < typename GUM_SCALAR >
45  class MultiDimImplementation;
46 
47  // ==========================================================================
48  // === GUM_MULTI_DIM ===
49  // ==========================================================================
50  /**
51  * @class MultiDimContainer
52  * @headerfile multiDimContainer.h <agrum/tools/multidim/multiDimContainer.h>
53  * @ingroup multidim_group
54  *
55  * @brief Abstract base class for all multi dimensionnal containers.
56  *
57  * The MultiDimContainer is an abstract base class for all multi
58  * dimensionnal container of GUM_SCALAR. Its purpose is to deal with
59  * GUM_SCALAR access with no regard to how the storage is done (tree,
60  * matrix...).
61  *
62  * MultiDimContainer is considered as const if its dimension does not change.
63  * Contained values may change even in a const MultiDimContainer :
64  * @code
65  * MultiDimArray<char> t;
66  * LabelizedVariable v( "v" ,"v" , 3);
67  * LabelizedVariable w( "w" ,"w" , 3);
68  * {
69  * t<<v;
70  * Instantiation I( t );I.setFirst();
71  * t[I]='a';
72  * }
73  * {
74  * MultiDimContainer<char>& notconst_t=t;
75  * notconst_t<<w;
76  * Instantiation I( notconst_t );I.setFirst();
77  * notconst_t[I]='b';
78  * }
79  * {
80  * const MultiDimContainer<char>& const_t=t;
81  * Instantiation I( const_t );I.setFirst();
82  * // const_t<<w; : ******************** DOES NOT COMPILE : YOU CANNOT DO THIS
83  * !!!!
84  * const_t[I]='c';
85  * }
86  * @endcode
87  *
88  * @tparam GUM_SCALAR The type of the scalar stored in this multidimensional
89  * matrix.
90  */
91  template < typename GUM_SCALAR >
92  class MultiDimContainer: public MultiDimAdressable {
93  public:
94  // =========================================================================
95  /// @name Constructors / Destructors
96  // =========================================================================
97  /// @{
98 
99  /**
100  * @brief Default constructor.
101  */
102  MultiDimContainer();
103 
104  /**
105  * @brief Copy constructor.
106  * @param src The MultiDimContainer to copy.
107  */
108  MultiDimContainer(const MultiDimContainer< GUM_SCALAR >& src);
109 
110  MultiDimContainer& operator=(const MultiDimContainer< GUM_SCALAR >& src);
111 
112  /**
113  * @brief Class move constructor.
114  */
115  MultiDimContainer(MultiDimContainer< GUM_SCALAR >&&);
116 
117  MultiDimContainer& operator=(MultiDimContainer< GUM_SCALAR >&& src);
118 
119  /**
120  * @brief Destructor.
121  */
122  virtual ~MultiDimContainer();
123 
124  /// @}
125  // =========================================================================
126  /// @name Accessors / Modifiers
127  // =========================================================================
128  /// @{
129  /**
130  * @brief Changes the value pointed by i.
131  *
132  * @warning If i variables set is disjoint with this MultiDimContainer
133  * then 0 is assumed for dimensions (i.e. variables) not prensent in the
134  * instantiation.
135  *
136  * @param i An Instantiation of this MultiDimContainer.
137  * @param value The new value.
138  */
139  virtual void set(const Instantiation& i, const GUM_SCALAR& value) const;
140 
141  /**
142  * @brief Returns the value pointed by i.
143  *
144  * @warning If i variables set is disjoint with this MultiDimContainer
145  * then 0 is assumed for dimensions (i.e. variables) not present in the
146  * instantiation.
147  *
148  * @param i An Instantiation of this MultiDimContainer.
149  * @return Returns the value pointe by i.
150  */
151  virtual GUM_SCALAR get(const Instantiation& i) const;
152 
153  /**
154  * @brief An [] operator using a Instantiation as argument.
155  *
156  * @warning If i variables set is disjoint with this MultiDimContainer
157  * then 0 is assumed for dimensions (i.e. variables) not prensent in the
158  * instantiation.
159  *
160  * @param i An Instantiation.
161  * @return Returns the adressed (GUM_SCALAR) value.
162  */
163  GUM_SCALAR operator[](const Instantiation& i) const;
164 
165  /**
166  * @brief Fill the table with d.
167  * @param d The value used to fill this MultiDimContainer.
168  */
169  virtual void fill(const GUM_SCALAR& d) const = 0;
170 
171  /**
172  * @brief Automatically fills this MultiDimContainer with the values in
173  * v.
174  *
175  * The order used to fill this MultiDimContainer is the same as with an
176  * instantiation over it.
177  * @code
178  * Size cpt = 0;
179  * Instantiation i( *this );
180  * for (i.setFirst(); !i.end(); ++i, ++cpt) {
181  * set(i, v[cpt]);
182  * }
183  * @endcode
184  *
185  * @param v Vector of values.
186  * @throw SizeError Raised if v size's does not matches this
187  * MultiDimContainer domain size.
188  */
189  virtual void populate(const std::vector< GUM_SCALAR >& v) const;
190 
191  /**
192  * @brief Automatically fills this MultiDimContainer with the values in
193  * l.
194  *
195  * The order used to fill this MultiDimContainer is the same as with an
196  * instantiation over it.
197  * @code
198  * Size cpt = 0;
199  * Instantiation i( *this );
200  * for (i.setFirst(); !i.end(); ++i, ++cpt) {
201  * set(i, v[cpt]);
202  * }
203  * @endcode
204  *
205  * @param l contains the data.
206  * @throw SizeError Raised if l size's does not matches this
207  * MultiDimContainer domain size.
208  */
209  virtual void populate(std::initializer_list< GUM_SCALAR > l) const;
210 
211  /// @}
212  // =========================================================================
213  /// @name Copy methods.
214  // =========================================================================
215  /// @{
216 
217  /**
218  * @brief Basic copy of a MultiDimContainer.
219  *
220  * This method is virtual because it should be optimized in certain
221  * MultiDimContainer.
222  *
223  * @param src The MultiDimContainer src which values are copied. This is a
224  * full copy with no verification of dimensions.
225  *
226  * @throw OperationNotAllowed Raised if src does not have the same domain
227  * size than this MultiDimContainer.
228  */
229  virtual void copyFrom(const MultiDimContainer< GUM_SCALAR >& src) const;
230 
231  /**
232  * @brief Basic copy of a MultiDimContainer.
233  *
234  * This method is virtual because it should be optimized in certain
235  * MultiDimContainer.
236  *
237  * @param src The MultiDimContainer src which values are copied.
238  * @param p_i Give the order to iterate in this MultiDimContainer during
239  * the copy (nullptr will correctly copy if this is a reorganization of
240  *src).
241  *
242  * @throw OperationNotAllowed Raised if src does not have the same domain
243  * size than this MultiDimContainer.
244  */
245  virtual void copyFrom(const MultiDimContainer< GUM_SCALAR >& src, Instantiation* p_i) const;
246 
247  /**
248  * @brief Basic extraction of a MultiDimContainer.
249  *
250  * This method is virtual because it should be optimized in certain
251  * MultiDimContainer.
252  *
253  * @param src The MultiDimContainer src which datas are copied.
254  * @param mask partial instantiation of variables of the Potential : the
255  *
256  * extraction will concern every variable not in the instantiation and the
257  * copy of data will use the (relevant) values in this instantiation.
258  */
259  virtual void extractFrom(const MultiDimContainer< GUM_SCALAR >& src, const Instantiation& mask);
260 
261  /**
262  * @brief Returns the implementation for this object (may be *this).
263  */
264  virtual const MultiDimImplementation< GUM_SCALAR >* content() const = 0;
265 
266  /**
267  * @brief Returns the implementation for this object (may be *this).
268  */
269  virtual MultiDimImplementation< GUM_SCALAR >* content() = 0;
270 
271  /**
272  * @brief In order to insure the dereference for decorators, we need to
273  * virtualize the access to master pointer.
274  * @return Returns the ref to content as MultiDimAdressable&
275  */
276  virtual MultiDimAdressable& getMasterRef();
277 
278  /**
279  * @brief In order to insure the dereference for decorators, we need to
280  * virtualize the access to master pointer.
281  * @return Returns the master of this MultiDimAdressable.
282  */
283  virtual const MultiDimAdressable& getMasterRef() const;
284 
285 
286  /**
287  * @brief Removes all variables in this MultiDimContainer and copy the
288  * content of src, variables included.
289  *
290  * @param src The MultiDimContainer to copy.
291  */
292  virtual void copy(const MultiDimContainer< GUM_SCALAR >& src);
293 
294  /**
295  * @brief Creates an empty clone of this MultiDimContainer.
296  *
297  * This method creates a clone of this object, withouth its content
298  * (including variable), you must use this method if you want to ensure
299  * that the generated object has the same type than the object containing
300  * the called newFactory()
301  * For example :
302  * @code
303  * MultiDimArray<double> y;
304  * MultiDimContainer<double>* x = y.newFactory();
305  * @endcode
306  * Then x is a MultiDimArray<double>*.
307  *
308  * @warning You must free by yourself the returned pointer.
309  *
310  * @return Returns an empty clone of this object with the same type.
311  */
312  virtual MultiDimContainer< GUM_SCALAR >* newFactory() const = 0;
313 
314  /// @}
315  // =========================================================================
316  /// @name Various methods.
317  // =========================================================================
318  /// @{
319 
320  /**
321  * @brief Returns a representation of this MultiDimContainer.
322  * @return Returns a representation of this MultiDimContainer.
323  */
324  virtual std::string toString() const;
325 
326  /**
327  * @brief Display the internal representation of i.
328  * @return Returns an internal representation of i.
329  */
330  virtual std::string toString(const Instantiation* i) const = 0;
331 
332  /**
333  * @brief Test if this MultiDimContainer is equal to p.
334  * @param p The MultiDimContainer to test for equality.
335  * @return Returns true if this MultiDimContainer is equal to p.
336  */
337  bool operator==(const MultiDimContainer< GUM_SCALAR >& p) const;
338 
339  /**
340  * @brief Test if this MultiDimContainer is different of p.
341  * @param p The MultiDimContainer to test for inequality.
342  * @return Returns true if this MultiDimContainer is different of p.
343  */
344  bool operator!=(const MultiDimContainer< GUM_SCALAR >& p) const;
345 
346  /**
347  * @brief Apply a function on every element of the container
348  * @param f the function to apply
349  */
350  virtual void apply(std::function< GUM_SCALAR(GUM_SCALAR) > f) const;
351 
352  /**
353  * @brief compute lfold for this container
354  * @param f the function to apply
355  * @param base the initial value
356  */
357  virtual GUM_SCALAR reduce(std::function< GUM_SCALAR(GUM_SCALAR, GUM_SCALAR) > f,
358  GUM_SCALAR base) const;
359 
360 
361  /// @}
362  // =========================================================================
363  /// @name Fast large modifications in structures.
364  // =========================================================================
365  /// @{
366 
367  /**
368  * @brief Call this method before doing important changes in this
369  * MultiDimContainer.
370  *
371  * @warning Remember to call endMultipleChanges() when you finish your
372  * changes.
373  */
374  virtual void beginMultipleChanges() = 0;
375 
376  /**
377  * @brief Call this method after doing important changes in this
378  * MultiDimContainer.
379  */
380  virtual void endMultipleChanges() = 0;
381 
382  /**
383  * @brief Call this method after doing important changes in this
384  * MultiDimContainer.
385  */
386  virtual void endMultipleChanges(const GUM_SCALAR& v) = 0;
387 
388  /// @}
389 
390  protected:
391  /**
392  * @brief Return a data, given a Instantiation.
393  *
394  * Note that get allows to change a value in the container.
395  * The method is tagged as const since a multidim is not const if its dimension
396  * changed.
397  *
398  * @warning If i variables set is disjoint with this MultiDimContainer
399  * then 0 is assumed for dimensions (i.e. variables) not present in the
400  * instantiation.
401  *
402  * @param i The instantiation used to find the data.
403  */
404  virtual GUM_SCALAR& get_(const Instantiation& i) const = 0;
405  };
406 } /* namespace gum */
407 
408 #include <agrum/tools/multidim/implementations/multiDimContainer_tpl.h>
409 
410 #endif /* GUM_MULTIDIM_CONTAINER_H */