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 MultiDimArray< GUM_SCALAR >* GUM_MULTI_DIM_PROJECTION_NAME(
46 const MultiDimArray< 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 MultiDimArray<GUM_SCALAR*>* GUM_MULTI_DIM_PROJECTION_POINTER_NAME(
57 const MultiDimArray<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 MultiDimArray<GUM_SCALAR>* GUM_MULTI_DIM_PROJECTION_NAME_F(
65 const MultiDimArray<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 MultiDimArray<GUM_SCALAR*>* GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F(
75 const MultiDimArray<GUM_SCALAR*>* table,
76 const Set<
const DiscreteVariable*>& del_vars,
77 GUM_SCALAR* ( *f )(
const GUM_SCALAR
const*,
78 const GUM_SCALAR
const* ) )
81 #ifdef GUM_MULTI_DIM_PROJECTION_IMPL2ARRAY_NAME 82 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR 83 template <
typename GUM_SCALAR>
84 MultiDimImplementation<GUM_SCALAR>*
85 GUM_MULTI_DIM_PROJECTION_IMPL2ARRAY_NAME(
86 const MultiDimImplementation<GUM_SCALAR>* ttable,
87 const Set<
const DiscreteVariable*>& del_vars )
90 #ifdef GUM_MULTI_DIM_PROJECTION_POINTER_IMPL2ARRAY_NAME 91 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR * 92 #define GUM_MULTI_DIM_PROJECTION_POINTER 93 template <
typename GUM_SCALAR>
94 MultiDimImplementation<GUM_SCALAR*>*
95 GUM_MULTI_DIM_PROJECTION_POINTER_IMPL2ARRAY_NAME(
96 const MultiDimImplementation<GUM_SCALAR*>* ttable,
97 const Set<
const DiscreteVariable*>& del_vars )
104 # ifdef GUM_MULTI_DIM_PROJECTION_IMPL2ARRAY_NAME 105 const MultiDimArray< GUM_SCALAR >* table
106 =
reinterpret_cast<
const MultiDimArray< GUM_SCALAR >* >(ttable);
109 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER_IMPL2ARRAY_NAME 110 const MultiDimArray< GUM_SCALAR* >* table
111 =
reinterpret_cast<
const MultiDimArray< GUM_SCALAR* >* >(ttable);
116 const GUM_SCALAR neutral_element = GUM_MULTI_DIM_PROJECTION_NEUTRAL;
120 const Sequence<
const DiscreteVariable* >& table_vars = table->variablesSequence();
121 bool need_swapping = table_vars.size() >= 2 * del_vars.size();
123 if (!need_swapping) {
133 std::vector< Idx > table_and_result_offset;
134 std::vector< Idx > table_and_result_domain;
135 std::vector< Idx > before_incr;
136 unsigned int nb_positive_before_incr = 0;
137 Idx table_alone_domain_size = 1;
138 Idx result_domain_size = 1;
139 Idx table_domain_size = 1;
140 Sequence<
const DiscreteVariable* > result_varSeq;
142 Idx tmp_before_incr = 1;
143 bool has_before_incr =
false;
145 for (
const auto var: table_vars) {
146 table_domain_size *= var->domainSize();
148 if (!del_vars.exists(var)) {
149 if (has_before_incr) {
150 before_incr.push_back(tmp_before_incr - 1);
151 has_before_incr =
false;
152 ++nb_positive_before_incr;
154 before_incr.push_back(0);
157 table_and_result_domain.push_back(var->domainSize());
158 table_and_result_offset.push_back(result_domain_size);
159 result_domain_size *= var->domainSize();
161 result_varSeq << var;
163 tmp_before_incr *= var->domainSize();
164 has_before_incr =
true;
165 table_alone_domain_size *= var->domainSize();
169 std::vector< Idx > table_and_result_value = table_and_result_domain;
170 std::vector< Idx > current_incr = before_incr;
171 std::vector< Idx > table_and_result_down = table_and_result_offset;
173 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
174 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
181 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result
182 =
new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
184 if (!result_varSeq.size()) {
return result; }
186 result->beginMultipleChanges();
188 for (
const auto var: result_varSeq)
192 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 193 result->endMultipleChanges();
195 for (Idx i = 0; i < result_domain_size; ++i) {
196 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
200 result->endMultipleChanges(neutral_element);
215 GUM_MULTI_DIM_PROJECTION_TYPE* pt
216 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE* >(&(table->unsafeGet(0)));
217 GUM_MULTI_DIM_PROJECTION_TYPE* pres
218 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE* >(&(result->unsafeGet(0)));
219 GUM_MULTI_DIM_PROJECTION_TYPE* pres_deb = pres;
221 if (!nb_positive_before_incr) {
222 for (Idx i = 0; i < table_alone_domain_size; ++i) {
223 for (Idx j = 0; j < result_domain_size; ++j) {
224 # ifdef GUM_MULTI_DIM_PROJECTION_EFFECTIVE_TYPE 225 GUM_MULTI_DIM_PROJECTION(*pres, *pt);
227 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 228 **pres = GUM_MULTI_DIM_PROJECTION(*pres, *pt);
230 *pres = GUM_MULTI_DIM_PROJECTION(*pres, *pt);
245 Idx result_offset = 0;
247 for (Idx i = 0; i < table_domain_size; ++i) {
248 # ifdef GUM_MULTI_DIM_PROJECTION_EFFECTIVE_TYPE 249 GUM_MULTI_DIM_PROJECTION(pres[result_offset], *pt);
251 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 252 *(pres[result_offset]) = GUM_MULTI_DIM_PROJECTION(pres[result_offset], *pt);
254 pres[result_offset] = GUM_MULTI_DIM_PROJECTION(pres[result_offset], *pt);
262 for (
unsigned int k = 0; k < current_incr.size(); ++k) {
264 if (current_incr[k]) {
269 current_incr[k] = before_incr[k];
272 --table_and_result_value[k];
274 if (table_and_result_value[k]) {
275 result_offset += table_and_result_offset[k];
279 table_and_result_value[k] = table_and_result_domain[k];
280 result_offset -= table_and_result_down[k];
297 std::vector< Idx > table_alone_offset;
298 std::vector< Idx > table_alone_domain;
300 Idx table_alone_domain_size = 1;
301 HashTable<
const DiscreteVariable*, Idx > var1offset(table_vars.size());
303 for (
const auto var: table_vars) {
304 if (del_vars.exists(var)) {
305 table_alone_domain.push_back(var->domainSize());
306 table_alone_offset.push_back(offset);
307 table_alone_domain_size *= var->domainSize();
310 var1offset.insert(var, offset);
311 offset *= var->domainSize();
314 std::vector< Idx > table_alone_value = table_alone_domain;
315 std::vector< Idx > table_alone_down = table_alone_offset;
317 for (
unsigned int i = 0; i < table_alone_down.size(); ++i)
318 table_alone_down[i] *= (table_alone_domain[i] - 1);
329 Sequence<
const DiscreteVariable* > result_varSeq;
330 std::vector< Idx > table_and_result_offset;
331 std::vector< Idx > table_and_result_domain;
332 Idx result_domain_size = 1;
333 bool has_before_incr =
false;
334 bool found_proj_var =
false;
336 for (
const auto var: table_vars) {
337 if (!del_vars.exists(var)) {
338 table_and_result_domain.push_back(var->domainSize());
339 table_and_result_offset.push_back(var1offset[var]);
340 found_proj_var =
true;
341 result_domain_size *= var->domainSize();
342 result_varSeq << var;
344 if (found_proj_var) has_before_incr =
true;
348 std::vector< Idx > table_and_result_value = table_and_result_domain;
349 std::vector< Idx > table_and_result_down = table_and_result_offset;
351 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
352 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
359 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result
360 =
new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
361 result->beginMultipleChanges();
363 for (
const auto var: result_varSeq)
366 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 367 result->endMultipleChanges();
370 for (Idx i = 0; i < result_domain_size; ++i) {
371 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
375 result->endMultipleChanges(neutral_element);
390 GUM_MULTI_DIM_PROJECTION_TYPE* pt
391 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE* >(&(table->unsafeGet(0)));
392 GUM_MULTI_DIM_PROJECTION_TYPE* pres
393 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE* >(&(result->unsafeGet(0)));
397 if (!has_before_incr) {
398 for (Idx i = 0; i < result_domain_size; ++i) {
399 for (Idx j = 0; j < table_alone_domain_size; ++j) {
400 # ifdef GUM_MULTI_DIM_PROJECTION_EFFECTIVE_TYPE 401 GUM_MULTI_DIM_PROJECTION(*pres, *pt);
403 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 404 **pres = GUM_MULTI_DIM_PROJECTION(*pres, *pt);
406 *pres = GUM_MULTI_DIM_PROJECTION(*pres, *pt);
420 Idx table_offset = 0;
422 for (Idx j = 0; j < result_domain_size; ++j) {
423 for (Idx i = 0; i < table_alone_domain_size; ++i) {
424 # ifdef GUM_MULTI_DIM_PROJECTION_EFFECTIVE_TYPE 425 GUM_MULTI_DIM_PROJECTION(*pres, pt[table_offset]);
427 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 428 **pres = GUM_MULTI_DIM_PROJECTION(*pres, pt[table_offset]);
430 *pres = GUM_MULTI_DIM_PROJECTION(*pres, pt[table_offset]);
435 for (
unsigned int k = 0; k < table_alone_value.size(); ++k) {
436 --table_alone_value[k];
438 if (table_alone_value[k]) {
439 table_offset += table_alone_offset[k];
443 table_alone_value[k] = table_alone_domain[k];
444 table_offset -= table_alone_down[k];
449 for (
unsigned int k = 0; k < table_and_result_value.size(); ++k) {
450 --table_and_result_value[k];
452 if (table_and_result_value[k]) {
453 table_offset += table_and_result_offset[k];
457 table_and_result_value[k] = table_and_result_domain[k];
458 table_offset -= table_and_result_down[k];
471 # undef GUM_MULTI_DIM_PROJECTION_TYPE 473 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 474 # undef GUM_MULTI_DIM_PROJECTION_POINTER