aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
scheduleMultiDim.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 /** @file
23  * @brief a MultiDimImplementation Wrapper used for scheduling inferences
24  *
25  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 #ifndef GUM_SCHEDULE_MULTI_DIM_H
28 #define GUM_SCHEDULE_MULTI_DIM_H
29 
30 #include <string>
31 
32 #include <agrum/agrum.h>
33 
34 #include <agrum/tools/core/hashTable.h>
35 #include <agrum/tools/core/sequence.h>
36 #include <agrum/tools/multidim/implementations/multiDimDecorator.h>
37 #include <agrum/tools/multidim/implementations/multiDimImplementation.h>
38 #include <agrum/tools/variables/discreteVariable.h>
39 
40 namespace gum {
41 
42 #ifndef DOXYGEN_SHOULD_SKIP_THIS
43  // we should grant ScheduleDeleteMultiDim the access to the hashtable actually
44  // containing the MultiDimImplementation: thus, when ScheduleDeleteMultiDim
45  // deletes an implementation, it can remove it from the hashtable and, thus,
46  // the ScheduleMultiDims pointing to it will become abstract.
47  template < typename GUM_SCALAR >
49 #endif
50 
51  /**
52  * @class ScheduleMultiDim
53  * @brief a MultiDimImplementation Wrapper used for scheduling inferences
54  *
55  * A ScheduleMultiDim is a wrapper that contains either a "real" multidim
56  * table or an Id that indicates that the multidim table that should be
57  * contained has not been computed yet (by the scheduler). This Id enables
58  * the scheduler to know which is the operation the result of which will be
59  *the
60  * multidim table that will eventually be contained in the ScheduleMultiDim.
61  * Here is a brief piece of code that should highlight the concept:
62  * @code
63  * // some arbitrary potentials (to be initialized before going on)
64  * gum::Potential<float> pot1, pot2, pot3;
65  *
66  * // we wish to schedule ( pot1 + pot2 ) + pot3
67  * // so, first, create ScheduleMultiDims for wrapping these potentials
68  * gum::ScheduleMultiDim<float> f1 ( pot1 ), f2 ( pot2 ), f3 ( pot3 );
69  *
70  * // now schedule a combination (+) between f1 and f2
71  * gum::ScheduleCombine<float> comb1 ( &f1, &f2, add );
72  *
73  * // get the result and schedule it with f3
74  * const ScheduleMultiDim<float>& result1 = comb1.result ();
75  * gum::ScheduleCombine<float> comb2 ( &result2, &f3,add );
76  *
77  * // get the resulting ScheduleMultiDim
78  * const ScheduleMultiDim<float>& result2 = comb2.result ();
79  *
80  * // here, no addition has been performed yet. We just have a structure
81  * // that indicates which operations we wish to do. So, for the moment,
82  * // result1 and result2 do not contain real multidim tables but just ids.
83  * // As such, they are called abstract and trying to get their "real"
84  * // multiDim table (using method multiDim()) would throw a NotFound
85  *exception.
86  * std::cout << result1.isAbstract ();
87  * std::cout << result2.isAbstract ();
88  * std::cout << ! f1.isAbstract ();
89  *
90  * // now, we can actually perform the operations
91  * comb1.execute ();
92  * std::cout << ! result1.isAbstract ();
93  * comb2.execute ();
94  *
95  * // here, we can display the content of the real multidim table stored
96  * // into result2
97  * std::cout << result2.multiDim ();
98  * @endcode
99  *
100  * So, to summarize the key idea underlying Schedule* classes: these classes
101  * encapsulate operations to perform and multidim tables that should be passed
102  * as argument to these operations. But nothing is actually computed until
103  * the execute() methods of the scheduled operations are executed.
104  */
105  template < typename GUM_SCALAR >
107  public:
108  // ############################################################################
109  /// @name Constructors / Destructors
110  // ############################################################################
111  /// @{
112 
113  /// constructs a ScheduleMultiDim containing an already built implementation
115 
116  /// constructs a ScheduleMultiDim containing an already built implementation
117  explicit ScheduleMultiDim(const MultiDimDecorator< GUM_SCALAR >&);
118 
119  /// construct a ScheduleMultiDim for an implementation yet to be built
120  /** The ScheduleMultiDim created is abstract, i.e., it does not contain a
121  * proper MultiDimImplementation yet. However, the variables of the latter
122  * need be known to optimize inference processes
123  * @warning the sequence of variables is copied into the wrapper. */
124  explicit ScheduleMultiDim(const Sequence< const DiscreteVariable* >& vars);
125 
126  /// copy constructor
127  ScheduleMultiDim(const ScheduleMultiDim< GUM_SCALAR >&);
128 
129  /// destructor
130  ~ScheduleMultiDim();
131 
132  /// @}
133 
134  // ############################################################################
135  /// @name Operators
136  // ############################################################################
137 
138  /// @{
139 
140  /// copy operator
141  ScheduleMultiDim< GUM_SCALAR >& operator=(const ScheduleMultiDim< GUM_SCALAR >&);
142 
143  /// checks whether two ScheduleMultiDim are related to the same table
144  bool operator==(const ScheduleMultiDim< GUM_SCALAR >&) const;
145 
146  /// checks whether two ScheduleMultiDim are related to different tables
147  bool operator!=(const ScheduleMultiDim< GUM_SCALAR >&) const;
148 
149  /// @}
150 
151  // ############################################################################
152  /// @name Accessors/Modifiers
153  // ############################################################################
154  /// @{
155 
156  /// returns whether the ScheduleMultiDim contains a real
157  /// multiDimImplementation
158  /** @returns true if the ScheduleMultiDim is abstract, i.e., it is does not
159  * actually contains a real MultiDimImplementation but rather a ID
160  * indicating
161  * that the real multiDimImplementation is yet to be created as a result of
162  * an
163  * operation on other multiDimImplementations. */
164  bool isAbstract() const;
165 
166  /** @brief returns the multiDimImplementation actually contained in the
167  * ScheduleMultiDim
168  *
169  * @throws NotFound exception is thrown if the multidimImplementation does
170  *not
171  * exist yet (because it has not been computed yet) */
172  const MultiDimImplementation< GUM_SCALAR >& multiDim() const;
173 
174  /// returns the id of the ScheduleMultiDim
175  Idx id() const;
176 
177  /// returns the set of variables involved in the multidim
178  const Sequence< const DiscreteVariable* >& variablesSequence() const;
179 
180  /// returns the domain size of the multidim
181  Size domainSize() const;
182 
183  /// sets a new multiDimImplementation inside the wrapper
184  /** @throws DuplicateElement exception is thrown if the
185  * MultiDimImplementation
186  * has already been wrapped in a ScheduleMultiDim with another id */
188 
189  /// sets a new multiDimDecorator inside the wrapper
190  /** @throws DuplicateElement exception is thrown if the MultiDimDecorator
191  * has already been wrapped in a ScheduleMultiDim with another id */
192  void setMultiDim(const MultiDimDecorator< GUM_SCALAR >&);
193 
194  /// displays the content of the multidim
195  std::string toString() const;
196 
197  /// @}
198 
199  private:
200  /// grant accesses to ScheduleDeleteMultiDim
201  friend class ScheduleDeleteMultiDim< GUM_SCALAR >;
202 
203  /// the unique Id of the ScheduleMultiDim
205 
206  /// returns a new distinct ID for each abtract scheduleMultiDim
207  static Idx _newId_();
208 
209  /// returns a mapping from id to multidimImplementations
211 
212  /// returns the id corresponding to a given multidim
213  /** useful to assign the same id every time a given MultiDimImplementation
214  * is wrapped into a ScheduleMultiDim */
216 
217  /// returns a table indicating how many ScheduleMultiDim have the same id
218  static HashTable< Idx, Idx >& _id2refs_();
219 
220  /// returns a table with the variables of the table corresponding to id
221  static HashTable< Idx, const Sequence< const DiscreteVariable* >* >& _id2vars_();
222 
223  /// returns a table with the domain size of the table corresponding to id
224  static HashTable< Idx, Size >& _id2size_();
225  };
226 
227 } /* namespace gum */
228 
229 // always include the template implementation
230 #include <agrum/tools/graphicalModels/inference/scheduler/scheduleMultiDim_tpl.h>
231 
232 #endif /* GUM_SCHEDULE_MULTI_DIM_H */
const Sequence< const DiscreteVariable *> & variablesSequence() const
returns the set of variables involved in the multidim
std::string toString() const
displays the content of the multidim
bool isAbstract() const
returns whether the ScheduleMultiDim contains a real multiDimImplementation
static HashTable< Idx, Idx > & _id2refs_()
returns a table indicating how many ScheduleMultiDim have the same id
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
Idx id() const
returns the id of the ScheduleMultiDim
ScheduleMultiDim(const ScheduleMultiDim< GUM_SCALAR > &)
copy constructor
Size domainSize() const
returns the domain size of the multidim
static HashTable< const MultiDimImplementation< GUM_SCALAR > *, Idx > & _multidim2id_()
returns the id corresponding to a given multidim
bool operator!=(const ScheduleMultiDim< GUM_SCALAR > &) const
checks whether two ScheduleMultiDim are related to different tables
ScheduleMultiDim< GUM_SCALAR > & operator=(const ScheduleMultiDim< GUM_SCALAR > &)
copy operator
Idx _id_
the unique Id of the ScheduleMultiDim
static HashTable< Idx, Size > & _id2size_()
returns a table with the domain size of the table corresponding to id
static Idx _newId_()
returns a new distinct ID for each abtract scheduleMultiDim
~ScheduleMultiDim()
destructor
void setMultiDim(const MultiDimDecorator< GUM_SCALAR > &)
sets a new multiDimDecorator inside the wrapper
const MultiDimImplementation< GUM_SCALAR > & multiDim() const
returns the multiDimImplementation actually contained in the ScheduleMultiDim
ScheduleMultiDim(const Sequence< const DiscreteVariable * > &vars)
construct a ScheduleMultiDim for an implementation yet to be built
static HashTable< Idx, const Sequence< const DiscreteVariable *> *> & _id2vars_()
returns a table with the variables of the table corresponding to id
bool operator==(const ScheduleMultiDim< GUM_SCALAR > &) const
checks whether two ScheduleMultiDim are related to the same table