30 #ifndef DOXYGEN_SHOULD_SKIP_THIS 42 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
44 TABLE< GUM_SCALAR >* (*combine)(
const TABLE< GUM_SCALAR >&,
45 const TABLE< GUM_SCALAR >&)) :
46 MultiDimCombination< GUM_SCALAR, TABLE >(),
53 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
55 const MultiDimCombinationDefault< GUM_SCALAR, TABLE >& from) :
63 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
70 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
71 MultiDimCombinationDefault< GUM_SCALAR, TABLE >*
73 return new MultiDimCombinationDefault< GUM_SCALAR, TABLE >(
_combine);
77 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
79 TABLE< GUM_SCALAR >* (*
combine)(
const TABLE< GUM_SCALAR >&,
80 const TABLE< GUM_SCALAR >&)) {
85 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
86 INLINE TABLE< GUM_SCALAR >* (
88 const TABLE< GUM_SCALAR >&,
const TABLE< GUM_SCALAR >&) {
94 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
96 const Sequence< const DiscreteVariable* >& seq1,
97 const Sequence< const DiscreteVariable* >& seq2)
const {
98 if (seq1.empty() && seq2.empty())
return 0;
102 for (
const auto ptrVar : seq1)
103 size *= ptrVar->domainSize();
105 for (
const auto ptrVar : seq2)
106 if (!seq1.exists(ptrVar)) size *= ptrVar->domainSize();
112 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
114 TABLE< GUM_SCALAR >& container,
115 const Set<
const TABLE< GUM_SCALAR >* >&
set) {
116 TABLE< GUM_SCALAR >* res =
combine(
set);
117 container = std::move(*res);
122 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
124 const Set<
const TABLE< GUM_SCALAR >* >&
set) {
126 if (
set.size() < 2) {
128 "the set passed to a MultiDimCombinationDefault" 129 " should at least contain two elements");
133 std::vector< const TABLE< GUM_SCALAR >* > tables(
set.size());
134 const Size tabsize = tables.size();
138 for (
auto iter =
set.cbegin(); iter !=
set.cend(); ++iter, ++i) {
146 std::vector< bool > is_t_new(tabsize,
false);
151 std::pair< Size, Size > pair;
152 PriorityQueue< std::pair< Size, Size >,
Size > queue;
154 for (
Size i =
Size(0); i < tabsize; ++i) {
156 const Sequence< const DiscreteVariable* >& seq1 =
157 tables[i]->variablesSequence();
159 for (
Size j = i + 1; j < tabsize; ++j) {
161 queue.insert(pair,
_combinedSize(seq1, tables[j]->variablesSequence()));
169 for (
Size k = 1; k < tabsize; ++k) {
172 const Size ti = pair.first;
173 const Size tj = pair.second;
175 TABLE< GUM_SCALAR >* result =
_combine(*(tables[ti]), *(tables[tj]));
178 if (tables[ti] && is_t_new[ti])
delete tables[ti];
179 if (tables[tj] && is_t_new[tj])
delete tables[tj];
184 tables[tj] =
nullptr;
187 for (
Size ind = 0; ind < tj; ++ind) {
188 if (tables[ind] !=
nullptr) {
195 for (
Size ind = tj + 1; ind < tabsize; ++ind) {
196 if (tables[ind] !=
nullptr) {
204 const Sequence< const DiscreteVariable* >& seq1 =
205 tables[ti]->variablesSequence();
209 for (
Size ind = 0; ind < ti; ++ind) {
210 if (tables[ind] !=
nullptr) {
212 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
213 queue.setPriority(pair, newsize);
219 for (
Size ind = ti + 1; ind < tabsize; ++ind) {
220 if (tables[ind] !=
nullptr) {
222 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
223 queue.setPriority(pair, newsize);
232 while (tables[k] ==
nullptr)
235 return const_cast< TABLE< GUM_SCALAR >*
>(tables[k]);
239 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
241 const Set<
const Sequence< const DiscreteVariable* >* >&
set)
const {
243 if (
set.size() < 2)
return 0.0f;
248 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
249 const Size tabsize = tables.size();
253 for (
auto iter =
set.cbegin(); iter !=
set.cend(); ++iter, ++i) {
262 std::vector< bool > is_t_new(tabsize,
false);
267 std::pair< Size, Size > pair;
268 PriorityQueue< std::pair< Size, Size >,
Size > queue;
270 for (
Size i =
Size(0); i < tabsize; ++i) {
273 for (
Size j = i + 1; j < tabsize; ++j) {
275 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
283 for (
Size k = 1; k < tabsize; ++k) {
286 const Size ti = pair.first;
287 const Size tj = pair.second;
290 Sequence< const DiscreteVariable* >* new_seq =
291 new Sequence< const DiscreteVariable* >;
292 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
293 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
297 for (
const auto ptrVar : seq1) {
298 new_size *= ptrVar->domainSize();
299 new_seq->insert(ptrVar);
302 for (
const auto ptrVar : seq2) {
303 if (!seq1.exists(ptrVar)) {
304 new_size *= ptrVar->domainSize();
305 new_seq->insert(ptrVar);
312 if (tables[ti] && is_t_new[ti])
delete tables[ti];
313 if (tables[tj] && is_t_new[tj])
delete tables[tj];
315 tables[ti] = new_seq;
318 tables[tj] =
nullptr;
321 for (
Size ind = 0; ind < tj; ++ind) {
322 if (tables[ind] !=
nullptr) {
330 for (
Size ind = tj + 1; ind < tabsize; ++ind) {
331 if (tables[ind] !=
nullptr) {
342 for (
Size ind = 0; ind < ti; ++ind) {
343 if (tables[ind] !=
nullptr) {
346 queue.setPriority(pair, newsize);
352 for (
Size ind = ti + 1; ind < tabsize; ++ind) {
353 if (tables[ind] !=
nullptr) {
356 queue.setPriority(pair, newsize);
365 while (tables[k] ==
nullptr)
374 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
376 const Set<
const TABLE< GUM_SCALAR >* >&
set)
const {
378 if (
set.size() < 2)
return 0.0f;
381 Set< const Sequence< const DiscreteVariable* >* > var_set(
set.size());
383 for (
const auto ptrTab :
set) {
384 var_set << &(ptrTab->variablesSequence());
391 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
392 std::pair< long, long >
394 const Set<
const Sequence< const DiscreteVariable* >* >&
set)
const {
396 if (
set.size() < 2)
return std::pair< long, long >(0, 0);
399 Size current_memory = 0;
402 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
403 const Size tabsize = tables.size();
405 std::vector< Size > table_size(
set.size());
410 for (
auto iter =
set.cbegin(); iter !=
set.cend(); ++iter, ++i) {
411 const Sequence< const DiscreteVariable* >* vars = *iter;
415 for (
const auto ptrVar : *vars) {
416 size *= ptrVar->domainSize();
419 table_size[i] = size;
427 std::vector< bool > is_t_new(tables.size(),
false);
432 std::pair< Size, Size > pair;
434 PriorityQueue< std::pair< Size, Size >,
Size > queue;
436 for (
Size i =
Size(0); i < tabsize; ++i) {
439 for (
Size j = i + 1; j < tabsize; ++j) {
441 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
449 for (
Size k = 1; k < tabsize; ++k) {
452 const Size ti = pair.first;
453 const Size tj = pair.second;
456 Sequence< const DiscreteVariable* >* new_seq =
457 new Sequence< const DiscreteVariable* >;
458 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
459 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
463 for (
const auto ptrVar : seq1) {
464 if (std::numeric_limits< Size >::max() / ptrVar->domainSize()
466 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
469 new_size *= ptrVar->domainSize();
471 new_seq->insert(ptrVar);
474 for (
const auto ptrVar : seq2) {
475 if (!seq1.exists(ptrVar)) {
476 if (std::numeric_limits< Size >::max() / ptrVar->domainSize()
478 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
481 new_size *= ptrVar->domainSize();
483 new_seq->insert(ptrVar);
487 if (std::numeric_limits< Size >::max() - current_memory < new_size) {
488 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
491 current_memory += new_size;
493 if (current_memory > max_memory) { max_memory = current_memory; }
496 if (tables[ti] && is_t_new[ti]) {
498 current_memory -= table_size[ti];
501 if (tables[tj] && is_t_new[tj]) {
503 current_memory -= table_size[tj];
506 tables[ti] = new_seq;
507 table_size[ti] = new_size;
510 tables[tj] =
nullptr;
513 for (
Size ind = 0; ind < tj; ++ind) {
514 if (tables[ind] !=
nullptr) {
522 for (
Size ind = tj + 1; ind < tabsize; ++ind) {
523 if (tables[ind] !=
nullptr) {
534 for (
Size ind =
Size(0); ind < ti; ++ind) {
535 if (tables[ind] !=
nullptr) {
538 queue.setPriority(pair, newsize);
544 for (
Size ind = ti + 1; ind < tabsize; ++ind) {
545 if (tables[ind] !=
nullptr) {
548 queue.setPriority(pair, newsize);
562 return std::pair< long, long >(long(max_memory), long(current_memory));
566 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
567 std::pair< long, long >
569 const Set<
const TABLE< GUM_SCALAR >* >&
set)
const {
571 if (
set.size() < 2)
return std::pair< long, long >(0, 0);
574 Set< const Sequence< const DiscreteVariable* >* > var_set(
set.size());
576 for (
const auto ptrTab :
set) {
577 var_set << &(ptrTab->variablesSequence());
virtual std::pair< long, long > memoryUsage(const Set< const TABLE< GUM_SCALAR > * > &set) const
Returns the additional memory consumption used during the combination.
MultiDimCombination()
default constructor
virtual TABLE< GUM_SCALAR > *(*)(const TABLE< GUM_SCALAR > &, const TABLE< GUM_SCALAR > &) combineFunction()
Returns the combination function currently used by the combinator.
virtual void setCombineFunction(TABLE< GUM_SCALAR > *(*combine)(const TABLE< GUM_SCALAR > &, const TABLE< GUM_SCALAR > &))
Changes the function used for combining two TABLES.
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
TABLE< GUM_SCALAR > *(* _combine)(const TABLE< GUM_SCALAR > &t1, const TABLE< GUM_SCALAR > &t2)
The function used to combine two tables.
virtual float nbOperations(const Set< const TABLE< GUM_SCALAR > * > &set) const
returns a rough estimate of the number of operations that will be performed to compute the combinatio...
Size _combinedSize(const Sequence< const DiscreteVariable * > &seq1, const Sequence< const DiscreteVariable * > &seq2) const
returns the domain size of the Cartesian product of the union of all the variables in seq1 and seq2...
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
virtual MultiDimCombinationDefault< GUM_SCALAR, TABLE > * newFactory() const
virtual constructor
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
MultiDimCombinationDefault(TABLE< GUM_SCALAR > *(*combine)(const TABLE< GUM_SCALAR > &, const TABLE< GUM_SCALAR > &))
Default constructor.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
virtual ~MultiDimCombinationDefault()
Destructor.
virtual TABLE< GUM_SCALAR > * combine(const Set< const TABLE< GUM_SCALAR > * > &set)
Creates and returns the result of the combination of the tables within set.
#define GUM_ERROR(type, msg)