31 #ifndef GUM_PROJECTION_PATTERN_ALLOWED 42 # ifdef GUM_MULTI_DIM_PROJECTION_NAME 43 # define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR 44 template <
typename GUM_SCALAR >
45 MultiDimImplementation< GUM_SCALAR >*
46 GUM_MULTI_DIM_PROJECTION_NAME(
const MultiDimImplementation< GUM_SCALAR >* table,
47 const Set<
const DiscreteVariable* >& del_vars)
52 #ifdef GUM_MULTI_DIM_PROJECTION_POINTER_NAME 53 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR * 54 #define GUM_MULTI_DIM_PROJECTION_POINTER 55 template <
typename GUM_SCALAR>
56 MultiDimImplementation<GUM_SCALAR*>* GUM_MULTI_DIM_PROJECTION_POINTER_NAME(
57 const MultiDimImplementation<GUM_SCALAR*>* table,
58 const Set<
const DiscreteVariable*>& del_vars )
61 #ifdef GUM_MULTI_DIM_PROJECTION_NAME_F 62 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR 63 template <
typename GUM_SCALAR>
64 MultiDimImplementation<GUM_SCALAR>* GUM_MULTI_DIM_PROJECTION_NAME_F(
65 const MultiDimImplementation<GUM_SCALAR>* table,
66 const Set<
const DiscreteVariable*>& del_vars,
67 GUM_SCALAR ( *f )(
const GUM_SCALAR&,
const GUM_SCALAR& ) )
70 #ifdef GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F 71 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR * 72 #define GUM_MULTI_DIM_PROJECTION_POINTER 73 template <
typename GUM_SCALAR>
74 MultiDimImplementation<GUM_SCALAR*>*
75 GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F(
76 const MultiDimImplementation<GUM_SCALAR*>* table,
77 const Set<
const DiscreteVariable*>& del_vars,
78 GUM_SCALAR* ( *f )(
const GUM_SCALAR
const*,
79 const GUM_SCALAR
const* ) )
88 const GUM_SCALAR neutral_element = GUM_MULTI_DIM_PROJECTION_NEUTRAL;
92 const Sequence<
const DiscreteVariable* >& table_vars = table->variablesSequence();
93 bool need_swapping = table_vars.size() >= 2 * del_vars.size();
105 std::vector< Idx > table_and_result_offset;
106 std::vector< Idx > table_and_result_domain;
107 std::vector< Idx > before_incr;
108 unsigned int nb_positive_before_incr = 0;
109 Idx table_alone_domain_size = 1;
110 Idx result_domain_size = 1;
111 Idx table_domain_size = 1;
112 Sequence<
const DiscreteVariable* > result_varSeq;
114 Idx tmp_before_incr = 1;
115 bool has_before_incr =
false;
117 for (
const auto var: table_vars) {
118 table_domain_size *= var->domainSize();
120 if (!del_vars.exists(var)) {
121 if (has_before_incr) {
122 before_incr.push_back(tmp_before_incr - 1);
123 has_before_incr =
false;
124 ++nb_positive_before_incr;
126 before_incr.push_back(0);
129 table_and_result_domain.push_back(var->domainSize());
130 table_and_result_offset.push_back(result_domain_size);
131 result_domain_size *= var->domainSize();
133 result_varSeq << var;
135 tmp_before_incr *= var->domainSize();
136 has_before_incr =
true;
137 table_alone_domain_size *= var->domainSize();
141 std::vector< Idx > table_and_result_value = table_and_result_domain;
142 std::vector< Idx > current_incr = before_incr;
143 std::vector< Idx > table_and_result_down = table_and_result_offset;
145 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
146 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
153 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result
154 =
new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
156 if (!result_varSeq.size()) {
return result; }
158 result->beginMultipleChanges();
160 for (
const auto var: result_varSeq)
163 result->endMultipleChanges();
166 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 168 for (Idx i = 0; i < result_domain_size; ++i) {
169 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
173 result->fill(neutral_element);
188 if (!nb_positive_before_incr) {
189 Idx result_offset = 0;
190 Instantiation table_inst(table);
192 for (Idx i = 0; i < table_alone_domain_size; ++i) {
193 for (Idx j = 0; j < result_domain_size; ++j) {
194 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 195 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
196 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
198 GUM_MULTI_DIM_PROJECTION_TYPE& res
199 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE& >(result->unsafeGet(result_offset));
200 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
214 Idx result_offset = 0;
215 Instantiation table_inst(table);
217 for (Idx i = 0; i < table_domain_size; ++i) {
218 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 219 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
220 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
222 GUM_MULTI_DIM_PROJECTION_TYPE& res
223 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE& >(result->unsafeGet(result_offset));
224 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
231 for (
unsigned int k = 0; k < current_incr.size(); ++k) {
233 if (current_incr[k]) {
238 current_incr[k] = before_incr[k];
241 --table_and_result_value[k];
243 if (table_and_result_value[k]) {
244 result_offset += table_and_result_offset[k];
248 table_and_result_value[k] = table_and_result_domain[k];
249 result_offset -= table_and_result_down[k];
266 std::vector< Idx > table_alone_offset;
267 std::vector< Idx > table_alone_domain;
269 Idx table_alone_domain_size = 1;
270 HashTable<
const DiscreteVariable*, Idx > var1offset(table_vars.size());
272 for (
const auto var: table_vars) {
273 if (del_vars.exists(var)) {
274 table_alone_domain.push_back(var->domainSize());
275 table_alone_offset.push_back(offset);
276 table_alone_domain_size *= var->domainSize();
279 var1offset.insert(var, offset);
280 offset *= var->domainSize();
283 std::vector< Idx > table_alone_value = table_alone_domain;
284 std::vector< Idx > table_alone_down = table_alone_offset;
286 for (
unsigned int i = 0; i < table_alone_down.size(); ++i)
287 table_alone_down[i] *= (table_alone_domain[i] - 1);
298 Sequence<
const DiscreteVariable* > result_varSeq;
299 std::vector< Idx > table_and_result_offset;
300 std::vector< Idx > table_and_result_domain;
301 Idx result_domain_size = 1;
302 bool has_before_incr =
false;
303 bool found_proj_var =
false;
305 for (
const auto var: table_vars) {
306 if (!del_vars.exists(var)) {
307 table_and_result_domain.push_back(var->domainSize());
308 table_and_result_offset.push_back(var1offset[var]);
309 found_proj_var =
true;
310 result_domain_size *= var->domainSize();
311 result_varSeq << var;
313 if (found_proj_var) has_before_incr =
true;
317 std::vector< Idx > table_and_result_value = table_and_result_domain;
318 std::vector< Idx > table_and_result_down = table_and_result_offset;
320 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
321 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
328 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result
329 =
new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
330 result->beginMultipleChanges();
332 for (
const auto var: result_varSeq)
335 result->endMultipleChanges();
338 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 340 for (Idx i = 0; i < result_domain_size; ++i) {
341 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
345 result->fill(neutral_element);
363 if (!has_before_incr) {
364 Idx result_offset = 0;
365 Instantiation table_inst(table);
367 for (Idx i = 0; i < result_domain_size; ++i) {
368 for (Idx j = 0; j < table_alone_domain_size; ++j) {
369 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 370 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
371 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
373 GUM_MULTI_DIM_PROJECTION_TYPE& res
374 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE& >(result->unsafeGet(result_offset));
375 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
388 Idx result_offset = 0;
389 Instantiation table_inst(table);
391 for (Idx j = 0; j < result_domain_size; ++j) {
392 for (Idx i = 0; i < table_alone_domain_size; ++i) {
393 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 394 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
395 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
397 GUM_MULTI_DIM_PROJECTION_TYPE& res
398 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE& >(result->unsafeGet(result_offset));
399 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
403 for (
unsigned int k = 0; k < table_alone_value.size(); ++k) {
404 --table_alone_value[k];
406 if (table_alone_value[k]) {
407 table_inst += table_alone_offset[k];
411 table_alone_value[k] = table_alone_domain[k];
412 table_inst -= table_alone_down[k];
417 for (
unsigned int k = 0; k < table_and_result_value.size(); ++k) {
418 --table_and_result_value[k];
420 if (table_and_result_value[k]) {
421 table_inst += table_and_result_offset[k];
425 table_and_result_value[k] = table_and_result_domain[k];
426 table_inst -= table_and_result_down[k];
438 # undef GUM_MULTI_DIM_PROJECTION_TYPE 440 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 441 # undef GUM_MULTI_DIM_PROJECTION_POINTER