aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
multiDimCombineAndProjectDefault_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief An efficient class for combining and projecting MultiDim tables
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
31 # include <limits>
32 
33 # include <agrum/agrum.h>
34 
35 # include <agrum/tools/multidim/utils/operators/multiDimCombineAndProjectDefault.h>
36 
37 namespace gum {
38 
39  // default constructor
40  template < typename GUM_SCALAR, template < typename > class TABLE >
41  MultiDimCombineAndProjectDefault< GUM_SCALAR, TABLE >::
42  MultiDimCombineAndProjectDefault(
43  TABLE< GUM_SCALAR >* (*combine)(const TABLE< GUM_SCALAR >&,
44  const TABLE< GUM_SCALAR >&),
45  TABLE< GUM_SCALAR >* (*project)(const TABLE< GUM_SCALAR >&,
46  const Set< const DiscreteVariable* >&)) :
47  MultiDimCombineAndProject< GUM_SCALAR, TABLE >(),
48  combination__(new MultiDimCombinationDefault< GUM_SCALAR, TABLE >(combine)),
49  projection__(new MultiDimProjection< GUM_SCALAR, TABLE >(project)) {
50  // for debugging purposes
51  GUM_CONSTRUCTOR(MultiDimCombineAndProjectDefault);
52  }
53 
54  // copy constructor
55  template < typename GUM_SCALAR, template < typename > class TABLE >
62  // for debugging purposes
64  }
65 
66  // destructor
67  template < typename GUM_SCALAR, template < typename > class TABLE >
70  // for debugging purposes
72  delete combination__;
73  delete projection__;
74  }
75 
76  // virtual constructor
77  template < typename GUM_SCALAR, template < typename > class TABLE >
81  }
82 
83  // combine and project
84  template < typename GUM_SCALAR, template < typename > class TABLE >
85  Set< const TABLE< GUM_SCALAR >* >
87  Set< const TABLE< GUM_SCALAR >* > table_set,
88  Set< const DiscreteVariable* > del_vars) {
89  // when we remove a variable, we need to combine all the tables containing
90  // this variable in order to produce a new unique table containing this
91  // variable. Removing the variable is then performed by marginalizing it
92  // out of the table. In the combineAndProject algorithm, we wish to remove
93  // first variables that produce small tables. This should speed up the
94  // marginalizing process
95  Size nb_vars;
96  {
97  // determine the set of all the variables involved in the tables.
98  // this should help sizing correctly the hashtables
99  Set< const DiscreteVariable* > all_vars;
100 
101  for (const auto ptrTab: table_set) {
102  for (const auto ptrVar: ptrTab->variablesSequence()) {
104  }
105  }
106 
107  nb_vars = all_vars.size();
108  }
109 
110  // the tables containing a given variable to be deleted
111  HashTable< const DiscreteVariable*, Set< const TABLE< GUM_SCALAR >* > >
113 
114  // for a given variable X to be deleted, the list of all the variables of
115  // the tables containing X (actually, we also count the number of tables
116  // containing the variable. This is more efficient for computing and
117  // updating the product_size priority queue (see below) when some tables
118  // are removed)
119  HashTable< const DiscreteVariable*,
120  HashTable< const DiscreteVariable*, unsigned int > >
122 
123  // initialize tables_vars_per_var and tables_per_var
124  {
125  Set< const TABLE< GUM_SCALAR >* > empty_set(table_set.size());
126  HashTable< const DiscreteVariable*, unsigned int > empty_hash(nb_vars);
127 
128  for (const auto ptrVar: del_vars) {
131  }
132 
133  // update properly tables_per_var and tables_vars_per_var
134  for (const auto ptrTab: table_set) {
135  const Sequence< const DiscreteVariable* >& vars
137 
138  for (const auto ptrVar: vars) {
139  if (del_vars.contains(ptrVar)) {
140  // add the table to the set of tables related to vars[i]
142 
143  // add the variables of the table to tables_vars_per_var[vars[i]]
144  HashTable< const DiscreteVariable*, unsigned int >& iter_vars
146 
147  for (const auto xptrVar: vars) {
148  try {
149  ++iter_vars[xptrVar];
150  } catch (const NotFound&) { iter_vars.insert(xptrVar, 1); }
151  }
152  }
153  }
154  }
155  }
156 
157  // the sizes of the tables produced when removing a given discrete variable
158  PriorityQueue< const DiscreteVariable*, double > product_size;
159 
160  // initialize properly product_size
161  for (const auto& elt: tables_vars_per_var) {
162  double size = 1.0;
163  const auto ptrVar = elt.first;
164  const auto& hashvars = elt.second; // HashTable<DiscreteVariable*, int>
165 
166  if (hashvars.size()) {
167  for (const auto& xelt: hashvars) {
168  size *= (double)xelt.first->domainSize();
169  }
170 
172  }
173  }
174 
175  // create a set of the temporary tables created during the
176  // marginalization process (useful for deallocating temporary tables)
178 
179  // now, remove all the variables in del_vars, starting from those that
180  // produce the smallest tables
181  while (!product_size.empty()) {
182  // get the best variable to remove
185 
186  // get the set of tables to combine
187  Set< const TABLE< GUM_SCALAR >* >& tables_to_combine
189 
190  // if there is no tables to combine, do nothing
191  if (tables_to_combine.size() == 0) continue;
192 
193  // compute the combination of all the tables: if there is only one table,
194  // there is nothing to do, else we shall use the MultiDimCombination
195  // to perform the combination
196  TABLE< GUM_SCALAR >* joint;
197 
198  bool joint_to_delete = false;
199 
200  if (tables_to_combine.size() == 1) {
201  joint = const_cast< TABLE< GUM_SCALAR >* >(*(tables_to_combine.begin()));
202  joint_to_delete = false;
203  } else {
205  joint_to_delete = true;
206  }
207 
208  // compute the table resulting from marginalizing out del_var from joint
209  Set< const DiscreteVariable* > del_one_var;
210  del_one_var << del_var;
211 
213 
214  // remove the temporary joint if needed
215  if (joint_to_delete) delete joint;
216 
217  // update tables_vars_per_var : remove the variables of the TABLEs we
218  // combined from this hashtable
219  // update accordingly tables_per_vars : remove these TABLEs
220  // update accordingly product_size : when a variable is no more used by
221  // any TABLE, divide product_size by its domain size
222 
223  for (const auto ptrTab: tables_to_combine) {
224  const Sequence< const DiscreteVariable* >& table_vars
226  const Size tab_vars_size = table_vars.size();
227 
228  for (Size i = 0; i < tab_vars_size; ++i) {
229  if (del_vars.contains(table_vars[i])) {
230  // ok, here we have a variable that needed to be removed => update
231  // product_size, tables_per_var and tables_vars_per_var: here,
232  // the update corresponds to removing table PtrTab
233  HashTable< const DiscreteVariable*, unsigned int >& table_vars_of_var_i
235  double div_size = 1.0;
236 
237  for (Size j = 0; j < tab_vars_size; ++j) {
238  unsigned int k = --table_vars_of_var_i[table_vars[j]];
239 
240  if (k == 0) {
243  }
244  }
245 
247 
248  if (div_size != 1.0) {
251  / div_size);
252  }
253  }
254  }
255 
257  delete ptrTab;
259  }
260 
262  }
263 
265 
266  // add the new projected marginal to the list of TABLES
267  const Sequence< const DiscreteVariable* >& marginal_vars
269 
270  for (const auto mvar: marginal_vars) {
271  if (del_vars.contains(mvar)) {
272  // add the new marginal table to the set of tables of mvar
274 
275  // add the variables of the table to tables_vars_per_var[mvar]
276  HashTable< const DiscreteVariable*, unsigned int >& iter_vars
278  double mult_size = 1.0;
279 
280  for (const auto var: marginal_vars) {
281  try {
282  ++iter_vars[var];
283  } catch (const NotFound&) {
284  iter_vars.insert(var, 1);
285  mult_size *= (double)var->domainSize();
286  }
287  }
288 
289  if (mult_size != 1.0) {
292  }
293  }
294  }
295 
298  }
299 
300  // here, tmp_marginals contains all the newly created tables and
301  // table_set contains the list of the tables resulting from the
302  // marginalizing out of del_vars of the combination of the tables
303  // of table_set. Note in particular that it will contain all the
304  // potentials with no dimension (constants)
305  return table_set;
306  }
307 
308  // changes the function used for combining two TABLES
309  template < typename GUM_SCALAR, template < typename > class TABLE >
310  INLINE void
312  TABLE< GUM_SCALAR >* (*combine)(const TABLE< GUM_SCALAR >&,
313  const TABLE< GUM_SCALAR >&)) {
315  }
316 
317  // returns the current combination function
318  template < typename GUM_SCALAR, template < typename > class TABLE >
319  INLINE TABLE< GUM_SCALAR >* (
321  const TABLE< GUM_SCALAR >&,
322  const TABLE< GUM_SCALAR >&) {
323  return combination__->combineFunction();
324  }
325 
326  // changes the class that performs the combinations
327  template < typename GUM_SCALAR, template < typename > class TABLE >
328  INLINE void
331  delete combination__;
333  }
334 
335  // changes the function used for projecting TABLES
336  template < typename GUM_SCALAR, template < typename > class TABLE >
337  INLINE void
339  TABLE< GUM_SCALAR >* (*proj)(const TABLE< GUM_SCALAR >&,
340  const Set< const DiscreteVariable* >&)) {
342  }
343 
344  // returns the current projection function
345  template < typename GUM_SCALAR, template < typename > class TABLE >
346  INLINE TABLE< GUM_SCALAR >* (
348  const TABLE< GUM_SCALAR >&,
349  const Set< const DiscreteVariable* >&) {
350  return projection__->projectFunction();
351  }
352 
353  // changes the class that performs the projections
354  template < typename GUM_SCALAR, template < typename > class TABLE >
355  INLINE void
358  delete projection__;
360  }
361 
362  /** @brief returns a rough estimate of the number of operations that will be
363  * performed to compute the combination */
364  template < typename GUM_SCALAR, template < typename > class TABLE >
366  const Set< const Sequence< const DiscreteVariable* >* >& table_set,
367  Set< const DiscreteVariable* > del_vars) const {
368  // when we remove a variable, we need to combine all the tables containing
369  // this variable in order to produce a new unique table containing this
370  // variable. Here, we do not have the tables but only their variables
371  // (dimensions), but the principle is identical. Removing a variable is then
372  // performed by marginalizing it out of the table or, equivalently, to
373  // remove it from the table's list of variables. In the
374  // combineAndProjectDefault algorithm, we wish to remove first variables
375  // that would produce small tables. This should speed up the whole
376  // marginalizing process.
377 
378  Size nb_vars;
379  {
380  // determine the set of all the variables involved in the tables.
381  // this should help sizing correctly the hashtables
382  Set< const DiscreteVariable* > all_vars;
383 
384  for (const auto ptrSeq: table_set) {
385  for (const auto ptrVar: *ptrSeq) {
387  }
388  }
389 
390  nb_vars = all_vars.size();
391  }
392 
393  // the tables (actually their variables) containing a given variable
394  // to be deleted
395  HashTable< const DiscreteVariable*,
396  Set< const Sequence< const DiscreteVariable* >* > >
398 
399  // for a given variable X to be deleted, the list of all the variables of
400  // the tables containing X (actually, we count the number of tables
401  // containing the variable. This is more efficient for computing and
402  // updating the product_size priority queue (see below) when some tables
403  // are removed)
404  HashTable< const DiscreteVariable*,
405  HashTable< const DiscreteVariable*, unsigned int > >
407 
408  // initialize tables_vars_per_var and tables_per_var
409  {
410  Set< const Sequence< const DiscreteVariable* >* > empty_set(
411  table_set.size());
412  HashTable< const DiscreteVariable*, unsigned int > empty_hash(nb_vars);
413 
414  for (const auto ptrVar: del_vars) {
417  }
418 
419  // update properly tables_per_var and tables_vars_per_var
420  for (const auto ptrSeq: table_set) {
421  const Sequence< const DiscreteVariable* >& vars = *ptrSeq;
422 
423  for (const auto ptrVar: vars) {
424  if (del_vars.contains(ptrVar)) {
425  // add the table's variables to the set of those related to ptrVar
427 
428  // add the variables of the table to tables_vars_per_var[ptrVar]
429  HashTable< const DiscreteVariable*, unsigned int >& iter_vars
431 
432  for (const auto xptrVar: vars) {
433  try {
434  ++iter_vars[xptrVar];
435  } catch (const NotFound&) { iter_vars.insert(xptrVar, 1); }
436  }
437  }
438  }
439  }
440  }
441 
442  // the sizes of the tables produced when removing a given discrete variable
443  PriorityQueue< const DiscreteVariable*, double > product_size;
444 
445  // initialize properly product_size
446  for (const auto& elt: tables_vars_per_var) {
447  double size = 1.0;
448  const auto ptrVar = elt.first;
449  const auto hashvars = elt.second; // HashTable<DiscreteVariable*, int>
450 
451  if (hashvars.size()) {
452  for (const auto& xelt: hashvars) {
453  size *= (double)xelt.first->domainSize();
454  }
455 
457  }
458  }
459 
460  // the resulting number of operations
461  float nb_operations = 0;
462 
463  // create a set of the temporary table's variables created during the
464  // marginalization process (useful for deallocating temporary tables)
465  Set< const Sequence< const DiscreteVariable* >* > tmp_marginals(
466  table_set.size());
467 
468  // now, remove all the variables in del_vars, starting from those that
469  // produce the smallest tables
470  while (!product_size.empty()) {
471  // get the best variable to remove
474 
475  // get the set of tables to combine
476  Set< const Sequence< const DiscreteVariable* >* >& tables_to_combine
478 
479  // if there is no tables to combine, do nothing
480  if (tables_to_combine.size() == 0) continue;
481 
482  // compute the combination of all the tables: if there is only one table,
483  // there is nothing to do, else we shall use the MultiDimCombination
484  // to perform the combination
485  Sequence< const DiscreteVariable* >* joint;
486 
487  bool joint_to_delete = false;
488 
489  if (tables_to_combine.size() == 1) {
490  joint = const_cast< Sequence< const DiscreteVariable* >* >(
492  joint_to_delete = false;
493  } else {
494  // here, compute the union of all the variables of the tables to combine
495  joint = new Sequence< const DiscreteVariable* >;
496 
497  for (const auto ptrSeq: tables_to_combine) {
498  for (const auto ptrVar: *ptrSeq) {
499  if (!joint->exists(ptrVar)) { joint->insert(ptrVar); }
500  }
501  }
502 
503  joint_to_delete = true;
504 
505  // update the number of operations performed
507  }
508 
509  // update the number of operations performed by marginalizing out del_var
510  Set< const DiscreteVariable* > del_one_var;
511  del_one_var << del_var;
512 
514 
515  // compute the table resulting from marginalizing out del_var from joint
517 
518  if (joint_to_delete) {
519  marginal = joint;
520  } else {
521  marginal = new Sequence< const DiscreteVariable* >(*joint);
522  }
523 
525 
526  // update tables_vars_per_var : remove the variables of the TABLEs we
527  // combined from this hashtable
528  // update accordingly tables_per_vars : remove these TABLEs
529  // update accordingly product_size : when a variable is no more used by
530  // any TABLE, divide product_size by its domain size
531 
532  for (const auto ptrSeq: tables_to_combine) {
533  const Sequence< const DiscreteVariable* >& table_vars = *ptrSeq;
534  const Size tab_vars_size = table_vars.size();
535 
536  for (Size i = 0; i < tab_vars_size; ++i) {
537  if (del_vars.contains(table_vars[i])) {
538  // ok, here we have a variable that needed to be removed => update
539  // product_size, tables_per_var and tables_vars_per_var
540  HashTable< const DiscreteVariable*, unsigned int >& table_vars_of_var_i
542  double div_size = 1.0;
543 
544  for (Size j = 0; j < tab_vars_size; ++j) {
545  unsigned int k = --table_vars_of_var_i[table_vars[j]];
546 
547  if (k == 0) {
550  }
551  }
552 
554 
555  if (div_size != 1.0) {
558  / div_size);
559  }
560  }
561  }
562 
564  delete ptrSeq;
566  }
567  }
568 
570 
571  // add the new projected marginal to the list of TABLES
572  for (const auto mvar: *marginal) {
573  if (del_vars.contains(mvar)) {
574  // add the new marginal table to the set of tables of var i
576 
577  // add the variables of the table to tables_vars_per_var[vars[i]]
578  HashTable< const DiscreteVariable*, unsigned int >& iter_vars
580  double mult_size = 1.0;
581 
582  for (const auto var: *marginal) {
583  try {
584  ++iter_vars[var];
585  } catch (const NotFound&) {
586  iter_vars.insert(var, 1);
587  mult_size *= (double)var->domainSize();
588  }
589  }
590 
591  if (mult_size != 1.0) {
594  }
595  }
596  }
597 
599  }
600 
601  // here, tmp_marginals contains all the newly created tables
603  ++iter) {
604  delete *iter;
605  }
606 
607  return nb_operations;
608  }
609 
610  /** @brief returns a rough estimate of the number of operations that will be
611  * performed to compute the combination */
612  template < typename GUM_SCALAR, template < typename > class TABLE >
614  const Set< const TABLE< GUM_SCALAR >* >& set,
615  const Set< const DiscreteVariable* >& del_vars) const {
616  // create the set of sets of discrete variables involved in the tables
617  Set< const Sequence< const DiscreteVariable* >* > var_set(set.size());
618 
619  for (const auto ptrTab: set) {
621  }
622 
623  return nbOperations(var_set, del_vars);
624  }
625 
626  // returns the memory consumption used during the combinations and
627  // projections
628  template < typename GUM_SCALAR, template < typename > class TABLE >
629  std::pair< long, long >
631  const Set< const Sequence< const DiscreteVariable* >* >& table_set,
632  Set< const DiscreteVariable* > del_vars) const {
633  // when we remove a variable, we need to combine all the tables containing
634  // this variable in order to produce a new unique table containing this
635  // variable. Here, we do not have the tables but only their variables
636  // (dimensions), but the principle is identical. Removing a variable is then
637  // performed by marginalizing it out of the table or, equivalently, to
638  // remove it from the table's list of variables. In the
639  // combineAndProjectDefault algorithm, we wish to remove first variables
640  // that would produce small tables. This should speed up the whole
641  // marginalizing process.
642 
643  Size nb_vars;
644  {
645  // determine the set of all the variables involved in the tables.
646  // this should help sizing correctly the hashtables
647  Set< const DiscreteVariable* > all_vars;
648 
649  for (const auto ptrSeq: table_set) {
650  for (const auto ptrVar: *ptrSeq) {
652  }
653  }
654 
655  nb_vars = all_vars.size();
656  }
657 
658  // the tables (actually their variables) containing a given variable
659  HashTable< const DiscreteVariable*,
660  Set< const Sequence< const DiscreteVariable* >* > >
662  // for a given variable X to be deleted, the list of all the variables of
663  // the tables containing X (actually, we count the number of tables
664  // containing the variable. This is more efficient for computing and
665  // updating the product_size priority queue (see below) when some tables
666  // are removed)
667  HashTable< const DiscreteVariable*,
668  HashTable< const DiscreteVariable*, unsigned int > >
670 
671  // initialize tables_vars_per_var and tables_per_var
672  {
673  Set< const Sequence< const DiscreteVariable* >* > empty_set(
674  table_set.size());
675  HashTable< const DiscreteVariable*, unsigned int > empty_hash(nb_vars);
676 
677  for (const auto ptrVar: del_vars) {
680  }
681 
682  // update properly tables_per_var and tables_vars_per_var
683  for (const auto ptrSeq: table_set) {
684  const Sequence< const DiscreteVariable* >& vars = *ptrSeq;
685 
686  for (const auto ptrVar: vars) {
687  if (del_vars.contains(ptrVar)) {
688  // add the table's variables to the set of those related to ptrVar
690 
691  // add the variables of the table to tables_vars_per_var[ptrVar]
692  HashTable< const DiscreteVariable*, unsigned int >& iter_vars
694 
695  for (const auto xptrVar: vars) {
696  try {
697  ++iter_vars[xptrVar];
698  } catch (const NotFound&) { iter_vars.insert(xptrVar, 1); }
699  }
700  }
701  }
702  }
703  }
704 
705  // the sizes of the tables produced when removing a given discrete variable
706  PriorityQueue< const DiscreteVariable*, double > product_size;
707 
708  // initialize properly product_size
709  for (const auto& elt: tables_vars_per_var) {
710  double size = 1.0;
711  const auto ptrVar = elt.first;
712  const auto hashvars = elt.second; // HashTable<DiscreteVariable*, int>
713 
714  if (hashvars.size()) {
715  for (const auto& xelt: hashvars) {
716  size *= (double)xelt.first->domainSize();
717  }
718 
720  }
721  }
722 
723  // the resulting memory consumtions
724  long max_memory = 0;
725  long current_memory = 0;
726 
727  // create a set of the temporary table's variables created during the
728  // marginalization process (useful for deallocating temporary tables)
729  Set< const Sequence< const DiscreteVariable* >* > tmp_marginals(
730  table_set.size());
731 
732  // now, remove all the variables in del_vars, starting from those that
733  // produce
734  // the smallest tables
735  while (!product_size.empty()) {
736  // get the best variable to remove
739 
740  // get the set of tables to combine
741  Set< const Sequence< const DiscreteVariable* >* >& tables_to_combine
743 
744  // if there is no tables to combine, do nothing
745  if (tables_to_combine.size() == 0) continue;
746 
747  // compute the combination of all the tables: if there is only one table,
748  // there is nothing to do, else we shall use the MultiDimCombination
749  // to perform the combination
750  Sequence< const DiscreteVariable* >* joint;
751 
752  bool joint_to_delete = false;
753 
754  if (tables_to_combine.size() == 1) {
755  joint = const_cast< Sequence< const DiscreteVariable* >* >(
757  joint_to_delete = false;
758  } else {
759  // here, compute the union of all the variables of the tables to combine
760  joint = new Sequence< const DiscreteVariable* >;
761 
762  for (const auto ptrSeq: tables_to_combine) {
763  for (const auto ptrVar: *ptrSeq) {
764  if (!joint->exists(ptrVar)) { joint->insert(ptrVar); }
765  }
766  }
767 
768  joint_to_delete = true;
769 
770  // update the number of operations performed
771  std::pair< long, long > comb_memory
773 
774  if ((std::numeric_limits< long >::max() - current_memory
775  < comb_memory.first)
776  || (std::numeric_limits< long >::max() - current_memory
777  < comb_memory.second)) {
778  GUM_ERROR(OutOfBounds, "memory usage out of long int range");
779  }
780 
783  }
784 
786  }
787 
788  // update the number of operations performed by marginalizing out del_var
789  Set< const DiscreteVariable* > del_one_var;
790  del_one_var << del_var;
791 
792  std::pair< long, long > comb_memory
794 
795  if ((std::numeric_limits< long >::max() - current_memory < comb_memory.first)
796  || (std::numeric_limits< long >::max() - current_memory
797  < comb_memory.second)) {
798  GUM_ERROR(OutOfBounds, "memory usage out of long int range");
799  }
800 
803  }
804 
806 
807  // compute the table resulting from marginalizing out del_var from joint
809 
810  if (joint_to_delete) {
811  marginal = joint;
812  } else {
813  marginal = new Sequence< const DiscreteVariable* >(*joint);
814  }
815 
817 
818  // update tables_vars_per_var : remove the variables of the TABLEs we
819  // combined from this hashtable
820  // update accordingly tables_per_vars : remove these TABLEs
821  // update accordingly product_size : when a variable is no more used by
822  // any TABLE, divide product_size by its domain size
823 
824  for (const auto ptrSeq: tables_to_combine) {
825  const Sequence< const DiscreteVariable* >& table_vars = *ptrSeq;
826  const Size tab_vars_size = table_vars.size();
827 
828  for (Size i = 0; i < tab_vars_size; ++i) {
829  if (del_vars.contains(table_vars[i])) {
830  // ok, here we have a variable that needed to be removed => update
831  // product_size, tables_per_var and tables_vars_per_var
832  HashTable< const DiscreteVariable*, unsigned int >& table_vars_of_var_i
834  double div_size = 1.0;
835 
836  for (Size j = 0; j < tab_vars_size; ++j) {
838 
839  if (k == 0) {
842  }
843  }
844 
846 
847  if (div_size != 1) {
850  / div_size);
851  }
852  }
853  }
854 
856  Size del_size = 1;
857 
858  for (const auto ptrVar: *ptrSeq) {
859  del_size *= ptrVar->domainSize();
860  }
861 
862  current_memory -= long(del_size);
863 
864  delete ptrSeq;
866  }
867  }
868 
870 
871  // add the new projected marginal to the list of TABLES
872  for (const auto mvar: *marginal) {
873  if (del_vars.contains(mvar)) {
874  // add the new marginal table to the set of tables of var i
876 
877  // add the variables of the table to tables_vars_per_var[vars[i]]
878  HashTable< const DiscreteVariable*, unsigned int >& iter_vars
880  double mult_size = 1.0;
881 
882  for (const auto var: *marginal) {
883  try {
884  ++iter_vars[var];
885  } catch (const NotFound&) {
886  iter_vars.insert(var, 1);
887  mult_size *= (double)var->domainSize();
888  }
889  }
890 
891  if (mult_size != 1) {
894  }
895  }
896  }
897 
899  }
900 
901  // here, tmp_marginals contains all the newly created tables
903  ++iter) {
904  delete *iter;
905  }
906 
907  return std::pair< long, long >(max_memory, current_memory);
908  }
909 
910  // returns the memory consumption used during the combinations and
911  // projections
912  template < typename GUM_SCALAR, template < typename > class TABLE >
913  std::pair< long, long >
915  const Set< const TABLE< GUM_SCALAR >* >& set,
916  const Set< const DiscreteVariable* >& del_vars) const {
917  // create the set of sets of discrete variables involved in the tables
918  Set< const Sequence< const DiscreteVariable* >* > var_set(set.size());
919 
920  for (const auto ptrTab: set) {
922  }
923 
924  return memoryUsage(var_set, del_vars);
925  }
926 
927 } /* namespace gum */
928 
929 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669