28 #ifndef GUM_OPERATOR_PATTERN_ALLOWED 39 # ifdef GUM_MULTI_DIM_OPERATOR_NAME 40 # define GUM_MULTI_DIM_OPERATOR_TYPE T 41 template <
typename T >
42 MultiDimArray< T >* GUM_MULTI_DIM_OPERATOR_NAME(
const MultiDimArray< T >* t1,
43 const MultiDimArray< T >* t2)
48 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME 49 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 51 MultiDimArray<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME(
52 const MultiDimArray<T*>* t1,
const MultiDimArray<T*>* t2 )
55 #ifdef GUM_MULTI_DIM_OPERATOR_NAME_F 56 #define GUM_MULTI_DIM_OPERATOR_TYPE T 58 MultiDimArray<T>* GUM_MULTI_DIM_OPERATOR_NAME_F(
59 const MultiDimArray<T>* t1,
60 const MultiDimArray<T>* t2,
61 const T ( *f )(
const T&,
const T& ) )
64 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F 65 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 67 MultiDimArray<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F(
68 const MultiDimArray<T*>* t1,
69 const MultiDimArray<T*>* t2,
70 const T* ( *f )(
const T*,
const T* ) )
73 #ifdef GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME 74 #define GUM_MULTI_DIM_OPERATOR_TYPE T 76 MultiDimImplementation<T>* GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME(
77 const MultiDimImplementation<T>* tt1,
78 const MultiDimImplementation<T>* tt2 )
81 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME 82 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 84 MultiDimImplementation<T*>*
85 GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME(
86 const MultiDimImplementation<T*>* tt1,
87 const MultiDimImplementation<T*>* tt2 )
94 # ifdef GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME 95 const MultiDimArray< T >* t1 =
96 reinterpret_cast< const MultiDimArray< T >*
>(tt1);
97 const MultiDimArray< T >* t2 =
98 reinterpret_cast< const MultiDimArray< T >*
>(tt2);
101 # ifdef GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME 102 const MultiDimArray< T* >* t1 =
103 reinterpret_cast< const MultiDimArray< T* >*
>(tt1);
104 const MultiDimArray< T* >* t2 =
105 reinterpret_cast< const MultiDimArray< T* >*
>(tt2);
109 const Sequence< const DiscreteVariable* >& t1_vars = t1->variablesSequence();
110 const Sequence< const DiscreteVariable* >& t2_vars = t2->variablesSequence();
113 HashTable< const DiscreteVariable*, Idx > t1_offsets;
115 Idx current_offset = 1;
117 for (
const auto var : t1_vars) {
118 t1_offsets.insert(var, current_offset);
119 current_offset *= var->domainSize();
122 HashTable< const DiscreteVariable*, Idx > t2_offsets;
124 Idx current_offset = 1;
126 for (
const auto var : t2_vars) {
127 t2_offsets.insert(var, current_offset);
128 current_offset *= var->domainSize();
142 std::vector< Idx > t1_alone_offset;
143 std::vector< Idx > t1_alone_domain;
144 Idx t1_alone_domain_size = 1;
146 std::vector< Idx > t2_alone_offset;
147 std::vector< Idx > t2_alone_domain;
148 Idx t2_alone_domain_size = 1;
150 std::vector< Idx > t1_and_t2_1_offset;
151 std::vector< Idx > t1_and_t2_2_offset;
152 std::vector< Idx > t1_and_t2_domain;
153 std::vector< const DiscreteVariable* > t1_and_t2_vars;
154 Idx t1_and_t2_domain_size = 1;
157 for (
const auto var : t1_vars)
158 if (t2_vars.exists(var)) {
159 t1_and_t2_domain.push_back(var->domainSize());
160 t1_and_t2_1_offset.push_back(t1_offsets[var]);
161 t1_and_t2_2_offset.push_back(t2_offsets[var]);
162 t1_and_t2_vars.push_back(var);
163 t1_and_t2_domain_size *= var->domainSize();
165 t1_alone_domain.push_back(var->domainSize());
166 t1_alone_offset.push_back(t1_offsets[var]);
167 t1_alone_domain_size *= var->domainSize();
170 for (
const auto var : t2_vars)
171 if (!t1_vars.exists(var)) {
172 t2_alone_domain.push_back(var->domainSize());
173 t2_alone_offset.push_back(t2_offsets[var]);
174 t2_alone_domain_size *= var->domainSize();
181 bool t1_and_t2_begin_vars =
false;
183 if (t1_and_t2_vars.size()) {
184 unsigned int nb_t1_t2_vars = 0;
186 for (
auto iter = t1_vars.begin(); nb_t1_t2_vars != t1_and_t2_vars.size();
187 ++iter, ++nb_t1_t2_vars)
188 if (*iter != t1_and_t2_vars[nb_t1_t2_vars])
break;
190 if (nb_t1_t2_vars == t1_and_t2_vars.size()) {
193 for (
auto iter = t2_vars.begin(); nb_t1_t2_vars != t1_and_t2_vars.size();
194 ++iter, ++nb_t1_t2_vars)
195 if (*iter != t1_and_t2_vars[nb_t1_t2_vars])
break;
197 if (nb_t1_t2_vars == t1_and_t2_vars.size()) {
198 t1_and_t2_begin_vars =
true;
214 std::vector< Idx > t1_and_t2_value = t1_and_t2_domain;
215 std::vector< Idx > t1_and_t2_1_down = t1_and_t2_1_offset;
216 std::vector< Idx > t1_and_t2_2_down = t1_and_t2_2_offset;
218 for (
unsigned int i = 0; i < t1_and_t2_domain.size(); ++i) {
219 t1_and_t2_1_down[i] *= (t1_and_t2_domain[i] - 1);
220 t1_and_t2_2_down[i] *= (t1_and_t2_domain[i] - 1);
223 std::vector< Idx > t1_alone_value = t1_alone_domain;
224 std::vector< Idx > t1_alone_down = t1_alone_offset;
226 for (
unsigned int i = 0; i < t1_alone_domain.size(); ++i) {
227 t1_alone_down[i] *= (t1_alone_domain[i] - 1);
230 std::vector< Idx > t2_alone_value = t2_alone_domain;
231 std::vector< Idx > t2_alone_down = t2_alone_offset;
233 for (
unsigned int i = 0; i < t2_alone_domain.size(); ++i) {
234 t2_alone_down[i] *= (t2_alone_domain[i] - 1);
242 MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >* result =
243 new MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >;
244 result->beginMultipleChanges();
246 for (
const auto var : t1_vars)
247 if (t2_vars.exists(var)) *result << *var;
249 for (
const auto var : t2_vars)
250 if (!t1_vars.exists(var)) *result << *var;
252 for (
const auto var : t1_vars)
253 if (!t2_vars.exists(var)) *result << *var;
255 result->endMultipleChanges();
261 GUM_MULTI_DIM_OPERATOR_TYPE* pt1 =
262 const_cast< GUM_MULTI_DIM_OPERATOR_TYPE*
>(&(t1->unsafeGet(0)));
263 GUM_MULTI_DIM_OPERATOR_TYPE* pt2 =
264 const_cast< GUM_MULTI_DIM_OPERATOR_TYPE*
>(&(t2->unsafeGet(0)));
265 GUM_MULTI_DIM_OPERATOR_TYPE* pres =
266 const_cast< GUM_MULTI_DIM_OPERATOR_TYPE*
>(&(result->unsafeGet(0)));
267 GUM_MULTI_DIM_OPERATOR_TYPE* pt2_deb = pt2;
268 GUM_MULTI_DIM_OPERATOR_TYPE* pt1_alone_begin;
273 if (t1_and_t2_begin_vars) {
274 for (
Idx i = 0; i < t1_alone_domain_size; ++i) {
276 pt1_alone_begin = pt1;
278 for (
Idx j = 0; j < t2_alone_domain_size; ++j) {
279 pt1 = pt1_alone_begin;
281 for (
Idx z = 0; z < t1_and_t2_domain_size; ++z) {
282 *pres = GUM_MULTI_DIM_OPERATOR(*pt1, *pt2);
294 Idx t1_alone_begin_offset = 0;
296 for (
Idx i = 0; i < t1_alone_domain_size; ++i) {
298 t1_alone_begin_offset = t1_offset;
300 for (
Idx j = 0; j < t2_alone_domain_size; ++j) {
301 t1_offset = t1_alone_begin_offset;
303 for (
Idx z = 0; z < t1_and_t2_domain_size; ++z) {
304 *pres = GUM_MULTI_DIM_OPERATOR(pt1[t1_offset], pt2[t2_offset]);
308 for (
unsigned int k = 0; k < t1_and_t2_value.size(); ++k) {
309 if (--t1_and_t2_value[k]) {
310 t1_offset += t1_and_t2_1_offset[k];
311 t2_offset += t1_and_t2_2_offset[k];
315 t1_and_t2_value[k] = t1_and_t2_domain[k];
316 t1_offset -= t1_and_t2_1_down[k];
317 t2_offset -= t1_and_t2_2_down[k];
322 for (
unsigned int k = 0; k < t2_alone_value.size(); ++k) {
323 if (--t2_alone_value[k]) {
324 t2_offset += t2_alone_offset[k];
328 t2_alone_value[k] = t2_alone_domain[k];
329 t2_offset -= t2_alone_down[k];
334 for (
unsigned int k = 0; k < t1_alone_value.size(); ++k) {
335 if (--t1_alone_value[k]) {
336 t1_offset += t1_alone_offset[k];
340 t1_alone_value[k] = t1_alone_domain[k];
341 t1_offset -= t1_alone_down[k];
349 # undef GUM_MULTI_DIM_OPERATOR_TYPE gum is the global namespace for all aGrUM entities