29 #ifndef GUM_PROJECTION_PATTERN_ALLOWED 40 # ifdef GUM_MULTI_DIM_PROJECTION_NAME 41 # define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR 42 template <
typename GUM_SCALAR >
43 MultiDimImplementation< GUM_SCALAR >* GUM_MULTI_DIM_PROJECTION_NAME(
44 const MultiDimImplementation< GUM_SCALAR >* table,
45 const Set< const DiscreteVariable* >& del_vars)
50 #ifdef GUM_MULTI_DIM_PROJECTION_POINTER_NAME 51 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR * 52 #define GUM_MULTI_DIM_PROJECTION_POINTER 53 template <
typename GUM_SCALAR>
54 MultiDimImplementation<GUM_SCALAR*>* GUM_MULTI_DIM_PROJECTION_POINTER_NAME(
55 const MultiDimImplementation<GUM_SCALAR*>* table,
56 const Set<const DiscreteVariable*>& del_vars )
59 #ifdef GUM_MULTI_DIM_PROJECTION_NAME_F 60 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR 61 template <
typename GUM_SCALAR>
62 MultiDimImplementation<GUM_SCALAR>* GUM_MULTI_DIM_PROJECTION_NAME_F(
63 const MultiDimImplementation<GUM_SCALAR>* table,
64 const Set<const DiscreteVariable*>& del_vars,
65 GUM_SCALAR ( *f )(
const GUM_SCALAR&,
const GUM_SCALAR& ) )
68 #ifdef GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F 69 #define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR * 70 #define GUM_MULTI_DIM_PROJECTION_POINTER 71 template <
typename GUM_SCALAR>
72 MultiDimImplementation<GUM_SCALAR*>*
73 GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F(
74 const MultiDimImplementation<GUM_SCALAR*>* table,
75 const Set<const DiscreteVariable*>& del_vars,
76 GUM_SCALAR* ( *f )(
const GUM_SCALAR
const*,
77 const GUM_SCALAR
const* ) )
86 const GUM_SCALAR neutral_element = GUM_MULTI_DIM_PROJECTION_NEUTRAL;
90 const Sequence< const DiscreteVariable* >& table_vars =
91 table->variablesSequence();
92 bool need_swapping = table_vars.size() >= 2 * del_vars.size();
104 std::vector< Idx > table_and_result_offset;
105 std::vector< Idx > table_and_result_domain;
106 std::vector< Idx > before_incr;
107 unsigned int nb_positive_before_incr = 0;
108 Idx table_alone_domain_size = 1;
109 Idx result_domain_size = 1;
110 Idx table_domain_size = 1;
111 Sequence< const DiscreteVariable* > result_varSeq;
113 Idx tmp_before_incr = 1;
114 bool has_before_incr =
false;
116 for (
const auto var : table_vars) {
117 table_domain_size *= var->domainSize();
119 if (!del_vars.exists(var)) {
120 if (has_before_incr) {
121 before_incr.push_back(tmp_before_incr - 1);
122 has_before_incr =
false;
123 ++nb_positive_before_incr;
125 before_incr.push_back(0);
128 table_and_result_domain.push_back(var->domainSize());
129 table_and_result_offset.push_back(result_domain_size);
130 result_domain_size *= var->domainSize();
132 result_varSeq << var;
134 tmp_before_incr *= var->domainSize();
135 has_before_incr =
true;
136 table_alone_domain_size *= var->domainSize();
140 std::vector< Idx > table_and_result_value = table_and_result_domain;
141 std::vector< Idx > current_incr = before_incr;
142 std::vector< Idx > table_and_result_down = table_and_result_offset;
144 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
145 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
152 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result =
153 new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
155 if (!result_varSeq.size()) {
return result; }
157 result->beginMultipleChanges();
159 for (
const auto var : result_varSeq)
162 result->endMultipleChanges();
165 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 167 for (
Idx i = 0; i < result_domain_size; ++i) {
168 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
172 result->fill(neutral_element);
187 if (!nb_positive_before_incr) {
188 Idx result_offset = 0;
189 Instantiation table_inst(table);
191 for (
Idx i = 0; i < table_alone_domain_size; ++i) {
192 for (
Idx j = 0; j < result_domain_size; ++j) {
193 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 194 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
195 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
197 GUM_MULTI_DIM_PROJECTION_TYPE& res =
198 const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(
199 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&
>(
224 result->unsafeGet(result_offset));
225 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
232 for (
unsigned int k = 0; k < current_incr.size(); ++k) {
234 if (current_incr[k]) {
239 current_incr[k] = before_incr[k];
242 --table_and_result_value[k];
244 if (table_and_result_value[k]) {
245 result_offset += table_and_result_offset[k];
249 table_and_result_value[k] = table_and_result_domain[k];
250 result_offset -= table_and_result_down[k];
267 std::vector< Idx > table_alone_offset;
268 std::vector< Idx > table_alone_domain;
270 Idx table_alone_domain_size = 1;
271 HashTable< const DiscreteVariable*, Idx > var1offset(table_vars.size());
273 for (
const auto var : table_vars) {
274 if (del_vars.exists(var)) {
275 table_alone_domain.push_back(var->domainSize());
276 table_alone_offset.push_back(offset);
277 table_alone_domain_size *= var->domainSize();
280 var1offset.insert(var, offset);
281 offset *= var->domainSize();
284 std::vector< Idx > table_alone_value = table_alone_domain;
285 std::vector< Idx > table_alone_down = table_alone_offset;
287 for (
unsigned int i = 0; i < table_alone_down.size(); ++i)
288 table_alone_down[i] *= (table_alone_domain[i] - 1);
299 Sequence< const DiscreteVariable* > result_varSeq;
300 std::vector< Idx > table_and_result_offset;
301 std::vector< Idx > table_and_result_domain;
302 Idx result_domain_size = 1;
303 bool has_before_incr =
false;
304 bool found_proj_var =
false;
306 for (
const auto var : table_vars) {
307 if (!del_vars.exists(var)) {
308 table_and_result_domain.push_back(var->domainSize());
309 table_and_result_offset.push_back(var1offset[var]);
310 found_proj_var =
true;
311 result_domain_size *= var->domainSize();
312 result_varSeq << var;
314 if (found_proj_var) has_before_incr =
true;
318 std::vector< Idx > table_and_result_value = table_and_result_domain;
319 std::vector< Idx > table_and_result_down = table_and_result_offset;
321 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
322 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
329 MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >* result =
330 new MultiDimArray< GUM_MULTI_DIM_PROJECTION_TYPE >;
331 result->beginMultipleChanges();
333 for (
const auto var : result_varSeq)
336 result->endMultipleChanges();
339 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 341 for (
Idx i = 0; i < result_domain_size; ++i) {
342 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
346 result->fill(neutral_element);
364 if (!has_before_incr) {
365 Idx result_offset = 0;
366 Instantiation table_inst(table);
368 for (
Idx i = 0; i < result_domain_size; ++i) {
369 for (
Idx j = 0; j < table_alone_domain_size; ++j) {
370 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 371 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
372 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
374 GUM_MULTI_DIM_PROJECTION_TYPE& res =
375 const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(
376 result->unsafeGet(result_offset));
377 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
390 Idx result_offset = 0;
391 Instantiation table_inst(table);
393 for (
Idx j = 0; j < result_domain_size; ++j) {
394 for (
Idx i = 0; i < table_alone_domain_size; ++i) {
395 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 396 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
397 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
399 GUM_MULTI_DIM_PROJECTION_TYPE& res =
400 const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(
401 result->unsafeGet(result_offset));
402 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
406 for (
unsigned int k = 0; k < table_alone_value.size(); ++k) {
407 --table_alone_value[k];
409 if (table_alone_value[k]) {
410 table_inst += table_alone_offset[k];
414 table_alone_value[k] = table_alone_domain[k];
415 table_inst -= table_alone_down[k];
420 for (
unsigned int k = 0; k < table_and_result_value.size(); ++k) {
421 --table_and_result_value[k];
423 if (table_and_result_value[k]) {
424 table_inst += table_and_result_offset[k];
428 table_and_result_value[k] = table_and_result_domain[k];
429 table_inst -= table_and_result_down[k];
441 # undef GUM_MULTI_DIM_PROJECTION_TYPE 443 # ifdef GUM_MULTI_DIM_PROJECTION_POINTER 444 # undef GUM_MULTI_DIM_PROJECTION_POINTER gum is the global namespace for all aGrUM entities