aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
multiDimCombinationDefault_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 A generic class to combine efficiently several 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
/
core
/
priorityQueue
.
h
>
36
#
include
<
agrum
/
tools
/
multidim
/
utils
/
operators
/
multiDimCombinationDefault
.
h
>
37
38
namespace
gum
{
39
40
// constructor
41
template
<
typename
GUM_SCALAR,
template
<
typename
>
class
TABLE >
42
MultiDimCombinationDefault< GUM_SCALAR, TABLE >::MultiDimCombinationDefault(
43
TABLE< GUM_SCALAR >* (*combine)(
const
TABLE< GUM_SCALAR >&,
44
const
TABLE< GUM_SCALAR >&)) :
45
MultiDimCombination< GUM_SCALAR, TABLE >(),
46
combine_(combine) {
47
// for debugging purposes
48
GUM_CONSTRUCTOR(MultiDimCombinationDefault);
49
}
50
51
// copy constructor
52
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
53
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
MultiDimCombinationDefault
(
54
const
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>&
from
) :
55
MultiDimCombination
<
GUM_SCALAR
,
TABLE
>(),
56
combine_
(
from
.
combine_
) {
57
// for debugging purposes
58
GUM_CONS_CPY
(
MultiDimCombinationDefault
);
59
}
60
61
// destructor
62
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
63
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::~
MultiDimCombinationDefault
() {
64
// for debugging purposes
65
GUM_DESTRUCTOR
(
MultiDimCombinationDefault
);
66
}
67
68
// virtual constructor
69
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
70
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>*
71
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
newFactory
()
const
{
72
return
new
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>(
combine_
);
73
}
74
75
// changes the function used for combining two TABLES
76
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
77
void
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
setCombineFunction
(
78
TABLE
<
GUM_SCALAR
>* (*
combine
)(
const
TABLE
<
GUM_SCALAR
>&,
79
const
TABLE
<
GUM_SCALAR
>&)) {
80
combine_
=
combine
;
81
}
82
83
// returns the combination function currently used by the combinator
84
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
85
INLINE
TABLE
<
GUM_SCALAR
>* (
86
*
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
combineFunction
())(
87
const
TABLE
<
GUM_SCALAR
>&,
88
const
TABLE
<
GUM_SCALAR
>&) {
89
return
combine_
;
90
}
91
92
// returns the domain size of the Cartesian product of the union of all the
93
// variables in seq1 and seq2
94
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
95
Size
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
combinedSize_
(
96
const
Sequence
<
const
DiscreteVariable
* >&
seq1
,
97
const
Sequence
<
const
DiscreteVariable
* >&
seq2
)
const
{
98
if
(
seq1
.
empty
() &&
seq2
.
empty
())
return
0;
99
100
Size
size
= 1;
101
102
for
(
const
auto
ptrVar
:
seq1
)
103
size
*=
ptrVar
->
domainSize
();
104
105
for
(
const
auto
ptrVar
:
seq2
)
106
if
(!
seq1
.
exists
(
ptrVar
))
size
*=
ptrVar
->
domainSize
();
107
108
return
size
;
109
}
110
111
// returns the result of the combination
112
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
113
INLINE
void
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
combine
(
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
);
118
delete
(
res
);
119
}
120
121
// returns the result of the combination
122
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
123
TABLE
<
GUM_SCALAR
>*
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
combine
(
124
const
Set
<
const
TABLE
<
GUM_SCALAR
>* >&
set
) {
125
// check if the set passed in argument is empty. If so, raise an exception
126
if
(
set
.
size
() < 2) {
127
GUM_ERROR
(
InvalidArgumentsNumber
,
128
"the set passed to a MultiDimCombinationDefault"
129
" should at least contain two elements"
);
130
}
131
132
// create a vector with all the tables to combine
133
std
::
vector
<
const
TABLE
<
GUM_SCALAR
>* >
tables
(
set
.
size
());
134
const
Size
tabsize
=
tables
.
size
();
135
136
{
137
Size
i
=
Size
(0);
138
for
(
auto
iter
=
set
.
cbegin
();
iter
!=
set
.
cend
(); ++
iter
, ++
i
) {
139
tables
[
i
] = *
iter
;
140
}
141
}
142
143
// create a vector indicating wether the elements in tables are freshly
144
// created TABLE<GUM_SCALAR>* due to the combination of some TABLEs or if
145
// they were added by the user into the combination container
146
std
::
vector
<
bool
>
is_t_new
(
tabsize
,
false
);
147
148
// for each pair of tables (i,j), compute the size of the table that would
149
// result from the addition of tables i and j and store the result into a
150
// priorityQueue
151
std
::
pair
<
Size
,
Size
>
pair
;
152
PriorityQueue
<
std
::
pair
<
Size
,
Size
>,
Size
>
queue
;
153
154
for
(
Size
i
=
Size
(0);
i
<
tabsize
; ++
i
) {
155
pair
.
first
=
i
;
156
const
Sequence
<
const
DiscreteVariable
* >&
seq1
157
=
tables
[
i
]->
variablesSequence
();
158
159
for
(
Size
j
=
i
+ 1;
j
<
tabsize
; ++
j
) {
160
pair
.
second
=
j
;
161
queue
.
insert
(
pair
,
combinedSize_
(
seq1
,
tables
[
j
]->
variablesSequence
()));
162
}
163
}
164
165
// now parse the priority queue: the top element (i,j) gives the combination
166
// to perform. When the result R has been computed, substitute i by R,
167
// remove table j and recompute all the priorities of all the pairs (R,k)
168
// still available.
169
for
(
Size
k
= 1;
k
<
tabsize
; ++
k
) {
170
// get the combination to perform and do it
171
pair
=
queue
.
pop
();
172
const
Size
ti
=
pair
.
first
;
173
const
Size
tj
=
pair
.
second
;
174
175
TABLE
<
GUM_SCALAR
>*
result
=
combine_
(*(
tables
[
ti
]), *(
tables
[
tj
]));
176
177
// substitute tables[pair.first] by the result
178
if
(
tables
[
ti
] &&
is_t_new
[
ti
])
delete
tables
[
ti
];
179
if
(
tables
[
tj
] &&
is_t_new
[
tj
])
delete
tables
[
tj
];
180
181
tables
[
ti
] =
result
;
182
is_t_new
[
ti
] =
true
;
183
184
tables
[
tj
] =
nullptr
;
185
186
// remove all the pairs involving tj in the priority queue
187
for
(
Size
ind
= 0;
ind
<
tj
; ++
ind
) {
188
if
(
tables
[
ind
] !=
nullptr
) {
189
pair
.
first
=
ind
;
190
queue
.
erase
(
pair
);
191
}
192
}
193
194
pair
.
first
=
tj
;
195
for
(
Size
ind
=
tj
+ 1;
ind
<
tabsize
; ++
ind
) {
196
if
(
tables
[
ind
] !=
nullptr
) {
197
pair
.
second
=
ind
;
198
queue
.
erase
(
pair
);
199
}
200
}
201
202
// update the "combinated" size of all the pairs involving "result"
203
{
204
const
Sequence
<
const
DiscreteVariable
* >&
seq1
205
=
tables
[
ti
]->
variablesSequence
();
206
pair
.
second
=
ti
;
207
Size
newsize
;
208
209
for
(
Size
ind
= 0;
ind
<
ti
; ++
ind
) {
210
if
(
tables
[
ind
] !=
nullptr
) {
211
pair
.
first
=
ind
;
212
newsize
=
combinedSize_
(
seq1
,
tables
[
ind
]->
variablesSequence
());
213
queue
.
setPriority
(
pair
,
newsize
);
214
}
215
}
216
217
pair
.
first
=
ti
;
218
219
for
(
Size
ind
=
ti
+ 1;
ind
<
tabsize
; ++
ind
) {
220
if
(
tables
[
ind
] !=
nullptr
) {
221
pair
.
second
=
ind
;
222
newsize
=
combinedSize_
(
seq1
,
tables
[
ind
]->
variablesSequence
());
223
queue
.
setPriority
(
pair
,
newsize
);
224
}
225
}
226
}
227
}
228
229
// here, there remains only one nonzero pointer in tables:
230
// the result of our combination
231
Size
k
= 0;
232
while
(
tables
[
k
] ==
nullptr
)
233
++
k
;
234
235
return
const_cast
<
TABLE
<
GUM_SCALAR
>* >(
tables
[
k
]);
236
}
237
238
// returns the result of the combination
239
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
240
float
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
nbOperations
(
241
const
Set
<
const
Sequence
<
const
DiscreteVariable
* >* >&
set
)
const
{
242
// check if the set passed in argument is empty.
243
if
(
set
.
size
() < 2)
return
0.0f;
244
245
float
result
= 0.0f;
246
247
// create a vector with all the tables to combine
248
std
::
vector
<
const
Sequence
<
const
DiscreteVariable
* >* >
tables
(
set
.
size
());
249
const
Size
tabsize
=
tables
.
size
();
250
251
{
252
Size
i
=
Size
(0);
253
for
(
auto
iter
=
set
.
cbegin
();
iter
!=
set
.
cend
(); ++
iter
, ++
i
) {
254
tables
[
i
] = *
iter
;
255
}
256
}
257
258
// create a vector indicating wether the elements in tables are freshly
259
// created Sequence<const DiscreteVariable *>* due to the combination of
260
// some TABLEs or if they were added by the user into the combination
261
// container
262
std
::
vector
<
bool
>
is_t_new
(
tabsize
,
false
);
263
264
// for each pair of tables (i,j), compute the size of the table that would
265
// result from the addition of tables i and j and store the result into a
266
// priorityQueue
267
std
::
pair
<
Size
,
Size
>
pair
;
268
PriorityQueue
<
std
::
pair
<
Size
,
Size
>,
Size
>
queue
;
269
270
for
(
Size
i
=
Size
(0);
i
<
tabsize
; ++
i
) {
271
pair
.
first
=
i
;
272
273
for
(
Size
j
=
i
+ 1;
j
<
tabsize
; ++
j
) {
274
pair
.
second
=
j
;
275
queue
.
insert
(
pair
,
combinedSize_
(*(
tables
[
i
]), *(
tables
[
j
])));
276
}
277
}
278
279
// now parse the priority queue: the top element (i,j) gives the combination
280
// to perform. When the result R has been computed, substitute i by R,
281
// remove table j and recompute all the priorities of all the pairs (R,k)
282
// still available.
283
for
(
Size
k
= 1;
k
<
tabsize
; ++
k
) {
284
// get the combination to perform and do it
285
pair
=
queue
.
pop
();
286
const
Size
ti
=
pair
.
first
;
287
const
Size
tj
=
pair
.
second
;
288
289
// compute the result
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
]);
294
295
Size
new_size
= 1;
296
297
for
(
const
auto
ptrVar
:
seq1
) {
298
new_size
*=
ptrVar
->
domainSize
();
299
new_seq
->
insert
(
ptrVar
);
300
}
301
302
for
(
const
auto
ptrVar
:
seq2
) {
303
if
(!
seq1
.
exists
(
ptrVar
)) {
304
new_size
*=
ptrVar
->
domainSize
();
305
new_seq
->
insert
(
ptrVar
);
306
}
307
}
308
309
result
+=
new_size
;
310
311
// substitute tables[pair.first] by the result
312
if
(
tables
[
ti
] &&
is_t_new
[
ti
])
delete
tables
[
ti
];
313
if
(
tables
[
tj
] &&
is_t_new
[
tj
])
delete
tables
[
tj
];
314
315
tables
[
ti
] =
new_seq
;
316
is_t_new
[
ti
] =
true
;
317
318
tables
[
tj
] =
nullptr
;
319
320
// remove all the pairs involving tj in the priority queue
321
for
(
Size
ind
= 0;
ind
<
tj
; ++
ind
) {
322
if
(
tables
[
ind
] !=
nullptr
) {
323
pair
.
first
=
ind
;
324
queue
.
erase
(
pair
);
325
}
326
}
327
328
pair
.
first
=
tj
;
329
330
for
(
Size
ind
=
tj
+ 1;
ind
<
tabsize
; ++
ind
) {
331
if
(
tables
[
ind
] !=
nullptr
) {
332
pair
.
second
=
ind
;
333
queue
.
erase
(
pair
);
334
}
335
}
336
337
// update the "combined" size of all the pairs involving "new_seq"
338
{
339
pair
.
second
=
ti
;
340
Size
newsize
;
341
342
for
(
Size
ind
= 0;
ind
<
ti
; ++
ind
) {
343
if
(
tables
[
ind
] !=
nullptr
) {
344
pair
.
first
=
ind
;
345
newsize
=
combinedSize_
(*
new_seq
, *(
tables
[
ind
]));
346
queue
.
setPriority
(
pair
,
newsize
);
347
}
348
}
349
350
pair
.
first
=
ti
;
351
352
for
(
Size
ind
=
ti
+ 1;
ind
<
tabsize
; ++
ind
) {
353
if
(
tables
[
ind
] !=
nullptr
) {
354
pair
.
second
=
ind
;
355
newsize
=
combinedSize_
(*
new_seq
, *(
tables
[
ind
]));
356
queue
.
setPriority
(
pair
,
newsize
);
357
}
358
}
359
}
360
}
361
362
// here, there remains only one nonzero pointer in tables:
363
// the result of our combination
364
Size
k
= 0;
365
while
(
tables
[
k
] ==
nullptr
)
366
++
k
;
367
368
delete
tables
[
k
];
369
370
return
result
;
371
}
372
373
// returns the result of the combination
374
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
375
float
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
nbOperations
(
376
const
Set
<
const
TABLE
<
GUM_SCALAR
>* >&
set
)
const
{
377
// check if the set passed in argument is empty.
378
if
(
set
.
size
() < 2)
return
0.0f;
379
380
// create the set of sets of discrete variables involved in the tables
381
Set
<
const
Sequence
<
const
DiscreteVariable
* >* >
var_set
(
set
.
size
());
382
383
for
(
const
auto
ptrTab
:
set
) {
384
var_set
<< &(
ptrTab
->
variablesSequence
());
385
}
386
387
return
nbOperations
(
var_set
);
388
}
389
390
// returns the memory consumption used during the combination
391
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
392
std
::
pair
<
long
,
long
>
393
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
memoryUsage
(
394
const
Set
<
const
Sequence
<
const
DiscreteVariable
* >* >&
set
)
const
{
395
// check if the set passed in argument is empty.
396
if
(
set
.
size
() < 2)
return
std
::
pair
<
long
,
long
>(0, 0);
397
398
Size
max_memory
= 0;
399
Size
current_memory
= 0;
400
401
// create a vector with all the tables to combine
402
std
::
vector
<
const
Sequence
<
const
DiscreteVariable
* >* >
tables
(
set
.
size
());
403
const
Size
tabsize
=
tables
.
size
();
404
405
std
::
vector
<
Size
>
table_size
(
set
.
size
());
406
407
{
408
Size
i
=
Size
(0);
409
410
for
(
auto
iter
=
set
.
cbegin
();
iter
!=
set
.
cend
(); ++
iter
, ++
i
) {
411
const
Sequence
<
const
DiscreteVariable
* >*
vars
= *
iter
;
412
tables
[
i
] =
vars
;
413
414
Size
size
=
Size
(1);
415
for
(
const
auto
ptrVar
: *
vars
) {
416
size
*=
ptrVar
->
domainSize
();
417
}
418
419
table_size
[
i
] =
size
;
420
}
421
}
422
423
// create a vector indicating wether the elements in tables are freshly
424
// created Sequence<const DiscreteVariable *>* due to the combination of
425
// some TABLEs or if they were added by the user into the combination
426
// container
427
std
::
vector
<
bool
>
is_t_new
(
tables
.
size
(),
false
);
428
429
// for each pair of tables (i,j), compute the size of the table that would
430
// result from the addition of tables i and j and store the result into a
431
// priorityQueue
432
std
::
pair
<
Size
,
Size
>
pair
;
433
434
PriorityQueue
<
std
::
pair
<
Size
,
Size
>,
Size
>
queue
;
435
436
for
(
Size
i
=
Size
(0);
i
<
tabsize
; ++
i
) {
437
pair
.
first
=
i
;
438
439
for
(
Size
j
=
i
+ 1;
j
<
tabsize
; ++
j
) {
440
pair
.
second
=
j
;
441
queue
.
insert
(
pair
,
combinedSize_
(*(
tables
[
i
]), *(
tables
[
j
])));
442
}
443
}
444
445
// now parse the priority queue: the top element (i,j) gives the combination
446
// to perform. When the result R has been computed, substitute i by R,
447
// remove table j and recompute all the priorities of all the pairs (R,k)
448
// still available.
449
for
(
Size
k
= 1;
k
<
tabsize
; ++
k
) {
450
// get the combination to perform and do it
451
pair
=
queue
.
pop
();
452
const
Size
ti
=
pair
.
first
;
453
const
Size
tj
=
pair
.
second
;
454
455
// compute the result
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
]);
460
461
Size
new_size
=
Size
(1);
462
463
for
(
const
auto
ptrVar
:
seq1
) {
464
if
(
std
::
numeric_limits
<
Size
>::
max
() /
ptrVar
->
domainSize
() <
new_size
) {
465
GUM_ERROR
(
OutOfBounds
,
"memory usage out of long int range"
);
466
}
467
468
new_size
*=
ptrVar
->
domainSize
();
469
470
new_seq
->
insert
(
ptrVar
);
471
}
472
473
for
(
const
auto
ptrVar
:
seq2
) {
474
if
(!
seq1
.
exists
(
ptrVar
)) {
475
if
(
std
::
numeric_limits
<
Size
>::
max
() /
ptrVar
->
domainSize
()
476
<
new_size
) {
477
GUM_ERROR
(
OutOfBounds
,
"memory usage out of long int range"
);
478
}
479
480
new_size
*=
ptrVar
->
domainSize
();
481
482
new_seq
->
insert
(
ptrVar
);
483
}
484
}
485
486
if
(
std
::
numeric_limits
<
Size
>::
max
() -
current_memory
<
new_size
) {
487
GUM_ERROR
(
OutOfBounds
,
"memory usage out of long int range"
);
488
}
489
490
current_memory
+=
new_size
;
491
492
if
(
current_memory
>
max_memory
) {
max_memory
=
current_memory
; }
493
494
// substitute tables[pair.first] by the result
495
if
(
tables
[
ti
] &&
is_t_new
[
ti
]) {
496
delete
tables
[
ti
];
497
current_memory
-=
table_size
[
ti
];
498
}
499
500
if
(
tables
[
tj
] &&
is_t_new
[
tj
]) {
501
delete
tables
[
tj
];
502
current_memory
-=
table_size
[
tj
];
503
}
504
505
tables
[
ti
] =
new_seq
;
506
table_size
[
ti
] =
new_size
;
507
is_t_new
[
ti
] =
true
;
508
509
tables
[
tj
] =
nullptr
;
510
511
// remove all the pairs involving tj in the priority queue
512
for
(
Size
ind
= 0;
ind
<
tj
; ++
ind
) {
513
if
(
tables
[
ind
] !=
nullptr
) {
514
pair
.
first
=
ind
;
515
queue
.
erase
(
pair
);
516
}
517
}
518
519
pair
.
first
=
tj
;
520
521
for
(
Size
ind
=
tj
+ 1;
ind
<
tabsize
; ++
ind
) {
522
if
(
tables
[
ind
] !=
nullptr
) {
523
pair
.
second
=
ind
;
524
queue
.
erase
(
pair
);
525
}
526
}
527
528
// update the "combined" size of all the pairs involving "new_seq"
529
{
530
pair
.
second
=
ti
;
531
Size
newsize
;
532
533
for
(
Size
ind
=
Size
(0);
ind
<
ti
; ++
ind
) {
534
if
(
tables
[
ind
] !=
nullptr
) {
535
pair
.
first
=
ind
;
536
newsize
=
combinedSize_
(*
new_seq
, *(
tables
[
ind
]));
537
queue
.
setPriority
(
pair
,
newsize
);
538
}
539
}
540
541
pair
.
first
=
ti
;
542
543
for
(
Size
ind
=
ti
+ 1;
ind
<
tabsize
; ++
ind
) {
544
if
(
tables
[
ind
] !=
nullptr
) {
545
pair
.
second
=
ind
;
546
newsize
=
combinedSize_
(*
new_seq
, *(
tables
[
ind
]));
547
queue
.
setPriority
(
pair
,
newsize
);
548
}
549
}
550
}
551
}
552
553
// here, there remains only one nonzero pointer in tables:
554
// the result of our combination
555
Size
k
=
Size
(0);
556
while
(!
tables
[
k
])
557
++
k
;
558
559
delete
tables
[
k
];
560
561
return
std
::
pair
<
long
,
long
>(
long
(
max_memory
),
long
(
current_memory
));
562
}
563
564
// returns the memory consumption used during the combination
565
template
<
typename
GUM_SCALAR
,
template
<
typename
>
class
TABLE
>
566
std
::
pair
<
long
,
long
>
567
MultiDimCombinationDefault
<
GUM_SCALAR
,
TABLE
>::
memoryUsage
(
568
const
Set
<
const
TABLE
<
GUM_SCALAR
>* >&
set
)
const
{
569
// check if the set passed in argument is empty.
570
if
(
set
.
size
() < 2)
return
std
::
pair
<
long
,
long
>(0, 0);
571
572
// create the set of sets of discrete variables involved in the tables
573
Set
<
const
Sequence
<
const
DiscreteVariable
* >* >
var_set
(
set
.
size
());
574
575
for
(
const
auto
ptrTab
:
set
) {
576
var_set
<< &(
ptrTab
->
variablesSequence
());
577
}
578
579
return
memoryUsage
(
var_set
);
580
}
581
582
}
/* namespace gum */
583
584
#
endif
/* DOXYGEN_SHOULD_SKIP_THIS */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669