aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
completeProjectionPattern4BaseName.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 the pattern used by all the "basename" projections of multidim tables
25  * over all their variables
26  *
27  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
28  */
29 
30 // check if we allowed these patterns to be used
31 #ifndef GUM_COMPLETE_PROJECTION_PATTERN_ALLOWED
32 
33 // #warning To use completeProjectionPattern, you must define
34 // GUM_COMPLETE_PROJECTION_PATTERN_ALLOWED
35 
36 #else
37 namespace gum {
38 
39  // a specialized function for projecting a multiDimImplementation over a subset
40  // of its variables
41 
42 # ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_NAME
43 # define GUM_MULTI_DIM_COMPLETE_PROJECTION_TYPE GUM_SCALAR
44  template < typename GUM_SCALAR >
45  GUM_SCALAR GUM_MULTI_DIM_COMPLETE_PROJECTION_NAME(
46  const MultiDimImplementation< GUM_SCALAR >* table,
47  Instantiation* instantiation = 0)
48 # endif
49 
50  // clang-format off
51 
52 #ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER_NAME
53 #define GUM_MULTI_DIM_COMPLETE_PROJECTION_TYPE GUM_SCALAR*
54 #define GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
55  template <typename GUM_SCALAR>
56  GUM_SCALAR* GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER_NAME(
57  const MultiDimImplementation<GUM_SCALAR*>* table,
58  Instantiation* instantiation = 0 )
59 #endif
60 
61 #ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_NAME_F
62 #define GUM_MULTI_DIM_COMPLETE_PROJECTION_TYPE GUM_SCALAR
63  template <typename GUM_SCALAR>
64  GUM_SCALAR GUM_MULTI_DIM_COMPLETE_PROJECTION_NAME_F(
65  const MultiDimImplementation<GUM_SCALAR>* table,
66  GUM_SCALAR ( *f )( const GUM_SCALAR&, const GUM_SCALAR& ),
67  Instantiation* instantiation = 0 )
68 #endif
69 
70 #ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER_NAME_F
71 #define GUM_MULTI_DIM_COMPLETE_PROJECTION_TYPE GUM_SCALAR*
72 #define GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
73  template <typename GUM_SCALAR>
74  GUM_SCALAR* GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER_NAME_F(
75  const MultiDimImplementation<GUM_SCALAR*>* table,
76  GUM_SCALAR* ( *f )(const GUM_SCALAR const*,
77  const GUM_SCALAR const*))
78 #endif
79 
80  // clang-format on
81 
82  {
83 
84 # ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER_NAME_F
85  Instantiation* instantiation = 0;
86 # endif // GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER_NAME_F
87 
88  // first, compute the domain size of the table:
89  Size nb_elt = table->domainSize();
90 
91  // now, parse the table and compute the projection. Start with the
92  // neutral element
93  Instantiation table_inst(table);
94  GUM_SCALAR current_val = GUM_MULTI_DIM_COMPLETE_PROJECTION_NEUTRAL;
95 
96  if (instantiation) {
97  GUM_SCALAR old_val = current_val;
98  Size current_ptr = 0;
99 
100  for (Size i = 0; i < nb_elt; ++i, ++table_inst) {
101 # ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
102  GUM_MULTI_DIM_COMPLETE_PROJECTION(&current_val, table->get(table_inst));
103 # else
104  GUM_MULTI_DIM_COMPLETE_PROJECTION(current_val, table->get(table_inst));
105 # endif // GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
106 
107  if (current_val != old_val) {
108  old_val = current_val;
109  current_ptr = i;
110  }
111  }
112 
113  // put the table's variables into the instantiation
114  instantiation->forgetMaster();
115  instantiation->clear();
116  const Sequence< const DiscreteVariable* >& table_vars
117  = table->variablesSequence();
118 
119  for (const auto var: table_vars)
120  instantiation->add(*var);
121 
122  // return the result
123  instantiation->operator+=(current_ptr);
124  return table->get(*instantiation);
125  } else {
126 # ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
127  GUM_SCALAR old_val = current_val;
128  Size current_ptr = 0;
129 
130  for (Size i = 0; i < nb_elt; ++i, ++table_inst) {
131  GUM_MULTI_DIM_COMPLETE_PROJECTION(&current_val, table->get(table_inst));
132 
133  if (current_val != old_val) {
134  old_val = current_val;
135  current_ptr = i;
136  }
137  }
138 
139  table_inst.setFirst();
140  table_inst += current_ptr return table->get(table_inst);
141 # else
142 
143  for (Size i = 0; i < nb_elt; ++i, ++table_inst) {
144  GUM_MULTI_DIM_COMPLETE_PROJECTION(current_val, table->get(table_inst));
145  }
146 
147  return current_val;
148 # endif /* GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER */
149  }
150  }
151 
152 # undef GUM_MULTI_DIM_COMPLETE_PROJECTION_TYPE
153 
154 # ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
155 # undef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
156 # endif
157 
158 } /* End of namespace gum */
159 
160 #endif /* GUM_COMPLETE_PROJECTION_PATTERN_ALLOWED */