aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
partialInstantiationRegister4MultiDim.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 for PartialInstantiationRegister4MultiDim.
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef GUM_PARTIAL_INSTANTIATION_REGISTER_4_MULTI_DIM_H
30 #define GUM_PARTIAL_INSTANTIATION_REGISTER_4_MULTI_DIM_H
31 
32 #include <agrum/tools/core/hashTable.h>
33 #include <agrum/tools/core/set.h>
34 #include <agrum/tools/variables/discreteVariable.h>
35 #include <iostream>
36 #include <string>
37 #include <utility>
38 
39 namespace gum {
40 
41  // the base object used by the partial instantiations
42  template < typename GUM_SCALAR >
43  class MultiDimImplementation;
44 
45  // ==========================================================================
46  // === GUM_MULTI_DIM_PARTIAL_INSTANTIATION_REGISTER ===
47  // ==========================================================================
48  /**
49  * @class PartialInstantiationRegister4MultiDim
50  * @ingroup multidim_group
51  *
52  * @warning Doxygen does not like spanning command on multiple line, so we
53  * could not configure it with the correct include directive. Use the
54  * following code snippet to include this file.
55  * @code
56  * #include <agrum/tools/multidim/partialInstantiationRegister4MultiDim.h>
57  * @endcode
58  *
59  * @brief A container for registering partial instantiation functions on
60  * multiDimImplementations, i.e., functions assigning values to subsets of
61  * the variables of some tables.
62  *
63  * @tparam GUM_SCALAR The type of scalars stored in the multidimensional
64  * table.
65  */
66  template < typename GUM_SCALAR >
67  class PartialInstantiationRegister4MultiDim {
68  public:
69  /// The type of functions used by the register
70  typedef MultiDimImplementation< GUM_SCALAR >* (*PartialInstantiationPtr)(
71  const MultiDimImplementation< GUM_SCALAR >*,
72  const HashTable< const DiscreteVariable*, Idx >&);
73 
74  // ========================================================================
75  /// @name Accessors / Modifiers
76  // ========================================================================
77  /// @{
78 
79  ///
80  /**
81  * @brief Adds a new entry into the register.
82  *
83  * This method inserts a new function (\e newFunction) taking a multiDim of
84  * type \e type_multidim (which actually inherit from
85  * MultiDimImplementation) and a hashTable assigning to some variables
86  * their values (actually the index of their values) in arguments. This
87  * new function's purpose is to achieve the instantiation of the variables
88  * of the hashtable within the multiDim. As such, it returns the table
89  * without these variables.
90  *
91  * Note that although \e newFunction actually performs an operation on
92  * multiDims of type \e type_multidim, it should be declared as taking in
93  * argument two MultiDimImplementations. This constraint is imposed by the
94  * C++ typing system.
95  *
96  * @param instantiation_func_name The name of the instantiation function.
97  * @param type_multidim The \e real type of the multiDim taken in argument
98  * by function \e newFunction.
99  * @param newFunction A pointer to the new function to register.
100  */
101  void insert(const std::string& instantiation_func_name,
102  const std::string& type_multidim,
103  PartialInstantiationPtr newFunction);
104 
105  /**
106  * @brief Removes a given entry from the register.
107  *
108  * Removes the function, if any, that performs the instantiation described
109  * by \e instantiation_func_name, and that takes in argument a multiDim of
110  * type \e type_multidim.
111  *
112  * @param instantiation_func_name The name of the instantiation performed
113  * by the function to remove.
114  * @param type_multidim The \e real type of the multiDim taken in argument
115  * by the function to remove.
116  */
117  void erase(const std::string& instantiation_func_name,
118  const std::string& type_multidim);
119 
120  /**
121  * @brief Indicates whether a given entry exists in the register.
122  *
123  * Indicates if the register contains a function that performs the
124  * instantiation described by \e instantiation_func_name, and that takes in
125  * argument a multiDim of type \e type_multidim.
126  *
127  * @param instantiation_func_name The name of the instantiation performed
128  * by the function we look for.
129  * @param type_multidim The \e real type of the multiDim taken in argument
130  * by the function we look for.
131  * @return Returns true if a given entry exists in the register.
132  */
133  bool exists(const std::string& instantiation_func_name,
134  const std::string& type_multidim) const;
135 
136  /**
137  * @brief Returns the specialized partial instantiation operator assigned
138  * to a given type of MultiDimImplementation.
139  *
140  * @param instantiation_func_name describes the name of the partial
141  * instantiation performed by the function we look for.
142  * @param type_multidim the \e real type of the multiDim taken in argument
143  * by the function we look for
144  * @returns Returns The function, if any, that performs the partial
145  * instantiation
146  * described by \e instantiation_name, and that takes in argument a multiDim
147  * of type \e type_multidim.
148  *
149  * @throws NotFound Raised if the operator we look for does not exist
150  * within this register.
151  */
152  PartialInstantiationPtr get(const std::string& instantiation_func_name,
153  const std::string& type_multidim) const;
154 
155  /// @}
156  // =========================================================================
157  /// @name Named Constructors
158  // =========================================================================
159  /// @{
160 
161  /**
162  * @brief A named constructor that constructs one and only one Register per
163  * data type.
164  *
165  * Note that this constructor prevents the famous init order fiasco.
166  */
167  static PartialInstantiationRegister4MultiDim& Register();
168 
169  /// @}
170 
171  private:
172  // =========================================================================
173  /// @name Constructors / Destructors
174  // =========================================================================
175  /// @{
176 
177  /**
178  * @brief Default constructor: creates an empty register.
179  */
180  PartialInstantiationRegister4MultiDim();
181 
182  /**
183  * @brief Copy operator: never to be used.
184  */
185  PartialInstantiationRegister4MultiDim(
186  const PartialInstantiationRegister4MultiDim&);
187 
188  /**
189  * @brief Class destructor.
190  */
191  ~PartialInstantiationRegister4MultiDim();
192 
193  /// @}
194 
195  /// The set of associations for a given partial instantiation type
196  typedef HashTable< std::string, PartialInstantiationPtr >
197  PartialInstantiationSet;
198 
199  /**
200  * @brief A mapping from the types of MultiDimImplementations to partial
201  * instantiation operators.
202  *
203  * In this type, the strings represent the very types of the
204  * MultiDimImplementations that will be combined. Hence, to a subtype of
205  * MultiDimImplementation is associated a function to partially instantiate
206  * this subtype of hypermatrix (the PartialInstantiationPtr).
207  */
208  HashTable< std::string, PartialInstantiationSet* > set__;
209  };
210 
211  /// A function to more easily register new instantiation functions in
212  /// MultiDims
213  template < typename GUM_SCALAR >
214  void registerPartialInstantiation(
215  const std::string& instantiation_func_name,
216  const std::string& type_multidim,
217  typename PartialInstantiationRegister4MultiDim<
218  GUM_SCALAR >::PartialInstantiationPtr function);
219 
220 } /* namespace gum */
221 
222 // always include the implementations
223 #include <agrum/tools/multidim/utils/partialInstantiationRegister4MultiDim_tpl.h>
224 
225 #endif /* GUM_PARTIAL_INSTANTIATION_REGISTER_MULTI_DIM_H */