51#ifndef GUM_PROJECTION_PATTERN_ALLOWED
62# ifdef GUM_MULTI_DIM_PROJECTION_NAME
63# define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR
65 template <
typename GUM_SCALAR >
73#ifdef GUM_MULTI_DIM_PROJECTION_POINTER_NAME
74#define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR *
75#define GUM_MULTI_DIM_PROJECTION_POINTER
76 template <
typename GUM_SCALAR>
82#ifdef GUM_MULTI_DIM_PROJECTION_NAME_F
83#define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR
84 template <
typename GUM_SCALAR>
88 GUM_SCALAR ( *f )(
const GUM_SCALAR&,
const GUM_SCALAR& ) )
91#ifdef GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F
92#define GUM_MULTI_DIM_PROJECTION_TYPE GUM_SCALAR *
93#define GUM_MULTI_DIM_PROJECTION_POINTER
94 template <
typename GUM_SCALAR>
96 GUM_MULTI_DIM_PROJECTION_POINTER_NAME_F(
99 GUM_SCALAR* ( *f )(
const GUM_SCALAR
const*,
100 const GUM_SCALAR
const* ) )
109 const GUM_SCALAR neutral_element = GUM_MULTI_DIM_PROJECTION_NEUTRAL;
114 bool need_swapping = table_vars.
size() >= 2 * del_vars.size();
116 if (!need_swapping) {
126 std::vector< Idx > table_and_result_offset;
127 std::vector< Idx > table_and_result_domain;
128 std::vector< Idx > before_incr;
129 unsigned int nb_positive_before_incr = 0;
130 Idx table_alone_domain_size = 1;
131 Idx result_domain_size = 1;
132 Idx table_domain_size = 1;
135 Idx tmp_before_incr = 1;
136 bool has_before_incr =
false;
138 for (
const auto var: table_vars) {
139 table_domain_size *= var->domainSize();
141 if (!del_vars.exists(var)) {
142 if (has_before_incr) {
143 before_incr.push_back(tmp_before_incr - 1);
144 has_before_incr =
false;
145 ++nb_positive_before_incr;
147 before_incr.push_back(0);
150 table_and_result_domain.push_back(var->domainSize());
151 table_and_result_offset.push_back(result_domain_size);
152 result_domain_size *= var->domainSize();
154 result_varSeq << var;
156 tmp_before_incr *= var->domainSize();
157 has_before_incr =
true;
158 table_alone_domain_size *= var->domainSize();
162 std::vector< Idx > table_and_result_value = table_and_result_domain;
163 std::vector< Idx > current_incr = before_incr;
164 std::vector< Idx > table_and_result_down = table_and_result_offset;
166 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
167 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
177 if (!result_varSeq.size()) {
return result; }
181 for (
const auto var: result_varSeq)
184 result->endMultipleChanges();
187# ifdef GUM_MULTI_DIM_PROJECTION_POINTER
189 for (
Idx i = 0; i < result_domain_size; ++i) {
190 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
194 result->fill(neutral_element);
209 if (!nb_positive_before_incr) {
210 Idx result_offset = 0;
214 for (
const auto var: table->variablesSequence())
215 table_inst.
add(*var);
217 for (
Idx i = 0; i < table_alone_domain_size; ++i) {
218 for (
Idx j = 0; j < result_domain_size; ++j) {
219# ifdef GUM_MULTI_DIM_PROJECTION_POINTER
220 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
221 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
223 GUM_MULTI_DIM_PROJECTION_TYPE& res
224 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(result->unsafeGet(result_offset));
225 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
239 Idx result_offset = 0;
243 for (
const auto var: table->variablesSequence())
244 table_inst.
add(*var);
246 for (
Idx i = 0; i < table_domain_size; ++i) {
247# ifdef GUM_MULTI_DIM_PROJECTION_POINTER
248 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
249 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
251 GUM_MULTI_DIM_PROJECTION_TYPE& res
252 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(result->unsafeGet(result_offset));
253 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
260 for (
unsigned int k = 0; k < current_incr.size(); ++k) {
262 if (current_incr[k]) {
267 current_incr[k] = before_incr[k];
270 --table_and_result_value[k];
272 if (table_and_result_value[k]) {
273 result_offset += table_and_result_offset[k];
277 table_and_result_value[k] = table_and_result_domain[k];
278 result_offset -= table_and_result_down[k];
295 std::vector< Idx > table_alone_offset;
296 std::vector< Idx > table_alone_domain;
298 Idx table_alone_domain_size = 1;
301 for (
const auto var: table_vars) {
302 if (del_vars.exists(var)) {
303 table_alone_domain.push_back(var->domainSize());
304 table_alone_offset.push_back(offset);
305 table_alone_domain_size *= var->domainSize();
308 var1offset.insert(var, offset);
309 offset *= var->domainSize();
312 std::vector< Idx > table_alone_value = table_alone_domain;
313 std::vector< Idx > table_alone_down = table_alone_offset;
315 for (
unsigned int i = 0; i < table_alone_down.size(); ++i)
316 table_alone_down[i] *= (table_alone_domain[i] - 1);
328 std::vector< Idx > table_and_result_offset;
329 std::vector< Idx > table_and_result_domain;
330 Idx result_domain_size = 1;
331 bool has_before_incr =
false;
332 bool found_proj_var =
false;
334 for (
const auto var: table_vars) {
335 if (!del_vars.exists(var)) {
336 table_and_result_domain.push_back(var->domainSize());
337 table_and_result_offset.push_back(var1offset[var]);
338 found_proj_var =
true;
339 result_domain_size *= var->domainSize();
340 result_varSeq << var;
342 if (found_proj_var) has_before_incr =
true;
346 std::vector< Idx > table_and_result_value = table_and_result_domain;
347 std::vector< Idx > table_and_result_down = table_and_result_offset;
349 for (
unsigned int i = 0; i < table_and_result_down.size(); ++i) {
350 table_and_result_down[i] *= (table_and_result_domain[i] - 1);
361 for (
const auto var: result_varSeq)
364 result->endMultipleChanges();
367# ifdef GUM_MULTI_DIM_PROJECTION_POINTER
369 for (
Idx i = 0; i < result_domain_size; ++i) {
370 result->unsafeSet(i,
new GUM_SCALAR(neutral_element));
374 result->fill(neutral_element);
392 if (!has_before_incr) {
393 Idx result_offset = 0;
397 for (
const auto var: table->variablesSequence())
398 table_inst.
add(*var);
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_POINTER
403 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
404 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
406 GUM_MULTI_DIM_PROJECTION_TYPE& res
407 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(result->unsafeGet(result_offset));
408 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
421 Idx result_offset = 0;
425 for (
const auto var: table->variablesSequence())
426 table_inst.
add(*var);
428 for (
Idx j = 0; j < result_domain_size; ++j) {
429 for (
Idx i = 0; i < table_alone_domain_size; ++i) {
430# ifdef GUM_MULTI_DIM_PROJECTION_POINTER
431 GUM_MULTI_DIM_PROJECTION_TYPE res = result->unsafeGet(result_offset);
432 *res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
434 GUM_MULTI_DIM_PROJECTION_TYPE& res
435 =
const_cast< GUM_MULTI_DIM_PROJECTION_TYPE&
>(result->unsafeGet(result_offset));
436 res = GUM_MULTI_DIM_PROJECTION(res, table->get(table_inst));
440 for (
unsigned int k = 0; k < table_alone_value.size(); ++k) {
441 --table_alone_value[k];
443 if (table_alone_value[k]) {
444 table_inst += table_alone_offset[k];
448 table_alone_value[k] = table_alone_domain[k];
449 table_inst -= table_alone_down[k];
454 for (
unsigned int k = 0; k < table_and_result_value.size(); ++k) {
455 --table_and_result_value[k];
457 if (table_and_result_value[k]) {
458 table_inst += table_and_result_offset[k];
462 table_and_result_value[k] = table_and_result_domain[k];
463 table_inst -= table_and_result_down[k];
475# undef GUM_MULTI_DIM_PROJECTION_TYPE
477# ifdef GUM_MULTI_DIM_PROJECTION_POINTER
478# undef GUM_MULTI_DIM_PROJECTION_POINTER
The class for generic Hash Tables.
Class for assigning/browsing values to tuples of discrete variables.
void add(const DiscreteVariable &v) final
Adds a new variable in the Instantiation.
Multidimensional matrix stored as an array in memory.
<agrum/base/multidim/multiDimImplementation.h>
void beginMultipleChanges() override
Call this method before doing important changes in this MultiDimContainer.
Size size() const noexcept
Returns the size of the sequence.
The generic class for storing (ordered) sequences of objects.
Size Idx
Type for indexes.
gum is the global namespace for all aGrUM entities
Set< const DiscreteVariable * > VariableSet