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
121 = table->variablesSequence();
122 bool need_swapping = table_vars.size() >= 2 * del_vars.size();
124 if (!need_swapping) {
134 std::vector< Idx > table_and_result_offset;
135 std::vector< Idx > table_and_result_domain;
136 std::vector< Idx > before_incr;
137 unsigned int nb_positive_before_incr = 0;
138 Idx table_alone_domain_size = 1;
139 Idx result_domain_size = 1;
140 Idx table_domain_size = 1;
141 Sequence<
const DiscreteVariable* > result_varSeq;
143 Idx tmp_before_incr = 1;
144 bool has_before_incr =
false;
146 for (
const auto var: table_vars) {
147 table_domain_size *= var->domainSize();
149 if (!del_vars.exists(var)) {
150 if (has_before_incr) {
151 before_incr.push_back(tmp_before_incr - 1);
152 has_before_incr =
false;
153 ++nb_positive_before_incr;
155 before_incr.push_back(0);
158 table_and_result_domain.push_back(var->domainSize());
159 table_and_result_offset.push_back(result_domain_size);
160 result_domain_size *= var->domainSize();
162 result_varSeq << var;
164 tmp_before_incr *= var->domainSize();
165 has_before_incr =
true;
166 table_alone_domain_size *= var->domainSize();
170 std::vector< Idx > table_and_result_value = table_and_result_domain;
171 std::vector< Idx > current_incr = before_incr;
172 std::vector< Idx > table_and_result_down = table_and_result_offset;
174 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
175 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
182 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result
183 =
new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
185 if (!result_varSeq.size()) {
return result; }
187 result->beginMultipleChanges();
189 for (
const auto var: result_varSeq)
193 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 194 result->endMultipleChanges();
196 for (Idx i = 0; i < result_domain_size; ++i) {
197 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
201 result->endMultipleChanges(neutral_element);
216 GUM_MULTI_DIM_PROJECTION_TYPE* pt
217 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE* >(&(table->unsafeGet(0)));
218 GUM_MULTI_DIM_PROJECTION_TYPE* pres
219 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE* >(&(result->unsafeGet(0)));
220 GUM_MULTI_DIM_PROJECTION_TYPE* pres_deb = pres;
222 if (!nb_positive_before_incr) {
223 for (Idx i = 0; i < table_alone_domain_size; ++i) {
224 for (Idx j = 0; j < result_domain_size; ++j) {
225 # ifdef GUM_MULTI_DIM_PROJECTION_EFFECTIVE_TYPE 226 GUM_MULTI_DIM_PROJECTION(*pres, *pt);
228 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 229 **pres = GUM_MULTI_DIM_PROJECTION(*pres, *pt);
231 *pres = GUM_MULTI_DIM_PROJECTION(*pres, *pt);
246 Idx result_offset = 0;
248 for (Idx i = 0; i < table_domain_size; ++i) {
249 # ifdef GUM_MULTI_DIM_PROJECTION_EFFECTIVE_TYPE 250 GUM_MULTI_DIM_PROJECTION(pres[result_offset], *pt);
252 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 253 *(pres[result_offset])
254 = GUM_MULTI_DIM_PROJECTION(pres[result_offset], *pt);
256 pres[result_offset] = GUM_MULTI_DIM_PROJECTION(pres[result_offset], *pt);
264 for (
unsigned int k = 0; k < current_incr.size(); ++k) {
266 if (current_incr[k]) {
271 current_incr[k] = before_incr[k];
274 --table_and_result_value[k];
276 if (table_and_result_value[k]) {
277 result_offset += table_and_result_offset[k];
281 table_and_result_value[k] = table_and_result_domain[k];
282 result_offset -= table_and_result_down[k];
299 std::vector< Idx > table_alone_offset;
300 std::vector< Idx > table_alone_domain;
302 Idx table_alone_domain_size = 1;
303 HashTable<
const DiscreteVariable*, Idx > var1offset(table_vars.size());
305 for (
const auto var: table_vars) {
306 if (del_vars.exists(var)) {
307 table_alone_domain.push_back(var->domainSize());
308 table_alone_offset.push_back(offset);
309 table_alone_domain_size *= var->domainSize();
312 var1offset.insert(var, offset);
313 offset *= var->domainSize();
316 std::vector< Idx > table_alone_value = table_alone_domain;
317 std::vector< Idx > table_alone_down = table_alone_offset;
319 for (
unsigned int i = 0; i < table_alone_down.size(); ++i)
320 table_alone_down[i] *= (table_alone_domain[i] - 1);
331 Sequence<
const DiscreteVariable* > result_varSeq;
332 std::vector< Idx > table_and_result_offset;
333 std::vector< Idx > table_and_result_domain;
334 Idx result_domain_size = 1;
335 bool has_before_incr =
false;
336 bool found_proj_var =
false;
338 for (
const auto var: table_vars) {
339 if (!del_vars.exists(var)) {
340 table_and_result_domain.push_back(var->domainSize());
341 table_and_result_offset.push_back(var1offset[var]);
342 found_proj_var =
true;
343 result_domain_size *= var->domainSize();
344 result_varSeq << var;
346 if (found_proj_var) has_before_incr =
true;
350 std::vector< Idx > table_and_result_value = table_and_result_domain;
351 std::vector< Idx > table_and_result_down = table_and_result_offset;
353 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
354 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
361 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result
362 =
new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
363 result->beginMultipleChanges();
365 for (
const auto var: result_varSeq)
368 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 369 result->endMultipleChanges();
372 for (Idx i = 0; i < result_domain_size; ++i) {
373 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
377 result->endMultipleChanges(neutral_element);
392 GUM_MULTI_DIM_PROJECTION_TYPE* pt
393 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE* >(&(table->unsafeGet(0)));
394 GUM_MULTI_DIM_PROJECTION_TYPE* pres
395 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE* >(&(result->unsafeGet(0)));
399 if (!has_before_incr) {
400 for (Idx i = 0; i < result_domain_size; ++i) {
401 for (Idx j = 0; j < table_alone_domain_size; ++j) {
402 # ifdef GUM_MULTI_DIM_PROJECTION_EFFECTIVE_TYPE 403 GUM_MULTI_DIM_PROJECTION(*pres, *pt);
405 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 406 **pres = GUM_MULTI_DIM_PROJECTION(*pres, *pt);
408 *pres = GUM_MULTI_DIM_PROJECTION(*pres, *pt);
422 Idx table_offset = 0;
424 for (Idx j = 0; j < result_domain_size; ++j) {
425 for (Idx i = 0; i < table_alone_domain_size; ++i) {
426 # ifdef GUM_MULTI_DIM_PROJECTION_EFFECTIVE_TYPE 427 GUM_MULTI_DIM_PROJECTION(*pres, pt[table_offset]);
429 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 430 **pres = GUM_MULTI_DIM_PROJECTION(*pres, pt[table_offset]);
432 *pres = GUM_MULTI_DIM_PROJECTION(*pres, pt[table_offset]);
437 for (
unsigned int k = 0; k < table_alone_value.size(); ++k) {
438 --table_alone_value[k];
440 if (table_alone_value[k]) {
441 table_offset += table_alone_offset[k];
445 table_alone_value[k] = table_alone_domain[k];
446 table_offset -= table_alone_down[k];
451 for (
unsigned int k = 0; k < table_and_result_value.size(); ++k) {
452 --table_and_result_value[k];
454 if (table_and_result_value[k]) {
455 table_offset += table_and_result_offset[k];
459 table_and_result_value[k] = table_and_result_domain[k];
460 table_offset -= table_and_result_down[k];
473 # undef GUM_MULTI_DIM_PROJECTION_TYPE 475 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 476 # undef GUM_MULTI_DIM_PROJECTION_POINTER