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 =
reinterpret_cast<
const MultiDimArray< T >* >(tt1);
98 const MultiDimArray< T >* t2 =
reinterpret_cast<
const MultiDimArray< T >* >(tt2);
101 # ifdef GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME 102 const MultiDimArray< T* >* t1 =
reinterpret_cast<
const MultiDimArray< T* >* >(tt1);
103 const MultiDimArray< T* >* t2 =
reinterpret_cast<
const MultiDimArray< T* >* >(tt2);
107 const Sequence<
const DiscreteVariable* >& t1_vars = t1->variablesSequence();
108 const Sequence<
const DiscreteVariable* >& t2_vars = t2->variablesSequence();
111 HashTable<
const DiscreteVariable*, Idx > t1_offsets;
113 Idx current_offset = 1;
115 for (
const auto var: t1_vars) {
116 t1_offsets.insert(var, current_offset);
117 current_offset *= var->domainSize();
120 HashTable<
const DiscreteVariable*, Idx > t2_offsets;
122 Idx current_offset = 1;
124 for (
const auto var: t2_vars) {
125 t2_offsets.insert(var, current_offset);
126 current_offset *= var->domainSize();
140 std::vector< Idx > t1_alone_offset;
141 std::vector< Idx > t1_alone_domain;
142 Idx t1_alone_domain_size = 1;
144 std::vector< Idx > t2_alone_offset;
145 std::vector< Idx > t2_alone_domain;
146 Idx t2_alone_domain_size = 1;
148 std::vector< Idx > t1_and_t2_1_offset;
149 std::vector< Idx > t1_and_t2_2_offset;
150 std::vector< Idx > t1_and_t2_domain;
151 std::vector<
const DiscreteVariable* > t1_and_t2_vars;
152 Idx t1_and_t2_domain_size = 1;
155 for (
const auto var: t1_vars)
156 if (t2_vars.exists(var)) {
157 t1_and_t2_domain.push_back(var->domainSize());
158 t1_and_t2_1_offset.push_back(t1_offsets[var]);
159 t1_and_t2_2_offset.push_back(t2_offsets[var]);
160 t1_and_t2_vars.push_back(var);
161 t1_and_t2_domain_size *= var->domainSize();
163 t1_alone_domain.push_back(var->domainSize());
164 t1_alone_offset.push_back(t1_offsets[var]);
165 t1_alone_domain_size *= var->domainSize();
168 for (
const auto var: t2_vars)
169 if (!t1_vars.exists(var)) {
170 t2_alone_domain.push_back(var->domainSize());
171 t2_alone_offset.push_back(t2_offsets[var]);
172 t2_alone_domain_size *= var->domainSize();
179 bool t1_and_t2_begin_vars =
false;
181 if (t1_and_t2_vars.size()) {
182 unsigned int nb_t1_t2_vars = 0;
184 for (
auto iter = t1_vars.begin(); nb_t1_t2_vars != t1_and_t2_vars.size();
185 ++iter, ++nb_t1_t2_vars)
186 if (*iter != t1_and_t2_vars[nb_t1_t2_vars])
break;
188 if (nb_t1_t2_vars == t1_and_t2_vars.size()) {
191 for (
auto iter = t2_vars.begin(); nb_t1_t2_vars != t1_and_t2_vars.size();
192 ++iter, ++nb_t1_t2_vars)
193 if (*iter != t1_and_t2_vars[nb_t1_t2_vars])
break;
195 if (nb_t1_t2_vars == t1_and_t2_vars.size()) { t1_and_t2_begin_vars =
true; }
210 std::vector< Idx > t1_and_t2_value = t1_and_t2_domain;
211 std::vector< Idx > t1_and_t2_1_down = t1_and_t2_1_offset;
212 std::vector< Idx > t1_and_t2_2_down = t1_and_t2_2_offset;
214 for (
unsigned int i = 0; i < t1_and_t2_domain.size(); ++i) {
215 t1_and_t2_1_down[i] *= (t1_and_t2_domain[i] - 1);
216 t1_and_t2_2_down[i] *= (t1_and_t2_domain[i] - 1);
219 std::vector< Idx > t1_alone_value = t1_alone_domain;
220 std::vector< Idx > t1_alone_down = t1_alone_offset;
222 for (
unsigned int i = 0; i < t1_alone_domain.size(); ++i) {
223 t1_alone_down[i] *= (t1_alone_domain[i] - 1);
226 std::vector< Idx > t2_alone_value = t2_alone_domain;
227 std::vector< Idx > t2_alone_down = t2_alone_offset;
229 for (
unsigned int i = 0; i < t2_alone_domain.size(); ++i) {
230 t2_alone_down[i] *= (t2_alone_domain[i] - 1);
238 MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >* result
239 =
new MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >;
240 result->beginMultipleChanges();
242 for (
const auto var: t1_vars)
243 if (t2_vars.exists(var)) *result << *var;
245 for (
const auto var: t2_vars)
246 if (!t1_vars.exists(var)) *result << *var;
248 for (
const auto var: t1_vars)
249 if (!t2_vars.exists(var)) *result << *var;
251 result->endMultipleChanges();
257 GUM_MULTI_DIM_OPERATOR_TYPE* pt1
258 =
const_cast< GUM_MULTI_DIM_OPERATOR_TYPE* >(&(t1->unsafeGet(0)));
259 GUM_MULTI_DIM_OPERATOR_TYPE* pt2
260 =
const_cast< GUM_MULTI_DIM_OPERATOR_TYPE* >(&(t2->unsafeGet(0)));
261 GUM_MULTI_DIM_OPERATOR_TYPE* pres
262 =
const_cast< GUM_MULTI_DIM_OPERATOR_TYPE* >(&(result->unsafeGet(0)));
263 GUM_MULTI_DIM_OPERATOR_TYPE* pt2_deb = pt2;
264 GUM_MULTI_DIM_OPERATOR_TYPE* pt1_alone_begin;
269 if (t1_and_t2_begin_vars) {
270 for (Idx i = 0; i < t1_alone_domain_size; ++i) {
272 pt1_alone_begin = pt1;
274 for (Idx j = 0; j < t2_alone_domain_size; ++j) {
275 pt1 = pt1_alone_begin;
277 for (Idx z = 0; z < t1_and_t2_domain_size; ++z) {
278 *pres = GUM_MULTI_DIM_OPERATOR(*pt1, *pt2);
290 Idx t1_alone_begin_offset = 0;
292 for (Idx i = 0; i < t1_alone_domain_size; ++i) {
294 t1_alone_begin_offset = t1_offset;
296 for (Idx j = 0; j < t2_alone_domain_size; ++j) {
297 t1_offset = t1_alone_begin_offset;
299 for (Idx z = 0; z < t1_and_t2_domain_size; ++z) {
300 *pres = GUM_MULTI_DIM_OPERATOR(pt1[t1_offset], pt2[t2_offset]);
304 for (
unsigned int k = 0; k < t1_and_t2_value.size(); ++k) {
305 if (--t1_and_t2_value[k]) {
306 t1_offset += t1_and_t2_1_offset[k];
307 t2_offset += t1_and_t2_2_offset[k];
311 t1_and_t2_value[k] = t1_and_t2_domain[k];
312 t1_offset -= t1_and_t2_1_down[k];
313 t2_offset -= t1_and_t2_2_down[k];
318 for (
unsigned int k = 0; k < t2_alone_value.size(); ++k) {
319 if (--t2_alone_value[k]) {
320 t2_offset += t2_alone_offset[k];
324 t2_alone_value[k] = t2_alone_domain[k];
325 t2_offset -= t2_alone_down[k];
330 for (
unsigned int k = 0; k < t1_alone_value.size(); ++k) {
331 if (--t1_alone_value[k]) {
332 t1_offset += t1_alone_offset[k];
336 t1_alone_value[k] = t1_alone_domain[k];
337 t1_offset -= t1_alone_down[k];
345 # undef GUM_MULTI_DIM_OPERATOR_TYPE