aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
partialInstantiationRegister4MultiDim.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 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, const std::string& type_multidim);
118 
119  /**
120  * @brief Indicates whether a given entry exists in the register.
121  *
122  * Indicates if the register contains a function that performs the
123  * instantiation described by \e instantiation_func_name, and that takes in
124  * argument a multiDim of type \e type_multidim.
125  *
126  * @param instantiation_func_name The name of the instantiation performed
127  * by the function we look for.
128  * @param type_multidim The \e real type of the multiDim taken in argument
129  * by the function we look for.
130  * @return Returns true if a given entry exists in the register.
131  */
132  bool exists(const std::string& instantiation_func_name, const std::string& type_multidim) const;
133 
134  /**
135  * @brief Returns the specialized partial instantiation operator assigned
136  * to a given type of MultiDimImplementation.
137  *
138  * @param instantiation_func_name describes the name of the partial
139  * instantiation performed by the function we look for.
140  * @param type_multidim the \e real type of the multiDim taken in argument
141  * by the function we look for
142  * @returns Returns The function, if any, that performs the partial
143  * instantiation
144  * described by \e instantiation_name, and that takes in argument a multiDim
145  * of type \e type_multidim.
146  *
147  * @throws NotFound Raised if the operator we look for does not exist
148  * within this register.
149  */
150  PartialInstantiationPtr get(const std::string& instantiation_func_name,
151  const std::string& type_multidim) const;
152 
153  /// @}
154  // =========================================================================
155  /// @name Named Constructors
156  // =========================================================================
157  /// @{
158 
159  /**
160  * @brief A named constructor that constructs one and only one Register per
161  * data type.
162  *
163  * Note that this constructor prevents the famous init order fiasco.
164  */
165  static PartialInstantiationRegister4MultiDim& Register();
166 
167  /// @}
168 
169  private:
170  // =========================================================================
171  /// @name Constructors / Destructors
172  // =========================================================================
173  /// @{
174 
175  /**
176  * @brief Default constructor: creates an empty register.
177  */
178  PartialInstantiationRegister4MultiDim();
179 
180  /**
181  * @brief Copy operator: never to be used.
182  */
183  PartialInstantiationRegister4MultiDim(const PartialInstantiationRegister4MultiDim&);
184 
185  /**
186  * @brief Class destructor.
187  */
188  ~PartialInstantiationRegister4MultiDim();
189 
190  /// @}
191 
192  /// The set of associations for a given partial instantiation type
193  typedef HashTable< std::string, PartialInstantiationPtr > PartialInstantiationSet;
194 
195  /**
196  * @brief A mapping from the types of MultiDimImplementations to partial
197  * instantiation operators.
198  *
199  * In this type, the strings represent the very types of the
200  * MultiDimImplementations that will be combined. Hence, to a subtype of
201  * MultiDimImplementation is associated a function to partially instantiate
202  * this subtype of hypermatrix (the PartialInstantiationPtr).
203  */
204  HashTable< std::string, PartialInstantiationSet* > _set_;
205  };
206 
207  /// A function to more easily register new instantiation functions in
208  /// MultiDims
209  template < typename GUM_SCALAR >
210  void registerPartialInstantiation(
211  const std::string& instantiation_func_name,
212  const std::string& type_multidim,
213  typename PartialInstantiationRegister4MultiDim< GUM_SCALAR >::PartialInstantiationPtr
214  function);
215 
216 } /* namespace gum */
217 
218 // always include the implementations
219 #include <agrum/tools/multidim/utils/partialInstantiationRegister4MultiDim_tpl.h>
220 
221 #endif /* GUM_PARTIAL_INSTANTIATION_REGISTER_MULTI_DIM_H */