aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
multiDimContainer.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 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,
246  Instantiation* p_i) const;
247 
248  /**
249  * @brief Basic extraction of a MultiDimContainer.
250  *
251  * This method is virtual because it should be optimized in certain
252  * MultiDimContainer.
253  *
254  * @param src The MultiDimContainer src which datas are copied.
255  * @param mask partial instantiation of variables of the Potential : the
256  *
257  * extraction will concern every variable not in the instantiation and the
258  * copy of data will use the (relevant) values in this instantiation.
259  */
260  virtual void extractFrom(const MultiDimContainer< GUM_SCALAR >& src,
261  const Instantiation& mask);
262 
263  /**
264  * @brief Returns the implementation for this object (may be *this).
265  */
266  virtual const MultiDimImplementation< GUM_SCALAR >* content() const = 0;
267 
268  /**
269  * @brief Returns the implementation for this object (may be *this).
270  */
271  virtual MultiDimImplementation< GUM_SCALAR >* content() = 0;
272 
273  /**
274  * @brief In order to insure the dereference for decorators, we need to
275  * virtualize the access to master pointer.
276  * @return Returns the ref to content as MultiDimAdressable&
277  */
278  virtual MultiDimAdressable& getMasterRef();
279 
280  /**
281  * @brief In order to insure the dereference for decorators, we need to
282  * virtualize the access to master pointer.
283  * @return Returns the master of this MultiDimAdressable.
284  */
285  virtual const MultiDimAdressable& getMasterRef() const;
286 
287 
288  /**
289  * @brief Removes all variables in this MultiDimContainer and copy the
290  * content of src, variables included.
291  *
292  * @param src The MultiDimContainer to copy.
293  */
294  virtual void copy(const MultiDimContainer< GUM_SCALAR >& src);
295 
296  /**
297  * @brief Creates an empty clone of this MultiDimContainer.
298  *
299  * This method creates a clone of this object, withouth its content
300  * (including variable), you must use this method if you want to ensure
301  * that the generated object has the same type than the object containing
302  * the called newFactory()
303  * For example :
304  * @code
305  * MultiDimArray<double> y;
306  * MultiDimContainer<double>* x = y.newFactory();
307  * @endcode
308  * Then x is a MultiDimArray<double>*.
309  *
310  * @warning You must free by yourself the returned pointer.
311  *
312  * @return Returns an empty clone of this object with the same type.
313  */
314  virtual MultiDimContainer< GUM_SCALAR >* newFactory() const = 0;
315 
316  /// @}
317  // =========================================================================
318  /// @name Various methods.
319  // =========================================================================
320  /// @{
321 
322  /**
323  * @brief Returns a representation of this MultiDimContainer.
324  * @return Returns a representation of this MultiDimContainer.
325  */
326  virtual std::string toString() const;
327 
328  /**
329  * @brief Display the internal representation of i.
330  * @return Returns an internal representation of i.
331  */
332  virtual std::string toString(const Instantiation* i) const = 0;
333 
334  /**
335  * @brief Test if this MultiDimContainer is equal to p.
336  * @param p The MultiDimContainer to test for equality.
337  * @return Returns true if this MultiDimContainer is equal to p.
338  */
339  bool operator==(const MultiDimContainer< GUM_SCALAR >& p) const;
340 
341  /**
342  * @brief Test if this MultiDimContainer is different of p.
343  * @param p The MultiDimContainer to test for inequality.
344  * @return Returns true if this MultiDimContainer is different of p.
345  */
346  bool operator!=(const MultiDimContainer< GUM_SCALAR >& p) const;
347 
348  /**
349  * @brief Apply a function on every element of the container
350  * @param f the function to apply
351  */
352  virtual void apply(std::function< GUM_SCALAR(GUM_SCALAR) > f) const;
353 
354  /**
355  * @brief compute lfold for this container
356  * @param f the function to apply
357  * @param base the initial value
358  */
359  virtual GUM_SCALAR
360  reduce(std::function< GUM_SCALAR(GUM_SCALAR, GUM_SCALAR) > f,
361  GUM_SCALAR base) const;
362 
363 
364  /// @}
365  // =========================================================================
366  /// @name Fast large modifications in structures.
367  // =========================================================================
368  /// @{
369 
370  /**
371  * @brief Call this method before doing important changes in this
372  * MultiDimContainer.
373  *
374  * @warning Remember to call endMultipleChanges() when you finish your
375  * changes.
376  */
377  virtual void beginMultipleChanges() = 0;
378 
379  /**
380  * @brief Call this method after doing important changes in this
381  * MultiDimContainer.
382  */
383  virtual void endMultipleChanges() = 0;
384 
385  /**
386  * @brief Call this method after doing important changes in this
387  * MultiDimContainer.
388  */
389  virtual void endMultipleChanges(const GUM_SCALAR& v) = 0;
390 
391  /// @}
392 
393  protected:
394  /**
395  * @brief Return a data, given a Instantiation.
396  *
397  * Note that get allows to change a value in the container.
398  * The method is tagged as const since a multidim is not const if its dimension
399  * changed.
400  *
401  * @warning If i variables set is disjoint with this MultiDimContainer
402  * then 0 is assumed for dimensions (i.e. variables) not present in the
403  * instantiation.
404  *
405  * @param i The instantiation used to find the data.
406  */
407  virtual GUM_SCALAR& get_(const Instantiation& i) const = 0;
408  };
409 } /* namespace gum */
410 
411 #include <agrum/tools/multidim/implementations/multiDimContainer_tpl.h>
412 
413 #endif /* GUM_MULTIDIM_CONTAINER_H */