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