32 #ifndef GUM_PROJECTION_PATTERN_ALLOWED 43 # ifdef GUM_MULTI_DIM_PROJECTION_NAME 44 # define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR 45 template <
typename GUM_SCALAR >
46 MultiDimImplementation< GUM_SCALAR >* GUM_MULTI_DIM_PROJECTION_NAME(
47 const MultiDimImplementation< GUM_SCALAR >* table,
48 const Set< const DiscreteVariable* >& del_vars)
53 #ifdef GUM_MULTI_DIM_PROJECTION_POINTER_NAME 54 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR * 55 #define GUM_MULTI_DIM_PROJECTION_POINTER 56 template <
typename GUM_SCALAR>
57 MultiDimImplementation<GUM_SCALAR*>* GUM_MULTI_DIM_PROJECTION_POINTER_NAME(
58 const MultiDimImplementation<GUM_SCALAR*>* table,
59 const Set<const DiscreteVariable*>& del_vars )
62 #ifdef GUM_MULTI_DIM_PROJECTION_NAME_F 63 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR 64 template <
typename GUM_SCALAR>
65 MultiDimImplementation<GUM_SCALAR>* GUM_MULTI_DIM_PROJECTION_NAME_F(
66 const MultiDimImplementation<GUM_SCALAR>* table,
67 const Set<const DiscreteVariable*>& del_vars,
68 GUM_SCALAR ( *f )(
const GUM_SCALAR&,
const GUM_SCALAR& ) )
71 #ifdef GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F 72 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR * 73 #define GUM_MULTI_DIM_PROJECTION_POINTER 74 template <
typename GUM_SCALAR>
75 MultiDimImplementation<GUM_SCALAR*>*
76 GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F(
77 const MultiDimImplementation<GUM_SCALAR*>* table,
78 const Set<const DiscreteVariable*>& del_vars,
79 GUM_SCALAR* ( *f )(
const GUM_SCALAR
const*,
80 const GUM_SCALAR
const* ) )
89 const GUM_SCALAR neutral_element = GUM_MULTI_DIM_PROJECTION_NEUTRAL;
93 const Sequence< const DiscreteVariable* >& table_vars =
94 table->variablesSequence();
95 bool need_swapping = table_vars.size() >= 2 * del_vars.size();
107 std::vector< Idx > table_and_result_offset;
108 std::vector< Idx > table_and_result_domain;
109 std::vector< Idx > before_incr;
110 unsigned int nb_positive_before_incr = 0;
111 Idx table_alone_domain_size = 1;
112 Idx result_domain_size = 1;
113 Idx table_domain_size = 1;
114 Sequence< const DiscreteVariable* > result_varSeq;
116 Idx tmp_before_incr = 1;
117 bool has_before_incr =
false;
119 for (
const auto var : table_vars) {
120 table_domain_size *= var->domainSize();
122 if (!del_vars.exists(var)) {
123 if (has_before_incr) {
124 before_incr.push_back(tmp_before_incr - 1);
125 has_before_incr =
false;
126 ++nb_positive_before_incr;
128 before_incr.push_back(0);
131 table_and_result_domain.push_back(var->domainSize());
132 table_and_result_offset.push_back(result_domain_size);
133 result_domain_size *= var->domainSize();
135 result_varSeq << var;
137 tmp_before_incr *= var->domainSize();
138 has_before_incr =
true;
139 table_alone_domain_size *= var->domainSize();
143 std::vector< Idx > table_and_result_value = table_and_result_domain;
144 std::vector< Idx > current_incr = before_incr;
145 std::vector< Idx > table_and_result_down = table_and_result_offset;
147 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
148 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
155 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result =
156 new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
158 if (!result_varSeq.size()) {
return result; }
160 result->beginMultipleChanges();
162 for (
const auto var : result_varSeq)
165 result->endMultipleChanges();
168 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 170 for (
Idx i = 0; i < result_domain_size; ++i) {
171 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
175 result->fill(neutral_element);
190 if (!nb_positive_before_incr) {
191 Idx result_offset = 0;
192 Instantiation table_inst(table);
194 for (
Idx i = 0; i < table_alone_domain_size; ++i) {
195 for (
Idx j = 0; j < result_domain_size; ++j) {
196 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 197 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
198 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
200 GUM_MULTI_DIM_PROJECTION_TYPE& res =
201 const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(
202 result->unsafeGet(result_offset));
203 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
217 Idx result_offset = 0;
218 Instantiation table_inst(table);
220 for (
Idx i = 0; i < table_domain_size; ++i) {
221 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 222 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
223 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
225 GUM_MULTI_DIM_PROJECTION_TYPE& res =
226 const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(
227 result->unsafeGet(result_offset));
228 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
235 for (
unsigned int k = 0; k < current_incr.size(); ++k) {
237 if (current_incr[k]) {
242 current_incr[k] = before_incr[k];
245 --table_and_result_value[k];
247 if (table_and_result_value[k]) {
248 result_offset += table_and_result_offset[k];
252 table_and_result_value[k] = table_and_result_domain[k];
253 result_offset -= table_and_result_down[k];
270 std::vector< Idx > table_alone_offset;
271 std::vector< Idx > table_alone_domain;
273 Idx table_alone_domain_size = 1;
274 HashTable< const DiscreteVariable*, Idx > var1offset(table_vars.size());
276 for (
const auto var : table_vars) {
277 if (del_vars.exists(var)) {
278 table_alone_domain.push_back(var->domainSize());
279 table_alone_offset.push_back(offset);
280 table_alone_domain_size *= var->domainSize();
283 var1offset.insert(var, offset);
284 offset *= var->domainSize();
287 std::vector< Idx > table_alone_value = table_alone_domain;
288 std::vector< Idx > table_alone_down = table_alone_offset;
290 for (
unsigned int i = 0; i < table_alone_down.size(); ++i)
291 table_alone_down[i] *= (table_alone_domain[i] - 1);
302 Sequence< const DiscreteVariable* > result_varSeq;
303 std::vector< Idx > table_and_result_offset;
304 std::vector< Idx > table_and_result_domain;
305 Idx result_domain_size = 1;
306 bool has_before_incr =
false;
307 bool found_proj_var =
false;
309 for (
const auto var : table_vars) {
310 if (!del_vars.exists(var)) {
311 table_and_result_domain.push_back(var->domainSize());
312 table_and_result_offset.push_back(var1offset[var]);
313 found_proj_var =
true;
314 result_domain_size *= var->domainSize();
315 result_varSeq << var;
317 if (found_proj_var) has_before_incr =
true;
321 std::vector< Idx > table_and_result_value = table_and_result_domain;
322 std::vector< Idx > table_and_result_down = table_and_result_offset;
324 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
325 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
332 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result =
333 new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
334 result->beginMultipleChanges();
336 for (
const auto var : result_varSeq)
339 result->endMultipleChanges();
342 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 344 for (
Idx i = 0; i < result_domain_size; ++i) {
345 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
349 result->fill(neutral_element);
367 if (!has_before_incr) {
368 Idx result_offset = 0;
369 Instantiation table_inst(table);
371 for (
Idx i = 0; i < result_domain_size; ++i) {
372 for (
Idx j = 0; j < table_alone_domain_size; ++j) {
373 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 374 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
375 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
377 GUM_MULTI_DIM_PROJECTION_TYPE& res =
378 const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(
379 result->unsafeGet(result_offset));
380 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
393 Idx result_offset = 0;
394 Instantiation table_inst(table);
396 for (
Idx j = 0; j < result_domain_size; ++j) {
397 for (
Idx i = 0; i < table_alone_domain_size; ++i) {
398 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 399 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
400 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
402 GUM_MULTI_DIM_PROJECTION_TYPE& res =
403 const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(
404 result->unsafeGet(result_offset));
405 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
409 for (
unsigned int k = 0; k < table_alone_value.size(); ++k) {
410 --table_alone_value[k];
412 if (table_alone_value[k]) {
413 table_inst += table_alone_offset[k];
417 table_alone_value[k] = table_alone_domain[k];
418 table_inst -= table_alone_down[k];
423 for (
unsigned int k = 0; k < table_and_result_value.size(); ++k) {
424 --table_and_result_value[k];
426 if (table_and_result_value[k]) {
427 table_inst += table_and_result_offset[k];
431 table_and_result_value[k] = table_and_result_domain[k];
432 table_inst -= table_and_result_down[k];
444 # undef GUM_MULTI_DIM_PROJECTION_TYPE 446 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 447 # undef GUM_MULTI_DIM_PROJECTION_POINTER Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.