30 #ifndef GUM_OPERATOR_PATTERN_ALLOWED 42 # ifdef GUM_MULTI_DIM_OPERATOR_NAME 43 # define GUM_MULTI_DIM_OPERATOR_TYPE T 44 template <
typename T >
45 MultiDimImplementation< T >*
46 GUM_MULTI_DIM_OPERATOR_NAME(
const MultiDimImplementation< T >* t1,
47 const MultiDimImplementation< T >* t2)
52 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME 53 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 55 MultiDimImplementation<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME(
56 const MultiDimImplementation<T*>* t1,
57 const MultiDimImplementation<T*>* t2 )
60 #ifdef GUM_MULTI_DIM_OPERATOR_NAME_F 61 #define GUM_MULTI_DIM_OPERATOR_TYPE T 63 MultiDimImplementation<T>* GUM_MULTI_DIM_OPERATOR_NAME_F(
64 const MultiDimImplementation<T>* t1,
65 const MultiDimImplementation<T>* t2,
66 const T ( *f )(
const T&,
const T& ) )
69 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F 70 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 72 MultiDimImplementation<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F(
73 const MultiDimImplementation<T*>* t1,
74 const MultiDimImplementation<T*>* t2,
75 const T ( *f )(
const T*,
const T* ) )
83 const Sequence<
const DiscreteVariable* >& t1_vars = t1->variablesSequence();
84 const Sequence<
const DiscreteVariable* >& t2_vars = t2->variablesSequence();
87 HashTable<
const DiscreteVariable*, Idx > t1_offsets;
89 Idx current_offset = 1;
91 for (
const auto var: t1_vars) {
92 t1_offsets.insert(var, current_offset);
93 current_offset *= var->domainSize();
96 HashTable<
const DiscreteVariable*, Idx > t2_offsets;
98 Idx current_offset = 1;
100 for (
const auto var: t2_vars) {
101 t2_offsets.insert(var, current_offset);
102 current_offset *= var->domainSize();
114 std::vector<
const DiscreteVariable* > t1_alone_var;
115 std::vector< Idx > t1_alone_domain;
116 Idx t1_alone_domain_size = 1;
118 std::vector<
const DiscreteVariable* > t2_alone_var;
119 std::vector< Idx > t2_alone_domain;
120 Idx t2_alone_domain_size = 1;
122 std::vector<
const DiscreteVariable* > t1_and_t2_var;
123 std::vector< Idx > t1_and_t2_domain;
124 Idx t1_and_t2_domain_size = 1;
127 for (
const auto var: t1_vars)
128 if (t2_vars.exists(var)) {
129 t1_and_t2_domain.push_back(var->domainSize());
130 t1_and_t2_var.push_back(var);
131 t1_and_t2_domain_size *= var->domainSize();
133 t1_alone_domain.push_back(var->domainSize());
134 t1_alone_var.push_back(var);
135 t1_alone_domain_size *= var->domainSize();
138 for (
const auto var: t2_vars)
139 if (!t1_vars.exists(var)) {
140 t2_alone_domain.push_back(var->domainSize());
141 t2_alone_var.push_back(var);
142 t2_alone_domain_size *= var->domainSize();
149 bool t1_and_t2_begin_vars =
false;
151 if (t1_and_t2_var.size()) {
152 unsigned int nb_t1_t2_vars = 0;
154 for (
const auto var: t1_vars) {
155 if (var != t1_and_t2_var[nb_t1_t2_vars])
break;
159 if (nb_t1_t2_vars == t1_and_t2_var.size()) {
162 for (
auto iter = t2_vars.begin(); nb_t1_t2_vars != t1_and_t2_var.size();
163 ++iter, ++nb_t1_t2_vars)
164 if (*iter != t1_and_t2_var[nb_t1_t2_vars])
break;
166 if (nb_t1_t2_vars == t1_and_t2_var.size()) t1_and_t2_begin_vars =
true;
178 std::vector< Idx > t1_and_t2_value = t1_and_t2_domain;
179 std::vector< Idx > t1_alone_value = t1_alone_domain;
180 std::vector< Idx > t2_alone_value = t2_alone_domain;
187 MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >* result
188 =
new MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >;
189 result->beginMultipleChanges();
191 for (
const auto var: t1_vars)
192 if (t2_vars.exists(var)) *result << *var;
194 for (
const auto var: t2_vars)
195 if (!t1_vars.exists(var)) *result << *var;
197 for (
const auto var: t1_vars)
198 if (!t2_vars.exists(var)) *result << *var;
200 result->endMultipleChanges();
206 Idx result_offset = 0;
207 Instantiation t2_inst(t2);
208 Instantiation t1_inst(t1);
209 Instantiation t1_alone_begin_inst(t1);
214 if (t1_and_t2_begin_vars) {
215 for (Idx i = 0; i < t1_alone_domain_size; ++i) {
217 t1_alone_begin_inst = t1_inst;
219 for (Idx j = 0; j < t2_alone_domain_size; ++j) {
220 t1_inst = t1_alone_begin_inst;
222 for (Idx z = 0; z < t1_and_t2_domain_size; ++z) {
225 GUM_MULTI_DIM_OPERATOR(t1->get(t1_inst), t2->get(t2_inst)));
236 for (Idx i = 0; i < t1_alone_domain_size; ++i) {
238 t1_alone_begin_inst = t1_inst;
240 for (Idx j = 0; j < t2_alone_domain_size; ++j) {
241 t1_inst = t1_alone_begin_inst;
243 for (Idx z = 0; z < t1_and_t2_domain_size; ++z) {
246 GUM_MULTI_DIM_OPERATOR(t1->get(t1_inst), t2->get(t2_inst)));
251 for (
unsigned int k = 0; k < t1_and_t2_value.size(); ++k) {
252 --t1_and_t2_value[k];
254 if (t1_and_t2_value[k]) {
255 t1_inst.incVar(*(t1_and_t2_var[k]));
256 t2_inst.incVar(*(t1_and_t2_var[k]));
260 t1_and_t2_value[k] = t1_and_t2_domain[k];
261 t1_inst.setFirstVar(*(t1_and_t2_var[k]));
262 t2_inst.setFirstVar(*(t1_and_t2_var[k]));
267 for (
unsigned int k = 0; k < t2_alone_value.size(); ++k) {
270 if (t2_alone_value[k]) {
271 t2_inst.incVar(*(t2_alone_var[k]));
275 t2_alone_value[k] = t2_alone_domain[k];
276 t2_inst.setFirstVar(*(t2_alone_var[k]));
281 for (
unsigned int k = 0; k < t1_alone_value.size(); ++k) {
284 if (t1_alone_value[k]) {
285 t1_inst.incVar(*(t1_alone_var[k]));
289 t1_alone_value[k] = t1_alone_domain[k];
290 t1_inst.setFirstVar(*(t1_alone_var[k]));
298 # undef GUM_MULTI_DIM_OPERATOR_TYPE