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 >* GUM_MULTI_DIM_PROJECTION_NAME(
46 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
93 = table->variablesSequence();
94 bool need_swapping = table_vars.size() >= 2 * del_vars.size();
106 std::vector< Idx > table_and_result_offset;
107 std::vector< Idx > table_and_result_domain;
108 std::vector< Idx > before_incr;
109 unsigned int nb_positive_before_incr = 0;
110 Idx table_alone_domain_size = 1;
111 Idx result_domain_size = 1;
112 Idx table_domain_size = 1;
113 Sequence<
const DiscreteVariable* > result_varSeq;
115 Idx tmp_before_incr = 1;
116 bool has_before_incr =
false;
118 for (
const auto var: table_vars) {
119 table_domain_size *= var->domainSize();
121 if (!del_vars.exists(var)) {
122 if (has_before_incr) {
123 before_incr.push_back(tmp_before_incr - 1);
124 has_before_incr =
false;
125 ++nb_positive_before_incr;
127 before_incr.push_back(0);
130 table_and_result_domain.push_back(var->domainSize());
131 table_and_result_offset.push_back(result_domain_size);
132 result_domain_size *= var->domainSize();
134 result_varSeq << var;
136 tmp_before_incr *= var->domainSize();
137 has_before_incr =
true;
138 table_alone_domain_size *= var->domainSize();
142 std::vector< Idx > table_and_result_value = table_and_result_domain;
143 std::vector< Idx > current_incr = before_incr;
144 std::vector< Idx > table_and_result_down = table_and_result_offset;
146 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
147 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
154 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result
155 =
new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
157 if (!result_varSeq.size()) {
return result; }
159 result->beginMultipleChanges();
161 for (
const auto var: result_varSeq)
164 result->endMultipleChanges();
167 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 169 for (Idx i = 0; i < result_domain_size; ++i) {
170 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
174 result->fill(neutral_element);
189 if (!nb_positive_before_incr) {
190 Idx result_offset = 0;
191 Instantiation table_inst(table);
193 for (Idx i = 0; i < table_alone_domain_size; ++i) {
194 for (Idx j = 0; j < result_domain_size; ++j) {
195 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 196 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
197 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
199 GUM_MULTI_DIM_PROJECTION_TYPE& res
200 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE& >(
201 result->unsafeGet(result_offset));
202 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
216 Idx result_offset = 0;
217 Instantiation table_inst(table);
219 for (Idx i = 0; i < table_domain_size; ++i) {
220 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 221 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
222 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
224 GUM_MULTI_DIM_PROJECTION_TYPE& res
225 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE& >(
226 result->unsafeGet(result_offset));
227 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
234 for (
unsigned int k = 0; k < current_incr.size(); ++k) {
236 if (current_incr[k]) {
241 current_incr[k] = before_incr[k];
244 --table_and_result_value[k];
246 if (table_and_result_value[k]) {
247 result_offset += table_and_result_offset[k];
251 table_and_result_value[k] = table_and_result_domain[k];
252 result_offset -= table_and_result_down[k];
269 std::vector< Idx > table_alone_offset;
270 std::vector< Idx > table_alone_domain;
272 Idx table_alone_domain_size = 1;
273 HashTable<
const DiscreteVariable*, Idx > var1offset(table_vars.size());
275 for (
const auto var: table_vars) {
276 if (del_vars.exists(var)) {
277 table_alone_domain.push_back(var->domainSize());
278 table_alone_offset.push_back(offset);
279 table_alone_domain_size *= var->domainSize();
282 var1offset.insert(var, offset);
283 offset *= var->domainSize();
286 std::vector< Idx > table_alone_value = table_alone_domain;
287 std::vector< Idx > table_alone_down = table_alone_offset;
289 for (
unsigned int i = 0; i < table_alone_down.size(); ++i)
290 table_alone_down[i] *= (table_alone_domain[i] - 1);
301 Sequence<
const DiscreteVariable* > result_varSeq;
302 std::vector< Idx > table_and_result_offset;
303 std::vector< Idx > table_and_result_domain;
304 Idx result_domain_size = 1;
305 bool has_before_incr =
false;
306 bool found_proj_var =
false;
308 for (
const auto var: table_vars) {
309 if (!del_vars.exists(var)) {
310 table_and_result_domain.push_back(var->domainSize());
311 table_and_result_offset.push_back(var1offset[var]);
312 found_proj_var =
true;
313 result_domain_size *= var->domainSize();
314 result_varSeq << var;
316 if (found_proj_var) has_before_incr =
true;
320 std::vector< Idx > table_and_result_value = table_and_result_domain;
321 std::vector< Idx > table_and_result_down = table_and_result_offset;
323 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
324 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
331 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result
332 =
new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
333 result->beginMultipleChanges();
335 for (
const auto var: result_varSeq)
338 result->endMultipleChanges();
341 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 343 for (Idx i = 0; i < result_domain_size; ++i) {
344 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
348 result->fill(neutral_element);
366 if (!has_before_incr) {
367 Idx result_offset = 0;
368 Instantiation table_inst(table);
370 for (Idx i = 0; i < result_domain_size; ++i) {
371 for (Idx j = 0; j < table_alone_domain_size; ++j) {
372 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 373 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
374 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
376 GUM_MULTI_DIM_PROJECTION_TYPE& res
377 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE& >(
378 result->unsafeGet(result_offset));
379 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
392 Idx result_offset = 0;
393 Instantiation table_inst(table);
395 for (Idx j = 0; j < result_domain_size; ++j) {
396 for (Idx i = 0; i < table_alone_domain_size; ++i) {
397 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 398 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
399 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
401 GUM_MULTI_DIM_PROJECTION_TYPE& res
402 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE& >(
403 result->unsafeGet(result_offset));
404 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
408 for (
unsigned int k = 0; k < table_alone_value.size(); ++k) {
409 --table_alone_value[k];
411 if (table_alone_value[k]) {
412 table_inst += table_alone_offset[k];
416 table_alone_value[k] = table_alone_domain[k];
417 table_inst -= table_alone_down[k];
422 for (
unsigned int k = 0; k < table_and_result_value.size(); ++k) {
423 --table_and_result_value[k];
425 if (table_and_result_value[k]) {
426 table_inst += table_and_result_offset[k];
430 table_and_result_value[k] = table_and_result_domain[k];
431 table_inst -= table_and_result_down[k];
443 # undef GUM_MULTI_DIM_PROJECTION_TYPE 445 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 446 # undef GUM_MULTI_DIM_PROJECTION_POINTER