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