30 #ifndef GUM_OPERATOR_PATTERN_ALLOWED 41 # ifdef GUM_MULTI_DIM_OPERATOR_NAME 42 # define GUM_MULTI_DIM_OPERATOR_TYPE T 43 template <
typename T >
44 MultiDimArray< T >* GUM_MULTI_DIM_OPERATOR_NAME(
const MultiDimArray< T >* t1,
45 const MultiDimArray< T >* t2)
50 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME 51 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 53 MultiDimArray<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME(
54 const MultiDimArray<T*>* t1,
const MultiDimArray<T*>* t2 )
57 #ifdef GUM_MULTI_DIM_OPERATOR_NAME_F 58 #define GUM_MULTI_DIM_OPERATOR_TYPE T 60 MultiDimArray<T>* GUM_MULTI_DIM_OPERATOR_NAME_F(
61 const MultiDimArray<T>* t1,
62 const MultiDimArray<T>* t2,
63 const T ( *f )(
const T&,
const T& ) )
66 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F 67 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 69 MultiDimArray<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F(
70 const MultiDimArray<T*>* t1,
71 const MultiDimArray<T*>* t2,
72 const T* ( *f )(
const T*,
const T* ) )
75 #ifdef GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME 76 #define GUM_MULTI_DIM_OPERATOR_TYPE T 78 MultiDimImplementation<T>* GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME(
79 const MultiDimImplementation<T>* tt1,
80 const MultiDimImplementation<T>* tt2 )
83 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME 84 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 86 MultiDimImplementation<T*>*
87 GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME(
88 const MultiDimImplementation<T*>* tt1,
89 const MultiDimImplementation<T*>* tt2 )
96 # ifdef GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME 97 const MultiDimArray< T >* t1
98 =
reinterpret_cast<
const MultiDimArray< T >* >(tt1);
99 const MultiDimArray< T >* t2
100 =
reinterpret_cast<
const MultiDimArray< T >* >(tt2);
103 # ifdef GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME 104 const MultiDimArray< T* >* t1
105 =
reinterpret_cast<
const MultiDimArray< T* >* >(tt1);
106 const MultiDimArray< T* >* t2
107 =
reinterpret_cast<
const MultiDimArray< T* >* >(tt2);
111 const Sequence<
const DiscreteVariable* >& t1_vars = t1->variablesSequence();
112 const Sequence<
const DiscreteVariable* >& t2_vars = t2->variablesSequence();
115 HashTable<
const DiscreteVariable*, Idx > t1_offsets;
117 Idx current_offset = 1;
119 for (
const auto var: t1_vars) {
120 t1_offsets.insert(var, current_offset);
121 current_offset *= var->domainSize();
124 HashTable<
const DiscreteVariable*, Idx > t2_offsets;
126 Idx current_offset = 1;
128 for (
const auto var: t2_vars) {
129 t2_offsets.insert(var, current_offset);
130 current_offset *= var->domainSize();
144 std::vector< Idx > t1_alone_offset;
145 std::vector< Idx > t1_alone_domain;
146 Idx t1_alone_domain_size = 1;
148 std::vector< Idx > t2_alone_offset;
149 std::vector< Idx > t2_alone_domain;
150 Idx t2_alone_domain_size = 1;
152 std::vector< Idx > t1_and_t2_1_offset;
153 std::vector< Idx > t1_and_t2_2_offset;
154 std::vector< Idx > t1_and_t2_domain;
155 std::vector<
const DiscreteVariable* > t1_and_t2_vars;
156 Idx t1_and_t2_domain_size = 1;
159 for (
const auto var: t1_vars)
160 if (t2_vars.exists(var)) {
161 t1_and_t2_domain.push_back(var->domainSize());
162 t1_and_t2_1_offset.push_back(t1_offsets[var]);
163 t1_and_t2_2_offset.push_back(t2_offsets[var]);
164 t1_and_t2_vars.push_back(var);
165 t1_and_t2_domain_size *= var->domainSize();
167 t1_alone_domain.push_back(var->domainSize());
168 t1_alone_offset.push_back(t1_offsets[var]);
169 t1_alone_domain_size *= var->domainSize();
172 for (
const auto var: t2_vars)
173 if (!t1_vars.exists(var)) {
174 t2_alone_domain.push_back(var->domainSize());
175 t2_alone_offset.push_back(t2_offsets[var]);
176 t2_alone_domain_size *= var->domainSize();
183 bool t1_and_t2_begin_vars =
false;
185 if (t1_and_t2_vars.size()) {
186 unsigned int nb_t1_t2_vars = 0;
188 for (
auto iter = t1_vars.begin(); nb_t1_t2_vars != t1_and_t2_vars.size();
189 ++iter, ++nb_t1_t2_vars)
190 if (*iter != t1_and_t2_vars[nb_t1_t2_vars])
break;
192 if (nb_t1_t2_vars == t1_and_t2_vars.size()) {
195 for (
auto iter = t2_vars.begin(); nb_t1_t2_vars != t1_and_t2_vars.size();
196 ++iter, ++nb_t1_t2_vars)
197 if (*iter != t1_and_t2_vars[nb_t1_t2_vars])
break;
199 if (nb_t1_t2_vars == t1_and_t2_vars.size()) {
200 t1_and_t2_begin_vars =
true;
216 std::vector< Idx > t1_and_t2_value = t1_and_t2_domain;
217 std::vector< Idx > t1_and_t2_1_down = t1_and_t2_1_offset;
218 std::vector< Idx > t1_and_t2_2_down = t1_and_t2_2_offset;
220 for (
unsigned int i = 0; i < t1_and_t2_domain.size(); ++i) {
221 t1_and_t2_1_down[i] *= (t1_and_t2_domain[i] - 1);
222 t1_and_t2_2_down[i] *= (t1_and_t2_domain[i] - 1);
225 std::vector< Idx > t1_alone_value = t1_alone_domain;
226 std::vector< Idx > t1_alone_down = t1_alone_offset;
228 for (
unsigned int i = 0; i < t1_alone_domain.size(); ++i) {
229 t1_alone_down[i] *= (t1_alone_domain[i] - 1);
232 std::vector< Idx > t2_alone_value = t2_alone_domain;
233 std::vector< Idx > t2_alone_down = t2_alone_offset;
235 for (
unsigned int i = 0; i < t2_alone_domain.size(); ++i) {
236 t2_alone_down[i] *= (t2_alone_domain[i] - 1);
244 MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >* result
245 =
new MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >;
246 result->beginMultipleChanges();
248 for (
const auto var: t1_vars)
249 if (t2_vars.exists(var)) *result << *var;
251 for (
const auto var: t2_vars)
252 if (!t1_vars.exists(var)) *result << *var;
254 for (
const auto var: t1_vars)
255 if (!t2_vars.exists(var)) *result << *var;
257 result->endMultipleChanges();
263 GUM_MULTI_DIM_OPERATOR_TYPE* pt1
264 =
const_cast< GUM_MULTI_DIM_OPERATOR_TYPE* >(&(t1->unsafeGet(0)));
265 GUM_MULTI_DIM_OPERATOR_TYPE* pt2
266 =
const_cast< GUM_MULTI_DIM_OPERATOR_TYPE* >(&(t2->unsafeGet(0)));
267 GUM_MULTI_DIM_OPERATOR_TYPE* pres
268 =
const_cast< GUM_MULTI_DIM_OPERATOR_TYPE* >(&(result->unsafeGet(0)));
269 GUM_MULTI_DIM_OPERATOR_TYPE* pt2_deb = pt2;
270 GUM_MULTI_DIM_OPERATOR_TYPE* pt1_alone_begin;
275 if (t1_and_t2_begin_vars) {
276 for (Idx i = 0; i < t1_alone_domain_size; ++i) {
278 pt1_alone_begin = pt1;
280 for (Idx j = 0; j < t2_alone_domain_size; ++j) {
281 pt1 = pt1_alone_begin;
283 for (Idx z = 0; z < t1_and_t2_domain_size; ++z) {
284 *pres = GUM_MULTI_DIM_OPERATOR(*pt1, *pt2);
296 Idx t1_alone_begin_offset = 0;
298 for (Idx i = 0; i < t1_alone_domain_size; ++i) {
300 t1_alone_begin_offset = t1_offset;
302 for (Idx j = 0; j < t2_alone_domain_size; ++j) {
303 t1_offset = t1_alone_begin_offset;
305 for (Idx z = 0; z < t1_and_t2_domain_size; ++z) {
306 *pres = GUM_MULTI_DIM_OPERATOR(pt1[t1_offset], pt2[t2_offset]);
310 for (
unsigned int k = 0; k < t1_and_t2_value.size(); ++k) {
311 if (--t1_and_t2_value[k]) {
312 t1_offset += t1_and_t2_1_offset[k];
313 t2_offset += t1_and_t2_2_offset[k];
317 t1_and_t2_value[k] = t1_and_t2_domain[k];
318 t1_offset -= t1_and_t2_1_down[k];
319 t2_offset -= t1_and_t2_2_down[k];
324 for (
unsigned int k = 0; k < t2_alone_value.size(); ++k) {
325 if (--t2_alone_value[k]) {
326 t2_offset += t2_alone_offset[k];
330 t2_alone_value[k] = t2_alone_domain[k];
331 t2_offset -= t2_alone_down[k];
336 for (
unsigned int k = 0; k < t1_alone_value.size(); ++k) {
337 if (--t1_alone_value[k]) {
338 t1_offset += t1_alone_offset[k];
342 t1_alone_value[k] = t1_alone_domain[k];
343 t1_offset -= t1_alone_down[k];
351 # undef GUM_MULTI_DIM_OPERATOR_TYPE