aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
completeProjectionRegister4MultiDim.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 A container for registering complete projection functions on
25  * multiDimImplementations, i.e., projections over all variables
26  *
27  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
28  */
29 
30 #ifndef GUM_COMPLETE_PROJECTION_REGISTER_4_MULTI_DIM_H
31 #define GUM_COMPLETE_PROJECTION_REGISTER_4_MULTI_DIM_H
32 
33 #include <iostream>
34 #include <string>
35 #include <utility>
36 
37 #include <agrum/tools/core/hashTable.h>
38 #include <agrum/tools/core/set.h>
39 #include <agrum/tools/multidim/instantiation.h>
40 #include <agrum/tools/variables/discreteVariable.h>
41 
42 namespace gum {
43 
44  // the base object used by the projections
45  template < typename GUM_SCALAR >
46  class MultiDimImplementation;
47 
48  // ===========================================================================
49  // === GUM_MULTI_DIM_COMPLETE_PROJECTION_REGISTER ===
50  // ===========================================================================
51 
52  // clang-format off
53  /**
54  * @class CompleteProjectionRegister4MultiDim
55  * @headerfile completeProjectionRegister4MultiDim.h agrum/multdim/operators/completeProjectionRegister4MultiDim.h
56  * @ingroup multidim_op_group
57  *
58  * @brief A container for registering complete projection functions on
59  * multiDimImplementations, i.e., functions projecting tables over all their
60  * variables.
61  *
62  */
63  // clang-format on
64  template < typename GUM_SCALAR >
65  class CompleteProjectionRegister4MultiDim {
66  public:
67  /// the type of functions used by the register
68  typedef GUM_SCALAR (*CompleteProjectionPtr)(
69  const MultiDimImplementation< GUM_SCALAR >*,
70  Instantiation* instantiation);
71 
72  // =========================================================================
73  /// @name Accessors / Modifiers
74  // =========================================================================
75  /// @{
76 
77  /**
78  * @brief Adds a new entry into the register.
79  *
80  * This method inserts a new function (\e newFunction) taking a multiDim of
81  * type \e type_multidim (which actually inherit from
82  * MultiDimImplementation) and, possibly, a pointer on an instantiation in
83  * arguments. This new function's purpose is to achieve the projection
84  * described by \e projection_name. For instance, if projection_name is
85  * "max", "min", "sum" or "product", the new function performs the usual
86  * algebraic operations.
87  *
88  * @param projection_name describes the name of the operation performed by
89  * newFunction. Usual operation names are "min", "max", "sum", "product"
90  * @param type_multidim the \e real type of the multiDim taken in argument
91  * by function \e newFunction.
92  *
93  * @param newFunction a pointer to the new function to register. Note that
94  * although \e newFunction actually performs an operation on multiDims of
95  * type \e type_multidim, it should be declared as taking in argument two
96  * MultiDimImplementations. This constraint is imposed by the C++ typing
97  * system.
98  */
99  void insert(const std::string& projection_name,
100  const std::string& type_multidim,
101  CompleteProjectionPtr newFunction);
102 
103  /**
104  * @brief Removes a given entry from the register.
105  *
106  * removes the function, if any, that performs the projection described by
107  * \e projection_name, and that takes in argument a multiDim of type \e
108  * type_multidim
109  *
110  * @param projection_name describes the name of the projection performed by
111  * the function to remove. Usual projection names are "min", "max", "sum",
112  * "product"
113  *
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& projection_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  * projection described by \e projection_name, and that takes in argument a
125  * multiDim of type \e type_multidim.
126  *
127  * @param projection_name describes the name of the projection performed by
128  * the function we look for. Usual projection names are "min", "max",
129  * "sum", "product".
130  *
131  * @param type_multidim the \e real type of the multiDim taken in argument
132  * by the function we look for.
133  */
134  bool exists(const std::string& projection_name,
135  const std::string& type_multidim) const;
136 
137  /**
138  * @brief returns the specialized projection operator assigned to a given
139  * type of MultiDimImplementation
140  *
141  * returns the function, if any, that performs the projection described by
142  * \e projection_name, and that takes in argument a multiDim of type \e
143  * type_multidim
144  *
145  * @param projection_name describes the name of the projection performed by
146  * the function we look for. Usual projection names are "min", "max",
147  * "sum", "product"
148  *
149  * @param type_multidim the \e real type of the multiDim taken in argument
150  * by the function we look for @throws NotFound exception is thrown if the
151  * operator we look for does not exist within this register.
152  */
153  CompleteProjectionPtr get(const std::string& projection_name,
154  const std::string& type_multidim) const;
155 
156  /// @}
157 
158  // =========================================================================
159  /// @name Named Constructors
160  // =========================================================================
161  /// @{
162 
163  /**
164  * @brief A named constructor that constructs one and only one Register per
165  * data type.
166  *
167  * Note that this constructor prevents the famous init order fiasco.
168  */
169  static CompleteProjectionRegister4MultiDim& Register();
170 
171  /// @}
172 
173  private:
174  // =========================================================================
175  /// @name Constructors / Destructors
176  // =========================================================================
177  /// @{
178 
179  /// Default constructor: creates an empty register
180  CompleteProjectionRegister4MultiDim();
181 
182  /// copy operator: never to be used
183  CompleteProjectionRegister4MultiDim(
184  const CompleteProjectionRegister4MultiDim&);
185 
186  /// Destructor
187  ~CompleteProjectionRegister4MultiDim();
188 
189  /// @}
190 
191  /// The set of associations for a given projection type
192  typedef HashTable< std::string, CompleteProjectionPtr > CompleteProjectionSet;
193 
194  /**
195  * @brief A mapping from the types of MultiDimImplementations to
196  * projection operators.
197  *
198  * In this type, the strings represent the very types of the
199  * MultiDimImplementations that will be combined. Hence, to a subtype of
200  * MultiDimImplementation is associated a function to project this subtype
201  * of hypermatrix (the CompleteProjectionPtr)
202  */
203  HashTable< std::string, CompleteProjectionSet* > set__;
204  };
205 
206  /// A function to more easily register new projection functions in MultiDims
207  /// @ingroup multidim_op_group
208  template < typename GUM_SCALAR >
209  void registerCompleteProjection(const std::string& projection_name,
210  const std::string& type_multidim,
211  typename CompleteProjectionRegister4MultiDim<
212  GUM_SCALAR >::CompleteProjectionPtr function);
213 
214 } /* namespace gum */
215 
216 // always include the implementations
217 #include <agrum/tools/multidim/utils/operators/completeProjectionRegister4MultiDim_tpl.h>
218 
219 #endif /* GUM_COMPLETE_PROJECTION_REGISTER_MULTI_DIM_H */