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