aGrUM  0.21.0
a C++ library for (probabilistic) graphical models
completeProjectionPattern4BaseName.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 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
46  GUM_MULTI_DIM_COMPLETE_PROJECTION_NAME(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 = table->variablesSequence();
117 
118  for (const auto var: table_vars)
119  instantiation->add(*var);
120 
121  // return the result
122  instantiation->operator+=(current_ptr);
123  return table->get(*instantiation);
124  } else {
125 # ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
126  GUM_SCALAR old_val = current_val;
127  Size current_ptr = 0;
128 
129  for (Size i = 0; i < nb_elt; ++i, ++table_inst) {
130  GUM_MULTI_DIM_COMPLETE_PROJECTION(&current_val, table->get(table_inst));
131 
132  if (current_val != old_val) {
133  old_val = current_val;
134  current_ptr = i;
135  }
136  }
137 
138  table_inst.setFirst();
139  table_inst += current_ptr return table->get(table_inst);
140 # else
141 
142  for (Size i = 0; i < nb_elt; ++i, ++table_inst) {
143  GUM_MULTI_DIM_COMPLETE_PROJECTION(current_val, table->get(table_inst));
144  }
145 
146  return current_val;
147 # endif /* GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER */
148  }
149  }
150 
151 # undef GUM_MULTI_DIM_COMPLETE_PROJECTION_TYPE
152 
153 # ifdef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
154 # undef GUM_MULTI_DIM_COMPLETE_PROJECTION_POINTER
155 # endif
156 
157 } /* End of namespace gum */
158 
159 #endif /* GUM_COMPLETE_PROJECTION_PATTERN_ALLOWED */