31 #ifndef GUM_OPERATOR_PATTERN_ALLOWED 43 # ifdef GUM_MULTI_DIM_OPERATOR_NAME 44 # define GUM_MULTI_DIM_OPERATOR_TYPE T 45 template <
typename T >
46 MultiDimImplementation< T >*
47 GUM_MULTI_DIM_OPERATOR_NAME(
const MultiDimImplementation< T >* t1,
48 const MultiDimImplementation< T >* t2)
53 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME 54 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 56 MultiDimImplementation<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME(
57 const MultiDimImplementation<T*>* t1,
58 const MultiDimImplementation<T*>* t2 )
61 #ifdef GUM_MULTI_DIM_OPERATOR_NAME_F 62 #define GUM_MULTI_DIM_OPERATOR_TYPE T 64 MultiDimImplementation<T>* GUM_MULTI_DIM_OPERATOR_NAME_F(
65 const MultiDimImplementation<T>* t1,
66 const MultiDimImplementation<T>* t2,
67 const T ( *f )(
const T&,
const T& ) )
70 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F 71 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 73 MultiDimImplementation<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F(
74 const MultiDimImplementation<T*>* t1,
75 const MultiDimImplementation<T*>* t2,
76 const T ( *f )(
const T*,
const T* ) )
84 const Sequence< const DiscreteVariable* >& t1_vars = t1->variablesSequence();
85 const Sequence< const DiscreteVariable* >& t2_vars = t2->variablesSequence();
88 HashTable< const DiscreteVariable*, Idx > t1_offsets;
90 Idx current_offset = 1;
92 for (
const auto var : t1_vars) {
93 t1_offsets.insert(var, current_offset);
94 current_offset *= var->domainSize();
97 HashTable< const DiscreteVariable*, Idx > t2_offsets;
99 Idx current_offset = 1;
101 for (
const auto var : t2_vars) {
102 t2_offsets.insert(var, current_offset);
103 current_offset *= var->domainSize();
115 std::vector< const DiscreteVariable* > t1_alone_var;
116 std::vector< Idx > t1_alone_domain;
117 Idx t1_alone_domain_size = 1;
119 std::vector< const DiscreteVariable* > t2_alone_var;
120 std::vector< Idx > t2_alone_domain;
121 Idx t2_alone_domain_size = 1;
123 std::vector< const DiscreteVariable* > t1_and_t2_var;
124 std::vector< Idx > t1_and_t2_domain;
125 Idx t1_and_t2_domain_size = 1;
128 for (
const auto var : t1_vars)
129 if (t2_vars.exists(var)) {
130 t1_and_t2_domain.push_back(var->domainSize());
131 t1_and_t2_var.push_back(var);
132 t1_and_t2_domain_size *= var->domainSize();
134 t1_alone_domain.push_back(var->domainSize());
135 t1_alone_var.push_back(var);
136 t1_alone_domain_size *= var->domainSize();
139 for (
const auto var : t2_vars)
140 if (!t1_vars.exists(var)) {
141 t2_alone_domain.push_back(var->domainSize());
142 t2_alone_var.push_back(var);
143 t2_alone_domain_size *= var->domainSize();
150 bool t1_and_t2_begin_vars =
false;
152 if (t1_and_t2_var.size()) {
153 unsigned int nb_t1_t2_vars = 0;
155 for (
const auto var : t1_vars) {
156 if (var != t1_and_t2_var[nb_t1_t2_vars])
break;
160 if (nb_t1_t2_vars == t1_and_t2_var.size()) {
163 for (
auto iter = t2_vars.begin(); nb_t1_t2_vars != t1_and_t2_var.size();
164 ++iter, ++nb_t1_t2_vars)
165 if (*iter != t1_and_t2_var[nb_t1_t2_vars])
break;
167 if (nb_t1_t2_vars == t1_and_t2_var.size()) t1_and_t2_begin_vars =
true;
179 std::vector< Idx > t1_and_t2_value = t1_and_t2_domain;
180 std::vector< Idx > t1_alone_value = t1_alone_domain;
181 std::vector< Idx > t2_alone_value = t2_alone_domain;
188 MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >* result =
189 new MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >;
190 result->beginMultipleChanges();
192 for (
const auto var : t1_vars)
193 if (t2_vars.exists(var)) *result << *var;
195 for (
const auto var : t2_vars)
196 if (!t1_vars.exists(var)) *result << *var;
198 for (
const auto var : t1_vars)
199 if (!t2_vars.exists(var)) *result << *var;
201 result->endMultipleChanges();
207 Idx result_offset = 0;
208 Instantiation t2_inst(t2);
209 Instantiation t1_inst(t1);
210 Instantiation t1_alone_begin_inst(t1);
215 if (t1_and_t2_begin_vars) {
216 for (
Idx i = 0; i < t1_alone_domain_size; ++i) {
218 t1_alone_begin_inst = t1_inst;
220 for (
Idx j = 0; j < t2_alone_domain_size; ++j) {
221 t1_inst = t1_alone_begin_inst;
223 for (
Idx z = 0; z < t1_and_t2_domain_size; ++z) {
226 GUM_MULTI_DIM_OPERATOR(t1->get(t1_inst), t2->get(t2_inst)));
237 for (
Idx i = 0; i < t1_alone_domain_size; ++i) {
239 t1_alone_begin_inst = t1_inst;
241 for (
Idx j = 0; j < t2_alone_domain_size; ++j) {
242 t1_inst = t1_alone_begin_inst;
244 for (
Idx z = 0; z < t1_and_t2_domain_size; ++z) {
247 GUM_MULTI_DIM_OPERATOR(t1->get(t1_inst), t2->get(t2_inst)));
252 for (
unsigned int k = 0; k < t1_and_t2_value.size(); ++k) {
253 --t1_and_t2_value[k];
255 if (t1_and_t2_value[k]) {
256 t1_inst.incVar(*(t1_and_t2_var[k]));
257 t2_inst.incVar(*(t1_and_t2_var[k]));
261 t1_and_t2_value[k] = t1_and_t2_domain[k];
262 t1_inst.setFirstVar(*(t1_and_t2_var[k]));
263 t2_inst.setFirstVar(*(t1_and_t2_var[k]));
268 for (
unsigned int k = 0; k < t2_alone_value.size(); ++k) {
271 if (t2_alone_value[k]) {
272 t2_inst.incVar(*(t2_alone_var[k]));
276 t2_alone_value[k] = t2_alone_domain[k];
277 t2_inst.setFirstVar(*(t2_alone_var[k]));
282 for (
unsigned int k = 0; k < t1_alone_value.size(); ++k) {
285 if (t1_alone_value[k]) {
286 t1_inst.incVar(*(t1_alone_var[k]));
290 t1_alone_value[k] = t1_alone_domain[k];
291 t1_inst.setFirstVar(*(t1_alone_var[k]));
299 # undef GUM_MULTI_DIM_OPERATOR_TYPE Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.