31 #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 MultiDimArray< T >* GUM_MULTI_DIM_OPERATOR_NAME(
const MultiDimArray< T >* t1,
46 const MultiDimArray< T >* t2)
51 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME 52 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 54 MultiDimArray<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME(
55 const MultiDimArray<T*>* t1,
const MultiDimArray<T*>* t2 )
58 #ifdef GUM_MULTI_DIM_OPERATOR_NAME_F 59 #define GUM_MULTI_DIM_OPERATOR_TYPE T 61 MultiDimArray<T>* GUM_MULTI_DIM_OPERATOR_NAME_F(
62 const MultiDimArray<T>* t1,
63 const MultiDimArray<T>* t2,
64 const T ( *f )(
const T&,
const T& ) )
67 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F 68 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 70 MultiDimArray<T*>* GUM_MULTI_DIM_OPERATOR_POINTER_NAME_F(
71 const MultiDimArray<T*>* t1,
72 const MultiDimArray<T*>* t2,
73 const T* ( *f )(
const T*,
const T* ) )
76 #ifdef GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME 77 #define GUM_MULTI_DIM_OPERATOR_TYPE T 79 MultiDimImplementation<T>* GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME(
80 const MultiDimImplementation<T>* tt1,
81 const MultiDimImplementation<T>* tt2 )
84 #ifdef GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME 85 #define GUM_MULTI_DIM_OPERATOR_TYPE T * 87 MultiDimImplementation<T*>*
88 GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME(
89 const MultiDimImplementation<T*>* tt1,
90 const MultiDimImplementation<T*>* tt2 )
97 # ifdef GUM_MULTI_DIM_OPERATOR_IMPL2ARRAY_NAME 98 const MultiDimArray< T >* t1 =
99 reinterpret_cast< const MultiDimArray< T >*
>(tt1);
100 const MultiDimArray< T >* t2 =
101 reinterpret_cast< const MultiDimArray< T >*
>(tt2);
104 # ifdef GUM_MULTI_DIM_OPERATOR_POINTER_IMPL2ARRAY_NAME 105 const MultiDimArray< T* >* t1 =
106 reinterpret_cast< const MultiDimArray< T* >*
>(tt1);
107 const MultiDimArray< T* >* t2 =
108 reinterpret_cast< const MultiDimArray< T* >*
>(tt2);
112 const Sequence< const DiscreteVariable* >& t1_vars = t1->variablesSequence();
113 const Sequence< const DiscreteVariable* >& t2_vars = t2->variablesSequence();
116 HashTable< const DiscreteVariable*, Idx > t1_offsets;
118 Idx current_offset = 1;
120 for (
const auto var : t1_vars) {
121 t1_offsets.insert(var, current_offset);
122 current_offset *= var->domainSize();
125 HashTable< const DiscreteVariable*, Idx > t2_offsets;
127 Idx current_offset = 1;
129 for (
const auto var : t2_vars) {
130 t2_offsets.insert(var, current_offset);
131 current_offset *= var->domainSize();
145 std::vector< Idx > t1_alone_offset;
146 std::vector< Idx > t1_alone_domain;
147 Idx t1_alone_domain_size = 1;
149 std::vector< Idx > t2_alone_offset;
150 std::vector< Idx > t2_alone_domain;
151 Idx t2_alone_domain_size = 1;
153 std::vector< Idx > t1_and_t2_1_offset;
154 std::vector< Idx > t1_and_t2_2_offset;
155 std::vector< Idx > t1_and_t2_domain;
156 std::vector< const DiscreteVariable* > t1_and_t2_vars;
157 Idx t1_and_t2_domain_size = 1;
160 for (
const auto var : t1_vars)
161 if (t2_vars.exists(var)) {
162 t1_and_t2_domain.push_back(var->domainSize());
163 t1_and_t2_1_offset.push_back(t1_offsets[var]);
164 t1_and_t2_2_offset.push_back(t2_offsets[var]);
165 t1_and_t2_vars.push_back(var);
166 t1_and_t2_domain_size *= var->domainSize();
168 t1_alone_domain.push_back(var->domainSize());
169 t1_alone_offset.push_back(t1_offsets[var]);
170 t1_alone_domain_size *= var->domainSize();
173 for (
const auto var : t2_vars)
174 if (!t1_vars.exists(var)) {
175 t2_alone_domain.push_back(var->domainSize());
176 t2_alone_offset.push_back(t2_offsets[var]);
177 t2_alone_domain_size *= var->domainSize();
184 bool t1_and_t2_begin_vars =
false;
186 if (t1_and_t2_vars.size()) {
187 unsigned int nb_t1_t2_vars = 0;
189 for (
auto iter = t1_vars.begin(); nb_t1_t2_vars != t1_and_t2_vars.size();
190 ++iter, ++nb_t1_t2_vars)
191 if (*iter != t1_and_t2_vars[nb_t1_t2_vars])
break;
193 if (nb_t1_t2_vars == t1_and_t2_vars.size()) {
196 for (
auto iter = t2_vars.begin(); nb_t1_t2_vars != t1_and_t2_vars.size();
197 ++iter, ++nb_t1_t2_vars)
198 if (*iter != t1_and_t2_vars[nb_t1_t2_vars])
break;
200 if (nb_t1_t2_vars == t1_and_t2_vars.size()) {
201 t1_and_t2_begin_vars =
true;
217 std::vector< Idx > t1_and_t2_value = t1_and_t2_domain;
218 std::vector< Idx > t1_and_t2_1_down = t1_and_t2_1_offset;
219 std::vector< Idx > t1_and_t2_2_down = t1_and_t2_2_offset;
221 for (
unsigned int i = 0; i < t1_and_t2_domain.size(); ++i) {
222 t1_and_t2_1_down[i] *= (t1_and_t2_domain[i] - 1);
223 t1_and_t2_2_down[i] *= (t1_and_t2_domain[i] - 1);
226 std::vector< Idx > t1_alone_value = t1_alone_domain;
227 std::vector< Idx > t1_alone_down = t1_alone_offset;
229 for (
unsigned int i = 0; i < t1_alone_domain.size(); ++i) {
230 t1_alone_down[i] *= (t1_alone_domain[i] - 1);
233 std::vector< Idx > t2_alone_value = t2_alone_domain;
234 std::vector< Idx > t2_alone_down = t2_alone_offset;
236 for (
unsigned int i = 0; i < t2_alone_domain.size(); ++i) {
237 t2_alone_down[i] *= (t2_alone_domain[i] - 1);
245 MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >* result =
246 new MultiDimArray< GUM_MULTI_DIM_OPERATOR_TYPE >;
247 result->beginMultipleChanges();
249 for (
const auto var : t1_vars)
250 if (t2_vars.exists(var)) *result << *var;
252 for (
const auto var : t2_vars)
253 if (!t1_vars.exists(var)) *result << *var;
255 for (
const auto var : t1_vars)
256 if (!t2_vars.exists(var)) *result << *var;
258 result->endMultipleChanges();
264 GUM_MULTI_DIM_OPERATOR_TYPE* pt1 =
265 const_cast< GUM_MULTI_DIM_OPERATOR_TYPE*
>(&(t1->unsafeGet(0)));
266 GUM_MULTI_DIM_OPERATOR_TYPE* pt2 =
267 const_cast< GUM_MULTI_DIM_OPERATOR_TYPE*
>(&(t2->unsafeGet(0)));
268 GUM_MULTI_DIM_OPERATOR_TYPE* pres =
269 const_cast< GUM_MULTI_DIM_OPERATOR_TYPE*
>(&(result->unsafeGet(0)));
270 GUM_MULTI_DIM_OPERATOR_TYPE* pt2_deb = pt2;
271 GUM_MULTI_DIM_OPERATOR_TYPE* pt1_alone_begin;
276 if (t1_and_t2_begin_vars) {
277 for (
Idx i = 0; i < t1_alone_domain_size; ++i) {
279 pt1_alone_begin = pt1;
281 for (
Idx j = 0; j < t2_alone_domain_size; ++j) {
282 pt1 = pt1_alone_begin;
284 for (
Idx z = 0; z < t1_and_t2_domain_size; ++z) {
285 *pres = GUM_MULTI_DIM_OPERATOR(*pt1, *pt2);
297 Idx t1_alone_begin_offset = 0;
299 for (
Idx i = 0; i < t1_alone_domain_size; ++i) {
301 t1_alone_begin_offset = t1_offset;
303 for (
Idx j = 0; j < t2_alone_domain_size; ++j) {
304 t1_offset = t1_alone_begin_offset;
306 for (
Idx z = 0; z < t1_and_t2_domain_size; ++z) {
307 *pres = GUM_MULTI_DIM_OPERATOR(pt1[t1_offset], pt2[t2_offset]);
311 for (
unsigned int k = 0; k < t1_and_t2_value.size(); ++k) {
312 if (--t1_and_t2_value[k]) {
313 t1_offset += t1_and_t2_1_offset[k];
314 t2_offset += t1_and_t2_2_offset[k];
318 t1_and_t2_value[k] = t1_and_t2_domain[k];
319 t1_offset -= t1_and_t2_1_down[k];
320 t2_offset -= t1_and_t2_2_down[k];
325 for (
unsigned int k = 0; k < t2_alone_value.size(); ++k) {
326 if (--t2_alone_value[k]) {
327 t2_offset += t2_alone_offset[k];
331 t2_alone_value[k] = t2_alone_domain[k];
332 t2_offset -= t2_alone_down[k];
337 for (
unsigned int k = 0; k < t1_alone_value.size(); ++k) {
338 if (--t1_alone_value[k]) {
339 t1_offset += t1_alone_offset[k];
343 t1_alone_value[k] = t1_alone_domain[k];
344 t1_offset -= t1_alone_down[k];
352 # undef GUM_MULTI_DIM_OPERATOR_TYPE Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.