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;
104 iter != seq1.endSafe();
106 size *= (*iter)->domainSize();
111 iter != seq2.endSafe();
113 if (!seq1.exists(*iter)) size *= (*iter)->domainSize();
120 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
122 TABLE< GUM_SCALAR >& container,
123 const Set<
const TABLE< GUM_SCALAR >* >&
set) {
124 TABLE< GUM_SCALAR >* res =
combine(
set);
130 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
132 const Set<
const TABLE< GUM_SCALAR >* >&
set) {
134 if (
set.size() < 2) {
136 "the set passed to a MultiDimCombinationDefault" 137 " should at least contain two elements");
141 std::vector< const TABLE< GUM_SCALAR >* > tables(
set.size());
146 for (
typename Set<
const TABLE< GUM_SCALAR >* >::const_iterator_safe iter =
148 iter !=
set.endSafe();
158 std::vector< bool > is_t_new(tables.size(),
false);
163 std::pair< unsigned int, unsigned int > pair;
165 PriorityQueue< std::pair< unsigned int, unsigned int >,
Size > queue;
167 for (
unsigned int i = 0; i < tables.size(); ++i) {
169 const Sequence< const DiscreteVariable* >& seq1 =
170 tables[i]->variablesSequence();
172 for (
unsigned int j = i + 1; j < tables.size(); ++j) {
174 queue.insert(pair,
_combinedSize(seq1, tables[j]->variablesSequence()));
183 for (
unsigned int k = 1; k < tables.size(); ++k) {
186 unsigned int ti = pair.first;
187 unsigned int tj = pair.second;
189 TABLE< GUM_SCALAR >* result =
_combine(*(tables[ti]), *(tables[tj]));
193 if (tables[ti] && is_t_new[ti])
delete tables[ti];
195 if (tables[tj] && is_t_new[tj])
delete tables[tj];
204 for (
unsigned int ind = 0; ind < tj; ++ind) {
213 for (
unsigned int ind = tj + 1; ind < tables.size(); ++ind) {
222 const Sequence< const DiscreteVariable* >& seq1 =
223 tables[ti]->variablesSequence();
227 for (
unsigned int ind = 0; ind < ti; ++ind) {
230 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
231 queue.setPriority(pair, newsize);
237 for (
unsigned int ind = ti + 1; ind < tables.size(); ++ind) {
240 newsize =
_combinedSize(seq1, tables[ind]->variablesSequence());
241 queue.setPriority(pair, newsize);
254 return const_cast< TABLE< GUM_SCALAR >*
>(tables[k]);
258 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
260 const Set<
const Sequence< const DiscreteVariable* >* >&
set)
const {
262 if (
set.size() < 2)
return 0.0f;
267 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
272 for (
typename Set<
const Sequence< const DiscreteVariable* >* >::
273 const_iterator_safe iter =
set.beginSafe();
274 iter !=
set.endSafe();
284 std::vector< bool > is_t_new(tables.size(),
false);
289 std::pair< unsigned int, unsigned int > pair;
291 PriorityQueue< std::pair< unsigned int, unsigned int >,
Size > queue;
293 for (
unsigned int i = 0; i < tables.size(); ++i) {
296 for (
unsigned int j = i + 1; j < tables.size(); ++j) {
298 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
307 for (
unsigned int k = 1; k < tables.size(); ++k) {
310 unsigned int ti = pair.first;
311 unsigned int tj = pair.second;
314 Sequence< const DiscreteVariable* >* new_seq =
315 new Sequence< const DiscreteVariable* >;
316 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
317 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
323 iter != seq1.endSafe();
325 new_size *= (*iter)->domainSize();
326 new_seq->insert(*iter);
331 iter != seq2.endSafe();
333 if (!seq1.exists(*iter)) {
334 new_size *= (*iter)->domainSize();
335 new_seq->insert(*iter);
343 if (tables[ti] && is_t_new[ti])
delete tables[ti];
345 if (tables[tj] && is_t_new[tj])
delete tables[tj];
347 tables[ti] = new_seq;
354 for (
unsigned int ind = 0; ind < tj; ++ind) {
363 for (
unsigned int ind = tj + 1; ind < tables.size(); ++ind) {
375 for (
unsigned int ind = 0; ind < ti; ++ind) {
379 queue.setPriority(pair, newsize);
385 for (
unsigned int ind = ti + 1; ind < tables.size(); ++ind) {
389 queue.setPriority(pair, newsize);
408 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
410 const Set<
const TABLE< GUM_SCALAR >* >&
set)
const {
412 if (
set.size() < 2)
return 0.0f;
415 Set< const Sequence< const DiscreteVariable* >* > var_set(
set.size());
417 for (
typename Set<
const TABLE< GUM_SCALAR >* >::const_iterator_safe iter =
419 iter !=
set.endSafe();
421 var_set << &((*iter)->variablesSequence());
428 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
429 std::pair< long, long >
431 const Set<
const Sequence< const DiscreteVariable* >* >&
set)
const {
433 if (
set.size() < 2)
return std::pair< long, long >(0, 0);
437 Size current_memory = 0;
440 std::vector< const Sequence< const DiscreteVariable* >* > tables(
set.size());
442 std::vector< Size > table_size(
set.size());
445 std::size_t i = std::size_t(0);
447 for (
typename Set<
const Sequence< const DiscreteVariable* >* >::
448 const_iterator_safe iter =
set.beginSafe();
449 iter !=
set.endSafe();
451 const Sequence< const DiscreteVariable* >* vars = *iter;
457 iter2 = vars->beginSafe();
458 iter2 != vars->endSafe();
460 size *= (*iter2)->domainSize();
463 table_size[i] = size;
471 std::vector< bool > is_t_new(tables.size(),
false);
476 std::pair< unsigned int, unsigned int > pair;
478 PriorityQueue< std::pair< unsigned int, unsigned int >,
Size > queue;
480 for (
unsigned int i = 0; i < tables.size(); ++i) {
483 for (
unsigned int j = i + 1; j < tables.size(); ++j) {
485 queue.insert(pair,
_combinedSize(*(tables[i]), *(tables[j])));
494 for (
unsigned int k = 1; k < tables.size(); ++k) {
497 unsigned int ti = pair.first;
498 unsigned int tj = pair.second;
501 Sequence< const DiscreteVariable* >* new_seq =
502 new Sequence< const DiscreteVariable* >;
503 const Sequence< const DiscreteVariable* >& seq1 = *(tables[ti]);
504 const Sequence< const DiscreteVariable* >& seq2 = *(tables[tj]);
510 iter != seq1.endSafe();
512 if (std::numeric_limits< Size >::max() / (*iter)->domainSize()
514 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
517 new_size *= (*iter)->domainSize();
519 new_seq->insert(*iter);
524 iter != seq2.endSafe();
526 if (!seq1.exists(*iter)) {
527 if (std::numeric_limits< Size >::max() / (*iter)->domainSize()
529 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
532 new_size *= (*iter)->domainSize();
534 new_seq->insert(*iter);
538 if (std::numeric_limits< Size >::max() - current_memory < new_size) {
539 GUM_ERROR(OutOfBounds,
"memory usage out of long int range");
542 current_memory += new_size;
544 if (current_memory > max_memory) { max_memory = current_memory; }
547 if (tables[ti] && is_t_new[ti]) {
549 current_memory -= table_size[ti];
552 if (tables[tj] && is_t_new[tj]) {
554 current_memory -= table_size[tj];
557 tables[ti] = new_seq;
559 table_size[ti] = new_size;
565 for (
unsigned int ind = 0; ind < tj; ++ind) {
574 for (
unsigned int ind = tj + 1; ind < tables.size(); ++ind) {
586 for (
unsigned int ind = 0; ind < ti; ++ind) {
590 queue.setPriority(pair, newsize);
596 for (
unsigned int ind = ti + 1; ind < tables.size(); ++ind) {
600 queue.setPriority(pair, newsize);
615 return std::pair< long, long >(long(max_memory), long(current_memory));
619 template <
typename GUM_SCALAR,
template <
typename >
class TABLE >
620 std::pair< long, long >
622 const Set<
const TABLE< GUM_SCALAR >* >&
set)
const {
624 if (
set.size() < 2)
return std::pair< long, long >(0, 0);
627 Set< const Sequence< const DiscreteVariable* >* > var_set(
set.size());
629 for (
typename Set<
const TABLE< GUM_SCALAR >* >::const_iterator_safe iter =
631 iter !=
set.endSafe();
633 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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
virtual MultiDimCombinationDefault< GUM_SCALAR, TABLE > * newFactory() const
virtual constructor
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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.