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