50#ifndef GUM_OPERATOR_PATTERN_ALLOWED
62# ifdef GUM_MULTI_DIM_OPERATOR_NAME
63# define GUM_MULTI_DIM_OPERATOR_TYPE T
65 template <
typename T >
72#ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME
73#define GUM_MULTI_DIM_OPERATOR_TYPE T *
80#ifdef GUM_MULTI_DIM_OPERATOR_NAME_F
81#define GUM_MULTI_DIM_OPERATOR_TYPE T
86 const T ( *f )(
const T&,
const T& ) )
89#ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F
90#define GUM_MULTI_DIM_OPERATOR_TYPE T *
95 const T ( *f )(
const T*,
const T* ) )
109 Idx current_offset = 1;
111 for (
const auto var: t1_vars) {
112 t1_offsets.insert(var, current_offset);
113 current_offset *= var->domainSize();
118 Idx current_offset = 1;
120 for (
const auto var: t2_vars) {
121 t2_offsets.insert(var, current_offset);
122 current_offset *= var->domainSize();
134 std::vector< const DiscreteVariable* > t1_alone_var;
135 std::vector< Idx > t1_alone_domain;
136 Idx t1_alone_domain_size = 1;
138 std::vector< const DiscreteVariable* > t2_alone_var;
139 std::vector< Idx > t2_alone_domain;
140 Idx t2_alone_domain_size = 1;
142 std::vector< const DiscreteVariable* > t1_and_t2_var;
143 std::vector< Idx > t1_and_t2_domain;
144 Idx t1_and_t2_domain_size = 1;
147 for (
const auto var: t1_vars)
148 if (t2_vars.exists(var)) {
149 t1_and_t2_domain.push_back(var->domainSize());
150 t1_and_t2_var.push_back(var);
151 t1_and_t2_domain_size *= var->domainSize();
153 t1_alone_domain.push_back(var->domainSize());
154 t1_alone_var.push_back(var);
155 t1_alone_domain_size *= var->domainSize();
158 for (
const auto var: t2_vars)
159 if (!t1_vars.exists(var)) {
160 t2_alone_domain.push_back(var->domainSize());
161 t2_alone_var.push_back(var);
162 t2_alone_domain_size *= var->domainSize();
169 bool t1_and_t2_begin_vars =
false;
171 if (t1_and_t2_var.size()) {
172 unsigned int nb_t1_t2_vars = 0;
174 for (
const auto var: t1_vars) {
175 if (var != t1_and_t2_var[nb_t1_t2_vars])
break;
179 if (nb_t1_t2_vars == t1_and_t2_var.size()) {
182 for (
auto iter = t2_vars.begin(); nb_t1_t2_vars != t1_and_t2_var.size();
183 ++iter, ++nb_t1_t2_vars)
184 if (*iter != t1_and_t2_var[nb_t1_t2_vars])
break;
186 if (nb_t1_t2_vars == t1_and_t2_var.size()) t1_and_t2_begin_vars =
true;
198 std::vector< Idx > t1_and_t2_value = t1_and_t2_domain;
199 std::vector< Idx > t1_alone_value = t1_alone_domain;
200 std::vector< Idx > t2_alone_value = t2_alone_domain;
211 for (
const auto var: t1_vars)
212 if (t2_vars.exists(var)) *result << *var;
214 for (
const auto var: t2_vars)
215 if (!t1_vars.exists(var)) *result << *var;
217 for (
const auto var: t1_vars)
218 if (!t2_vars.exists(var)) *result << *var;
220 result->endMultipleChanges();
226 Idx result_offset = 0;
235 for (
const auto var: t2_vars)
237 for (
const auto var: t1_vars)
239 for (
const auto var: t1_vars)
240 t1_alone_begin_inst.add(*var);
245 if (t1_and_t2_begin_vars) {
246 for (
Idx i = 0; i < t1_alone_domain_size; ++i) {
248 t1_alone_begin_inst = t1_inst;
250 for (
Idx j = 0; j < t2_alone_domain_size; ++j) {
251 t1_inst = t1_alone_begin_inst;
253 for (
Idx z = 0; z < t1_and_t2_domain_size; ++z) {
254 result->unsafeSet(result_offset,
255 GUM_MULTI_DIM_OPERATOR(t1->get(t1_inst), t2->get(t2_inst)));
266 for (
Idx i = 0; i < t1_alone_domain_size; ++i) {
268 t1_alone_begin_inst = t1_inst;
270 for (
Idx j = 0; j < t2_alone_domain_size; ++j) {
271 t1_inst = t1_alone_begin_inst;
273 for (
Idx z = 0; z < t1_and_t2_domain_size; ++z) {
274 result->unsafeSet(result_offset,
275 GUM_MULTI_DIM_OPERATOR(t1->get(t1_inst), t2->get(t2_inst)));
280 for (
unsigned int k = 0; k < t1_and_t2_value.size(); ++k) {
281 --t1_and_t2_value[k];
283 if (t1_and_t2_value[k]) {
284 t1_inst.incVar(*(t1_and_t2_var[k]));
285 t2_inst.incVar(*(t1_and_t2_var[k]));
289 t1_and_t2_value[k] = t1_and_t2_domain[k];
290 t1_inst.setFirstVar(*(t1_and_t2_var[k]));
291 t2_inst.setFirstVar(*(t1_and_t2_var[k]));
296 for (
unsigned int k = 0; k < t2_alone_value.size(); ++k) {
299 if (t2_alone_value[k]) {
300 t2_inst.incVar(*(t2_alone_var[k]));
304 t2_alone_value[k] = t2_alone_domain[k];
305 t2_inst.setFirstVar(*(t2_alone_var[k]));
310 for (
unsigned int k = 0; k < t1_alone_value.size(); ++k) {
313 if (t1_alone_value[k]) {
314 t1_inst.incVar(*(t1_alone_var[k]));
318 t1_alone_value[k] = t1_alone_domain[k];
319 t1_inst.setFirstVar(*(t1_alone_var[k]));
327# undef GUM_MULTI_DIM_OPERATOR_TYPE
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.
The generic class for storing (ordered) sequences of objects.
Size Idx
Type for indexes.
gum is the global namespace for all aGrUM entities