aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
SVED_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 Inline implementation of SVED.
25
*
26
* @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27
*/
28
#
include
<
agrum
/
PRM
/
inference
/
SVED
.
h
>
29
30
namespace
gum
{
31
namespace
prm
{
32
33
template
<
typename
GUM_SCALAR
>
34
SVED
<
GUM_SCALAR
>::~
SVED
() {
35
GUM_DESTRUCTOR
(
SVED
);
36
37
for
(
const
auto
&
elt
:
_elim_orders_
)
38
delete
elt
.
second
;
39
40
if
(
_class_elim_order_
!=
nullptr
)
delete
_class_elim_order_
;
41
}
42
43
template
<
typename
GUM_SCALAR
>
44
void
SVED
<
GUM_SCALAR
>::
_eliminateNodes_
(
const
PRMInstance
<
GUM_SCALAR
>*
query
,
45
NodeId
node
,
46
BucketSet
&
pool
,
47
BucketSet
&
trash
) {
48
Set
<
const
PRMInstance
<
GUM_SCALAR
>* >
ignore
;
49
ignore
.
insert
(
query
);
50
// Extracting required attributes and slotchains
51
Set
<
NodeId
>&
attr_set
=
_getAttrSet_
(
query
);
52
Set
<
NodeId
>&
sc_set
=
_getSCSet_
(
query
);
53
// Downward elimination
54
List
<
const
PRMInstance
<
GUM_SCALAR
>* >
elim_list
;
55
56
for
(
const
auto
attr
:
attr_set
) {
57
try
{
58
for
(
auto
iter
=
query
->
getRefAttr
(
attr
).
begin
();
iter
!=
query
->
getRefAttr
(
attr
).
end
();
59
++
iter
)
60
if
((!
ignore
.
exists
(
iter
->
first
)) && (
_bb_
.
exists
(
iter
->
first
)))
61
_eliminateNodesDownward_
(
query
,
iter
->
first
,
pool
,
trash
,
elim_list
,
ignore
);
62
}
catch
(
NotFound
&) {
63
// Ok
64
}
65
}
66
67
// Eliminating all nodes in query instance, except query
68
InstanceBayesNet
<
GUM_SCALAR
>
bn
(*
query
);
69
DefaultTriangulation
t
(&(
bn
.
moralGraph
()), &(
bn
.
modalities
()));
70
std
::
vector
<
const
DiscreteVariable
* >
elim_order
;
71
72
if
(
this
->
hasEvidence
(
query
))
_insertEvidence_
(
query
,
pool
);
73
74
for
(
const
auto
attr
:
attr_set
)
75
pool
.
insert
(&(
const_cast
<
Potential
<
GUM_SCALAR
>& >(
query
->
get
(
attr
).
cpf
())));
76
77
for
(
size_t
idx
= 0;
idx
<
t
.
eliminationOrder
().
size
(); ++
idx
) {
78
if
(
t
.
eliminationOrder
()[
idx
] !=
node
) {
79
auto
var_id
=
t
.
eliminationOrder
()[
idx
];
80
const
auto
&
var
=
bn
.
variable
(
var_id
);
81
elim_order
.
push_back
(&
var
);
82
}
83
}
84
85
eliminateNodes
(
elim_order
,
pool
,
trash
);
86
// Eliminating instance in elim_list
87
List
<
const
PRMInstance
<
GUM_SCALAR
>* >
tmp_list
;
88
_reduceElimList_
(
query
,
elim_list
,
tmp_list
,
ignore
,
pool
,
trash
);
89
90
while
(!
elim_list
.
empty
()) {
91
if
(
_checkElimOrder_
(
query
,
elim_list
.
front
())) {
92
if
((!
ignore
.
exists
(
elim_list
.
front
())) && (
_bb_
.
exists
(
elim_list
.
front
())))
93
_eliminateNodesDownward_
(
query
,
elim_list
.
front
(),
pool
,
trash
,
elim_list
,
ignore
);
94
}
else
if
(
_bb_
.
exists
(
elim_list
.
front
())) {
95
tmp_list
.
insert
(
elim_list
.
front
());
96
}
97
98
elim_list
.
popFront
();
99
}
100
101
// Upward elimination
102
for
(
const
auto
chain
:
sc_set
)
103
for
(
const
auto
parent
:
query
->
getInstances
(
chain
))
104
if
((!
ignore
.
exists
(
parent
)) && (
_bb_
.
exists
(*
parent
)))
105
_eliminateNodesUpward_
(
parent
,
pool
,
trash
,
tmp_list
,
ignore
);
106
}
107
108
template
<
typename
GUM_SCALAR
>
109
void
SVED
<
GUM_SCALAR
>::
_eliminateNodesDownward_
(
110
const
PRMInstance
<
GUM_SCALAR
>*
from
,
111
const
PRMInstance
<
GUM_SCALAR
>*
i
,
112
BucketSet
&
pool
,
113
BucketSet
&
trash
,
114
List
<
const
PRMInstance
<
GUM_SCALAR
>* >&
elim_list
,
115
Set
<
const
PRMInstance
<
GUM_SCALAR
>* >&
ignore
) {
116
ignore
.
insert
(
i
);
117
// Extracting required attributes and slotchains
118
Set
<
NodeId
>&
attr_set
=
_getAttrSet_
(
i
);
119
Set
<
NodeId
>&
sc_set
=
_getSCSet_
(
i
);
120
// Calling elimination over child instance
121
List
<
const
PRMInstance
<
GUM_SCALAR
>* >
my_list
;
122
123
for
(
const
auto
attr
:
attr_set
) {
124
try
{
125
for
(
auto
iter
=
i
->
getRefAttr
(
attr
).
begin
();
iter
!=
i
->
getRefAttr
(
attr
).
end
(); ++
iter
)
126
if
((!
ignore
.
exists
(
iter
->
first
)) && (
_bb_
.
exists
(
iter
->
first
)))
127
_eliminateNodesDownward_
(
i
,
iter
->
first
,
pool
,
trash
,
my_list
,
ignore
);
128
}
catch
(
NotFound
&) {
129
// Ok
130
}
131
}
132
133
// Eliminating all nodes in current instance
134
if
(
this
->
hasEvidence
(
i
)) {
135
_eliminateNodesWithEvidence_
(
i
,
pool
,
trash
);
136
}
else
{
137
_insertLiftedNodes_
(
i
,
pool
,
trash
);
138
139
for
(
const
auto
agg
:
i
->
type
().
aggregates
())
140
if
(
_bb_
.
requisiteNodes
(
i
).
exists
(
agg
->
id
()))
pool
.
insert
(
_getAggPotential_
(
i
,
agg
));
141
142
try
{
143
InstanceBayesNet
<
GUM_SCALAR
>
bn
(*
i
);
144
std
::
vector
<
const
DiscreteVariable
* >
elim_order
;
145
146
for
(
auto
node
:
_getElimOrder_
(
i
->
type
())) {
147
const
auto
&
var
=
bn
.
variable
(
node
);
148
elim_order
.
push_back
(&
var
);
149
}
150
151
eliminateNodes
(
elim_order
,
pool
,
trash
);
152
}
catch
(
NotFound
&) {
153
// Raised if there is no inner nodes to eliminate
154
}
155
}
156
157
// Calling elimination over child's parents
158
while
(!
my_list
.
empty
()) {
159
if
(
_checkElimOrder_
(
i
,
my_list
.
front
())) {
160
if
((!
ignore
.
exists
(
my_list
.
front
())) && (
_bb_
.
exists
(
my_list
.
front
())))
161
_eliminateNodesDownward_
(
i
,
my_list
.
front
(),
pool
,
trash
,
my_list
,
ignore
);
162
}
else
if
(
_bb_
.
exists
(
my_list
.
front
())) {
163
elim_list
.
insert
(
my_list
.
front
());
164
}
165
166
my_list
.
popFront
();
167
}
168
169
// Adding parents instance to elim_list
170
for
(
const
auto
chain
:
sc_set
)
171
for
(
const
auto
parent
:
i
->
getInstances
(
chain
))
172
if
((!
ignore
.
exists
(
parent
)) &&
_bb_
.
exists
(
parent
) && (
parent
!=
from
))
173
elim_list
.
insert
(
parent
);
174
}
175
176
template
<
typename
GUM_SCALAR
>
177
void
SVED
<
GUM_SCALAR
>::
_eliminateNodesUpward_
(
178
const
PRMInstance
<
GUM_SCALAR
>*
i
,
179
BucketSet
&
pool
,
180
BucketSet
&
trash
,
181
List
<
const
PRMInstance
<
GUM_SCALAR
>* >&
elim_list
,
182
Set
<
const
PRMInstance
<
GUM_SCALAR
>* >&
ignore
) {
183
ignore
.
insert
(
i
);
184
// Extracting required attributes and slotchains
185
Set
<
NodeId
>&
attr_set
=
_getAttrSet_
(
i
);
186
Set
<
NodeId
>&
sc_set
=
_getSCSet_
(
i
);
187
188
// Downward elimination
189
for
(
const
auto
attr
:
attr_set
) {
190
try
{
191
for
(
auto
iter
=
i
->
getRefAttr
(
attr
).
begin
();
iter
!=
i
->
getRefAttr
(
attr
).
end
(); ++
iter
)
192
if
((!
ignore
.
exists
(
iter
->
first
)) && (
_bb_
.
exists
(
iter
->
first
)))
193
_eliminateNodesDownward_
(
i
,
iter
->
first
,
pool
,
trash
,
elim_list
,
ignore
);
194
}
catch
(
NotFound
&) {
195
// Ok
196
}
197
}
198
199
// Eliminating all nodes in i instance
200
if
(
this
->
hasEvidence
(
i
)) {
201
_eliminateNodesWithEvidence_
(
i
,
pool
,
trash
);
202
}
else
{
203
_insertLiftedNodes_
(
i
,
pool
,
trash
);
204
205
for
(
const
auto
agg
:
i
->
type
().
aggregates
())
206
if
(
_bb_
.
requisiteNodes
(
i
).
exists
(
agg
->
id
()))
pool
.
insert
(
_getAggPotential_
(
i
,
agg
));
207
208
try
{
209
InstanceBayesNet
<
GUM_SCALAR
>
bn
(*
i
);
210
std
::
vector
<
const
DiscreteVariable
* >
elim_order
;
211
212
for
(
auto
node
:
_getElimOrder_
(
i
->
type
())) {
213
const
auto
&
var
=
bn
.
variable
(
node
);
214
elim_order
.
push_back
(&
var
);
215
}
216
eliminateNodes
(
elim_order
,
pool
,
trash
);
217
}
catch
(
NotFound
&) {
218
// Raised if there is no inner nodes to eliminate
219
}
220
}
221
222
// Eliminating instance in elim_list
223
List
<
const
PRMInstance
<
GUM_SCALAR
>* >
tmp_list
;
224
225
while
(!
elim_list
.
empty
()) {
226
if
(
_checkElimOrder_
(
i
,
elim_list
.
front
())) {
227
if
((!
ignore
.
exists
(
elim_list
.
front
())) && (
_bb_
.
exists
(
elim_list
.
front
())))
228
_eliminateNodesDownward_
(
i
,
elim_list
.
front
(),
pool
,
trash
,
elim_list
,
ignore
);
229
}
else
if
(
_bb_
.
exists
(
elim_list
.
front
())) {
230
ignore
.
insert
(
elim_list
.
front
());
231
}
232
233
elim_list
.
popFront
();
234
}
235
236
// Upward elimination
237
for
(
const
auto
chain
:
sc_set
)
238
for
(
const
auto
parent
:
i
->
getInstances
(
chain
))
239
if
((!
ignore
.
exists
(
parent
)) && (
_bb_
.
exists
(
parent
)))
240
_eliminateNodesUpward_
(
parent
,
pool
,
trash
,
tmp_list
,
ignore
);
241
}
242
243
template
<
typename
GUM_SCALAR
>
244
void
SVED
<
GUM_SCALAR
>::
_eliminateNodesWithEvidence_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
245
BucketSet
&
pool
,
246
BucketSet
&
trash
) {
247
// Adding required evidences
248
for
(
const
auto
&
elt
:
this
->
evidence
(
i
))
249
if
(
_bb_
.
requisiteNodes
(
i
).
exists
(
elt
.
first
))
250
pool
.
insert
(
const_cast
<
Potential
<
GUM_SCALAR
>* >(
elt
.
second
));
251
252
// Adding potentials and eliminating the remaining nodes
253
for
(
const
auto
&
a
: *
i
)
254
if
(
_bb_
.
requisiteNodes
(
i
).
exists
(
a
.
first
))
255
pool
.
insert
(&(
const_cast
<
Potential
<
GUM_SCALAR
>& >(
a
.
second
->
cpf
())));
256
257
InstanceBayesNet
<
GUM_SCALAR
>
bn
(*
i
);
258
DefaultTriangulation
t
(&(
bn
.
moralGraph
()), &(
bn
.
modalities
()));
259
const
std
::
vector
<
NodeId
>&
full_elim_order
=
t
.
eliminationOrder
();
260
261
for
(
auto
var
=
full_elim_order
.
begin
();
var
!=
full_elim_order
.
end
(); ++
var
)
262
eliminateNode
(&(
i
->
get
(*
var
).
type
().
variable
()),
pool
,
trash
);
263
}
264
265
template
<
typename
GUM_SCALAR
>
266
void
SVED
<
GUM_SCALAR
>::
_insertLiftedNodes_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
267
BucketSet
&
pool
,
268
BucketSet
&
trash
) {
269
BucketSet
*
lifted_pool
=
nullptr
;
270
271
try
{
272
lifted_pool
=
_lifted_pools_
[&(
_bb_
.
requisiteNodes
(
i
))];
273
}
catch
(
NotFound
&) {
274
_initLiftedNodes_
(
i
,
trash
);
275
lifted_pool
=
_lifted_pools_
[&(
_bb_
.
requisiteNodes
(
i
))];
276
}
277
278
for
(
const
auto
lifted_pot
: *
lifted_pool
) {
279
Potential
<
GUM_SCALAR
>*
pot
=
copyPotential
(
i
->
bijection
(), *
lifted_pot
);
280
pool
.
insert
(
pot
);
281
trash
.
insert
(
pot
);
282
}
283
}
284
285
template
<
typename
GUM_SCALAR
>
286
void
SVED
<
GUM_SCALAR
>::
_initLiftedNodes_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
287
BucketSet
&
trash
) {
288
PRMClass
<
GUM_SCALAR
>&
c
=
const_cast
<
PRMClass
<
GUM_SCALAR
>& >(
i
->
type
());
289
BucketSet
*
lifted_pool
=
new
BucketSet
();
290
_lifted_pools_
.
insert
(&(
_bb_
.
requisiteNodes
(
i
)),
lifted_pool
);
291
292
for
(
const
auto
node
:
_bb_
.
requisiteNodes
(
i
))
293
if
(
PRMClassElement
<
GUM_SCALAR
>::
isAttribute
(
c
.
get
(
node
)))
294
lifted_pool
->
insert
(
const_cast
<
Potential
<
GUM_SCALAR
>* >(&(
c
.
get
(
node
).
cpf
())));
295
296
NodeSet
inners
,
outers
,
ignore
;
297
298
for
(
const
auto
&
elt
: *
i
) {
299
if
(
_bb_
.
requisiteNodes
(*
i
).
exists
(
elt
.
first
)) {
300
if
(
PRMClassElement
<
GUM_SCALAR
>::
isAttribute
(
c
.
get
(
elt
.
first
))) {
301
if
(
c
.
isOutputNode
(
c
.
get
(
elt
.
first
)))
302
outers
.
insert
(
elt
.
first
);
303
else
if
(!
outers
.
exists
(
elt
.
first
))
304
inners
.
insert
(
elt
.
first
);
305
}
else
if
(
PRMClassElement
<
GUM_SCALAR
>::
isAggregate
(
c
.
get
(
elt
.
first
))) {
306
outers
.
insert
(
elt
.
first
);
307
308
// We need to put in the output_elim_order aggregator's parents
309
// which are
310
// innner nodes
311
for
(
const
auto
par
:
c
.
containerDag
().
parents
(
elt
.
first
))
312
if
(
PRMClassElement
<
GUM_SCALAR
>::
isAttribute
(
i
->
type
().
get
(
par
))
313
&&
i
->
type
().
isInnerNode
(
i
->
type
().
get
(
par
))
314
&&
_bb_
.
requisiteNodes
(
i
).
exists
(
par
)) {
315
inners
.
erase
(
par
);
316
outers
.
insert
(
par
);
317
}
318
}
319
}
else
{
320
ignore
.
insert
(
elt
.
first
);
321
}
322
}
323
324
// Now we proceed with the elimination of inner attributes
325
ClassBayesNet
<
GUM_SCALAR
>
bn
(
c
);
326
List
<
NodeSet
>
partial_ordering
;
327
328
if
(
inners
.
size
())
partial_ordering
.
pushBack
(
inners
);
329
330
if
(
outers
.
size
())
partial_ordering
.
pushBack
(
outers
);
331
332
if
(
ignore
.
size
())
partial_ordering
.
pushBack
(
ignore
);
333
334
GUM_ASSERT
(
inners
.
size
() ||
outers
.
size
());
335
PartialOrderedTriangulation
t
(&(
bn
.
moralGraph
()), &(
bn
.
modalities
()), &
partial_ordering
);
336
337
for
(
size_t
idx
= 0;
idx
<
inners
.
size
(); ++
idx
)
338
eliminateNode
(&(
c
.
get
(
t
.
eliminationOrder
()[
idx
]).
type
().
variable
()), *
lifted_pool
,
trash
);
339
340
// If there is not only inner and input Attributes
341
if
(
outers
.
size
()) {
342
_elim_orders_
.
insert
(&
c
,
343
new
std
::
vector
<
NodeId
>(
t
.
eliminationOrder
().
begin
() +
inners
.
size
(),
344
t
.
eliminationOrder
().
end
()));
345
}
346
}
347
348
template
<
typename
GUM_SCALAR
>
349
void
SVED
<
GUM_SCALAR
>::
_initElimOrder_
() {
350
ClassDependencyGraph
<
GUM_SCALAR
>
cdg
(*(
this
->
prm_
));
351
Sequence
<
const
PRMClassElementContainer
<
GUM_SCALAR
>* >
class_elim_order
;
352
std
::
list
<
NodeId
>
l
;
353
354
for
(
const
auto
node
:
cdg
.
dag
().
nodes
()) {
355
if
(
cdg
.
dag
().
parents
(
node
).
empty
()) {
l
.
push_back
(
node
); }
356
}
357
358
Set
<
NodeId
>
visited_node
;
359
360
while
(!
l
.
empty
()) {
361
visited_node
.
insert
(
l
.
front
());
362
363
if
(!
class_elim_order
.
exists
(
cdg
.
get
(
l
.
front
()).
first
)) {
364
class_elim_order
.
insert
(
cdg
.
get
(
l
.
front
()).
first
);
365
}
366
367
for
(
const
auto
child
:
cdg
.
dag
().
children
(
l
.
front
())) {
368
if
(!
visited_node
.
contains
(
child
)) {
l
.
push_back
(
child
); }
369
}
370
371
l
.
pop_front
();
372
}
373
374
_class_elim_order_
=
new
Sequence
<
std
::
string
>();
375
for
(
auto
c
:
class_elim_order
) {
376
std
::
string
name
=
c
->
name
();
377
auto
pos
=
name
.
find_first_of
(
"<"
);
378
if
(
pos
!=
std
::
string
::
npos
) {
name
=
name
.
substr
(0,
pos
); }
379
try
{
380
_class_elim_order_
->
insert
(
name
);
381
}
catch
(
DuplicateElement
&) {}
382
}
383
}
384
385
template
<
typename
GUM_SCALAR
>
386
void
SVED
<
GUM_SCALAR
>::
posterior_
(
const
Chain
&
chain
,
Potential
<
GUM_SCALAR
>&
m
) {
387
const
PRMInstance
<
GUM_SCALAR
>*
i
=
chain
.
first
;
388
const
PRMAttribute
<
GUM_SCALAR
>*
elt
=
chain
.
second
;
389
SVED
<
GUM_SCALAR
>::
BucketSet
pool
,
trash
;
390
_bb_
.
compute
(
i
,
elt
->
id
());
391
_eliminateNodes_
(
i
,
elt
->
id
(),
pool
,
trash
);
392
393
std
::
vector
<
const
Potential
<
GUM_SCALAR
>* >
result
;
394
for
(
auto
pot
:
pool
) {
395
if
(
pot
->
contains
(*(
m
.
variablesSequence
().
atPos
(0))))
result
.
push_back
(
pot
);
396
}
397
398
while
(
result
.
size
() > 1) {
399
const
auto
&
p1
= *(
result
.
back
());
400
result
.
pop_back
();
401
const
auto
&
p2
= *(
result
.
back
());
402
result
.
pop_back
();
403
auto
mult
=
new
Potential
<
GUM_SCALAR
>(
p1
*
p2
);
404
result
.
push_back
(
mult
);
405
trash
.
insert
(
mult
);
406
}
407
408
m
= *(
result
.
back
());
409
m
.
normalize
();
410
411
GUM_ASSERT
(
m
.
nbrDim
() == (
Size
)1);
412
413
// cleaning up the mess
414
for
(
const
auto
pot
:
trash
)
415
delete
pot
;
416
417
for
(
const
auto
&
elt
:
_lifted_pools_
)
418
delete
elt
.
second
;
419
420
_lifted_pools_
.
clear
();
421
422
for
(
const
auto
&
elt
:
_req_set_
) {
423
delete
elt
.
second
.
first
;
424
delete
elt
.
second
.
second
;
425
}
426
427
_req_set_
.
clear
();
428
429
for
(
const
auto
elt
:
_elim_orders_
)
430
delete
elt
.
second
;
431
432
_elim_orders_
.
clear
();
433
}
434
435
template
<
typename
GUM_SCALAR
>
436
void
SVED
<
GUM_SCALAR
>::
joint_
(
const
std
::
vector
<
Chain
>&
queries
,
437
Potential
<
GUM_SCALAR
>&
j
) {
438
GUM_ERROR
(
FatalError
,
"Not implemented."
)
439
}
440
441
template
<
typename
GUM_SCALAR
>
442
void
SVED
<
GUM_SCALAR
>::
_initReqSets_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
) {
443
Set
<
NodeId
>*
attr_set
=
new
Set
<
NodeId
>();
444
Set
<
NodeId
>*
sc_set
=
new
Set
<
NodeId
>();
445
446
for
(
const
auto
node
:
_bb_
.
requisiteNodes
(
i
)) {
447
switch
(
i
->
type
().
get
(
node
).
elt_type
()) {
448
case
PRMClassElement
<
GUM_SCALAR
>::
prm_aggregate
:
449
case
PRMClassElement
<
GUM_SCALAR
>::
prm_attribute
: {
450
attr_set
->
insert
(
node
);
451
break
;
452
}
453
454
case
PRMClassElement
<
GUM_SCALAR
>::
prm_slotchain
: {
455
sc_set
->
insert
(
node
);
456
break
;
457
}
458
459
default
: {
460
GUM_ERROR
(
FatalError
,
461
"There should not be elements other"
462
" than PRMAttribute<GUM_SCALAR> and SlotChain."
);
463
}
464
}
465
}
466
467
_req_set_
.
insert
(&(
_bb_
.
requisiteNodes
(
i
)),
468
std
::
pair
<
Set
<
NodeId
>*,
Set
<
NodeId
>* >(
attr_set
,
sc_set
));
469
}
470
471
template
<
typename
GUM_SCALAR
>
472
INLINE
SVED
<
GUM_SCALAR
>::
SVED
(
const
PRM
<
GUM_SCALAR
>&
prm
,
473
const
PRMSystem
<
GUM_SCALAR
>&
model
) :
474
PRMInference
<
GUM_SCALAR
>(
prm
,
model
),
475
_class_elim_order_
(0),
_bb_
(*
this
) {
476
GUM_CONSTRUCTOR
(
SVED
);
477
}
478
479
480
template
<
typename
GUM_SCALAR
>
481
INLINE
void
SVED
<
GUM_SCALAR
>::
_insertEvidence_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
482
BucketSet
&
pool
) {
483
for
(
const
auto
&
elt
:
this
->
evidence
(
i
))
484
pool
.
insert
(
const_cast
<
Potential
<
GUM_SCALAR
>* >(
elt
.
second
));
485
}
486
487
template
<
typename
GUM_SCALAR
>
488
INLINE
std
::
vector
<
NodeId
>&
489
SVED
<
GUM_SCALAR
>::
_getElimOrder_
(
const
PRMClass
<
GUM_SCALAR
>&
c
) {
490
return
*(
_elim_orders_
[&
c
]);
491
}
492
493
template
<
typename
GUM_SCALAR
>
494
INLINE
std
::
string
SVED
<
GUM_SCALAR
>::
_trim_
(
const
std
::
string
&
s
) {
495
auto
pos
=
s
.
find_first_of
(
"<"
);
496
if
(
pos
!=
std
::
string
::
npos
) {
return
s
.
substr
(0,
pos
); }
497
return
s
;
498
}
499
500
template
<
typename
GUM_SCALAR
>
501
INLINE
bool
SVED
<
GUM_SCALAR
>::
_checkElimOrder_
(
const
PRMInstance
<
GUM_SCALAR
>*
first
,
502
const
PRMInstance
<
GUM_SCALAR
>*
second
) {
503
if
(
_class_elim_order_
== 0) {
_initElimOrder_
(); }
504
505
auto
first_name
=
_trim_
(
first
->
type
().
name
());
506
auto
second_name
=
_trim_
(
second
->
type
().
name
());
507
return
(
_class_elim_order_
->
pos
(
first_name
) <=
_class_elim_order_
->
pos
(
second_name
));
508
}
509
510
template
<
typename
GUM_SCALAR
>
511
INLINE
Potential
<
GUM_SCALAR
>*
512
SVED
<
GUM_SCALAR
>::
_getAggPotential_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
513
const
PRMAggregate
<
GUM_SCALAR
>*
agg
) {
514
return
&(
const_cast
<
Potential
<
GUM_SCALAR
>& >(
i
->
get
(
agg
->
safeName
()).
cpf
()));
515
}
516
517
template
<
typename
GUM_SCALAR
>
518
INLINE
void
519
SVED
<
GUM_SCALAR
>::
evidenceAdded_
(
const
typename
SVED
<
GUM_SCALAR
>::
Chain
&
chain
) {
520
// Do nothing
521
}
522
523
template
<
typename
GUM_SCALAR
>
524
INLINE
void
525
SVED
<
GUM_SCALAR
>::
evidenceRemoved_
(
const
typename
SVED
<
GUM_SCALAR
>::
Chain
&
chain
) {
526
// Do nothing
527
}
528
529
template
<
typename
GUM_SCALAR
>
530
INLINE
Set
<
NodeId
>&
SVED
<
GUM_SCALAR
>::
_getAttrSet_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
) {
531
try
{
532
return
*(
_req_set_
[&(
_bb_
.
requisiteNodes
(
i
))].
first
);
533
}
catch
(
NotFound
&) {
534
_initReqSets_
(
i
);
535
return
*(
_req_set_
[&(
_bb_
.
requisiteNodes
(
i
))].
first
);
536
}
537
}
538
539
template
<
typename
GUM_SCALAR
>
540
INLINE
Set
<
NodeId
>&
SVED
<
GUM_SCALAR
>::
_getSCSet_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
) {
541
try
{
542
return
*(
_req_set_
[&(
_bb_
.
requisiteNodes
(
i
))].
second
);
543
}
catch
(
NotFound
&) {
544
_initReqSets_
(
i
);
545
return
*(
_req_set_
[&(
_bb_
.
requisiteNodes
(
i
))].
second
);
546
}
547
}
548
549
template
<
typename
GUM_SCALAR
>
550
INLINE
void
551
SVED
<
GUM_SCALAR
>::
_reduceElimList_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
552
List
<
const
PRMInstance
<
GUM_SCALAR
>* >&
elim_list
,
553
List
<
const
PRMInstance
<
GUM_SCALAR
>* >&
reduced_list
,
554
Set
<
const
PRMInstance
<
GUM_SCALAR
>* >&
ignore
,
555
BucketSet
&
pool
,
556
BucketSet
&
trash
) {
557
while
(!
elim_list
.
empty
()) {
558
if
(
_checkElimOrder_
(
i
,
elim_list
.
front
())) {
559
if
((!
ignore
.
exists
(
elim_list
.
front
())) && (
_bb_
.
exists
(
elim_list
.
front
()))) {
560
_eliminateNodesDownward_
(
i
,
elim_list
.
front
(),
pool
,
trash
,
elim_list
,
ignore
);
561
}
562
}
else
if
(
_bb_
.
exists
(
elim_list
.
front
())) {
563
reduced_list
.
insert
(
elim_list
.
front
());
564
}
565
566
elim_list
.
popFront
();
567
}
568
}
569
570
template
<
typename
GUM_SCALAR
>
571
INLINE
std
::
string
SVED
<
GUM_SCALAR
>::
name
()
const
{
572
return
"SVED"
;
573
}
574
575
}
/* namespace prm */
576
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643
gum::prm::ParamScopeData::ParamScopeData
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)
Definition:
PRMClass_tpl.h:1032