27 #ifndef DOXYGEN_SHOULD_SKIP_THIS 39 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
41 TABLE< GUM_SCALAR >* (*combine)(
const TABLE< GUM_SCALAR >&,
42 const TABLE< GUM_SCALAR >&)) :
43 MultiDimCombination< GUM_SCALAR, TABLE >(),
50 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
52 const MultiDimCombinationDefault< GUM_SCALAR, TABLE >& from) :
60 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
67 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
68 MultiDimCombinationDefault< GUM_SCALAR, TABLE >*
70 return new MultiDimCombinationDefault< GUM_SCALAR, TABLE >(
_combine);
74 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
76 TABLE< GUM_SCALAR >* (*
combine)(
const TABLE< GUM_SCALAR >&,
77 const TABLE< GUM_SCALAR >&)) {
82 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
83 INLINE TABLE< GUM_SCALAR >* (
85 const TABLE< GUM_SCALAR >&,
const TABLE< GUM_SCALAR >&) {
91 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
93 const Sequence< const DiscreteVariable* >& seq1,
94 const Sequence< const DiscreteVariable* >& seq2)
const {
95 if (seq1.empty() && seq2.empty())
return 0;
101 iter != seq1.endSafe();
103 size *= (*iter)->domainSize();
108 iter != seq2.endSafe();
110 if (!seq1.exists(*iter)) size *= (*iter)->domainSize();
117 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
119 TABLE< GUM_SCALAR >& container,
120 const Set<
const TABLE< GUM_SCALAR >* >&
set) {
121 TABLE< GUM_SCALAR >* res =
combine(
set);
127 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
129 const Set<
const TABLE< GUM_SCALAR >* >&
set) {
131 if (
set.size() < 2) {
133 "the set passed to a MultiDimCombinationDefault" 134 " should at least contain two elements");
138 std::vector< const TABLE< GUM_SCALAR >* > tables(
set.size());
143 for (
typename Set<
const TABLE< GUM_SCALAR >* >::const_iterator_safe iter =
145 iter !=
set.endSafe();
155 std::vector< bool > is_t_new(tables.size(),
false);
160 std::pair< unsigned int, unsigned int > pair;
162 PriorityQueue< std::pair< unsigned int, unsigned int >,
Size > queue;
164 for (
unsigned int i = 0; i < tables.size(); ++i) {
166 const Sequence< const DiscreteVariable* >& seq1 =
167 tables[i]->variablesSequence();
169 for (
unsigned int j = i + 1; j < tables.size(); ++j) {
171 queue.insert(pair,
_combinedSize(seq1, tables[j]->variablesSequence()));
180 for (
unsigned int k = 1; k < tables.size(); ++k) {
183 unsigned int ti = pair.first;
184 unsigned int tj = pair.second;
186 TABLE< GUM_SCALAR >* result =
_combine(*(tables[ti]), *(tables[tj]));
190 if (tables[ti] && is_t_new[ti])
delete tables[ti];
192 if (tables[tj] && is_t_new[tj])
delete tables[tj];
201 for (
unsigned int ind = 0; ind < tj; ++ind) {
210 for (
unsigned int ind = tj + 1; ind < tables.size(); ++ind) {
219 const Sequence< const DiscreteVariable* >& seq1 =
220 tables[ti]->variablesSequence();
224 for (
unsigned int ind = 0; ind < ti; ++ind) {
227 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
228 queue.setPriority(pair, newsize);
234 for (
unsigned int ind = ti + 1; ind < tables.size(); ++ind) {
237 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
238 queue.setPriority(pair, newsize);
251 return const_cast< TABLE< GUM_SCALAR >*
>(tables[k]);
255 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
257 const Set<
const Sequence< const DiscreteVariable* >* >&
set)
const {
259 if (
set.size() < 2)
return 0.0f;
264 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
269 for (
typename Set<
const Sequence< const DiscreteVariable* >* >::
270 const_iterator_safe iter =
set.beginSafe();
271 iter !=
set.endSafe();
281 std::vector< bool > is_t_new(tables.size(),
false);
286 std::pair< unsigned int, unsigned int > pair;
288 PriorityQueue< std::pair< unsigned int, unsigned int >,
Size > queue;
290 for (
unsigned int i = 0; i < tables.size(); ++i) {
293 for (
unsigned int j = i + 1; j < tables.size(); ++j) {
295 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
304 for (
unsigned int k = 1; k < tables.size(); ++k) {
307 unsigned int ti = pair.first;
308 unsigned int tj = pair.second;
311 Sequence< const DiscreteVariable* >* new_seq =
312 new Sequence< const DiscreteVariable* >;
313 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
314 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
320 iter != seq1.endSafe();
322 new_size *= (*iter)->domainSize();
323 new_seq->insert(*iter);
328 iter != seq2.endSafe();
330 if (!seq1.exists(*iter)) {
331 new_size *= (*iter)->domainSize();
332 new_seq->insert(*iter);
340 if (tables[ti] && is_t_new[ti])
delete tables[ti];
342 if (tables[tj] && is_t_new[tj])
delete tables[tj];
344 tables[ti] = new_seq;
351 for (
unsigned int ind = 0; ind < tj; ++ind) {
360 for (
unsigned int ind = tj + 1; ind < tables.size(); ++ind) {
372 for (
unsigned int ind = 0; ind < ti; ++ind) {
376 queue.setPriority(pair, newsize);
382 for (
unsigned int ind = ti + 1; ind < tables.size(); ++ind) {
386 queue.setPriority(pair, newsize);
405 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
407 const Set<
const TABLE< GUM_SCALAR >* >&
set)
const {
409 if (
set.size() < 2)
return 0.0f;
412 Set< const Sequence< const DiscreteVariable* >* > var_set(
set.size());
414 for (
typename Set<
const TABLE< GUM_SCALAR >* >::const_iterator_safe iter =
416 iter !=
set.endSafe();
418 var_set << &((*iter)->variablesSequence());
425 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
426 std::pair< long, long >
428 const Set<
const Sequence< const DiscreteVariable* >* >&
set)
const {
430 if (
set.size() < 2)
return std::pair< long, long >(0, 0);
434 Size current_memory = 0;
437 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
439 std::vector< Size > table_size(
set.size());
442 std::size_t i = std::size_t(0);
444 for (
typename Set<
const Sequence< const DiscreteVariable* >* >::
445 const_iterator_safe iter =
set.beginSafe();
446 iter !=
set.endSafe();
448 const Sequence< const DiscreteVariable* >* vars = *iter;
454 iter2 = vars->beginSafe();
455 iter2 != vars->endSafe();
457 size *= (*iter2)->domainSize();
460 table_size[i] = size;
468 std::vector< bool > is_t_new(tables.size(),
false);
473 std::pair< unsigned int, unsigned int > pair;
475 PriorityQueue< std::pair< unsigned int, unsigned int >,
Size > queue;
477 for (
unsigned int i = 0; i < tables.size(); ++i) {
480 for (
unsigned int j = i + 1; j < tables.size(); ++j) {
482 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
491 for (
unsigned int k = 1; k < tables.size(); ++k) {
494 unsigned int ti = pair.first;
495 unsigned int tj = pair.second;
498 Sequence< const DiscreteVariable* >* new_seq =
499 new Sequence< const DiscreteVariable* >;
500 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
501 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
507 iter != seq1.endSafe();
509 if (std::numeric_limits< Size >::max() / (*iter)->domainSize()
511 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
514 new_size *= (*iter)->domainSize();
516 new_seq->insert(*iter);
521 iter != seq2.endSafe();
523 if (!seq1.exists(*iter)) {
524 if (std::numeric_limits< Size >::max() / (*iter)->domainSize()
526 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
529 new_size *= (*iter)->domainSize();
531 new_seq->insert(*iter);
535 if (std::numeric_limits< Size >::max() - current_memory < new_size) {
536 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
539 current_memory += new_size;
541 if (current_memory > max_memory) { max_memory = current_memory; }
544 if (tables[ti] && is_t_new[ti]) {
546 current_memory -= table_size[ti];
549 if (tables[tj] && is_t_new[tj]) {
551 current_memory -= table_size[tj];
554 tables[ti] = new_seq;
556 table_size[ti] = new_size;
562 for (
unsigned int ind = 0; ind < tj; ++ind) {
571 for (
unsigned int ind = tj + 1; ind < tables.size(); ++ind) {
583 for (
unsigned int ind = 0; ind < ti; ++ind) {
587 queue.setPriority(pair, newsize);
593 for (
unsigned int ind = ti + 1; ind < tables.size(); ++ind) {
597 queue.setPriority(pair, newsize);
612 return std::pair< long, long >(long(max_memory), long(current_memory));
616 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
617 std::pair< long, long >
619 const Set<
const TABLE< GUM_SCALAR >* >&
set)
const {
621 if (
set.size() < 2)
return std::pair< long, long >(0, 0);
624 Set< const Sequence< const DiscreteVariable* >* > var_set(
set.size());
626 for (
typename Set<
const TABLE< GUM_SCALAR >* >::const_iterator_safe iter =
628 iter !=
set.endSafe();
630 var_set << &((*iter)->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.
gum is the global namespace for all aGrUM entities
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...
virtual MultiDimCombinationDefault< GUM_SCALAR, TABLE > * newFactory() const
virtual constructor
priority queues (in which an element cannot appear more than once)
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)
SequenceIteratorSafe< Key > const_iterator_safe
Types for STL compliance.