aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
structuredBayesBall_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 StructuredBayesBall.
25
*
26
* @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27
*/
28
29
#
include
<
agrum
/
PRM
/
inference
/
structuredBayesBall
.
h
>
30
31
namespace
gum
{
32
namespace
prm
{
33
34
template
<
typename
GUM_SCALAR
>
35
StructuredBayesBall
<
GUM_SCALAR
>::~
StructuredBayesBall
() {
36
GUM_DESTRUCTOR
(
StructuredBayesBall
);
37
38
for
(
const
auto
&
elt
:
_reqMap_
)
39
delete
elt
.
second
.
first
;
40
}
41
42
template
<
typename
GUM_SCALAR
>
43
void
StructuredBayesBall
<
GUM_SCALAR
>::
_clean_
() {
44
for
(
const
auto
&
elt
:
_reqMap_
)
45
delete
elt
.
second
.
first
;
46
47
_keyMap_
.
clear
();
48
_reqMap_
.
clear
();
49
}
50
51
template
<
typename
GUM_SCALAR
>
52
bool
StructuredBayesBall
<
GUM_SCALAR
>::
_isHardEvidence_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
53
NodeId
n
) {
54
try
{
55
typename
PRMInference
<
GUM_SCALAR
>::
Chain
chain
=
std
::
make_pair
(
i
, &(
i
->
get
(
n
)));
56
57
if
(
_inf_
->
hasEvidence
(
chain
)) {
58
const
Potential
<
GUM_SCALAR
>*
e
=
_inf_
->
evidence
(
i
)[
n
];
59
Instantiation
inst
(
e
);
60
Size
count
= 0;
61
62
for
(
inst
.
setFirst
(); !
inst
.
end
();
inst
.
inc
()) {
63
if
((
e
->
get
(
inst
) == (
GUM_SCALAR
)1.0))
64
++
count
;
65
else
if
(
e
->
get
(
inst
) != (
GUM_SCALAR
)0.0)
66
return
false
;
67
}
68
69
return
(
count
== 1);
70
}
71
72
return
false
;
73
}
catch
(
NotFound
&) {
return
false
; }
74
}
75
76
template
<
typename
GUM_SCALAR
>
77
void
StructuredBayesBall
<
GUM_SCALAR
>::
_compute_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
78
NodeId
n
) {
79
_clean_
();
80
/// Key = instance.PRMClassElement<GUM_DATA>
81
/// pair = <upper mark, lower mark>
82
StructuredBayesBall
<
GUM_SCALAR
>::
InstanceMap
marks
;
83
_fromChild_
(
i
,
n
,
marks
);
84
_fillMaps_
(
marks
);
85
86
for
(
const
auto
&
elt
:
marks
)
87
delete
elt
.
second
;
88
}
89
90
template
<
typename
GUM_SCALAR
>
91
void
StructuredBayesBall
<
GUM_SCALAR
>::
_fromChild_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
92
NodeId
n
,
93
InstanceMap
&
marks
) {
94
if
(!
marks
.
exists
(
i
)) {
marks
.
insert
(
i
,
new
StructuredBayesBall
<
GUM_SCALAR
>::
MarkMap
()); }
95
96
if
(!
marks
[
i
]->
exists
(
n
)) {
marks
[
i
]->
insert
(
n
,
std
::
pair
<
bool
,
bool
>(
false
,
false
)); }
97
98
// Sending message to parents
99
switch
(
i
->
type
().
get
(
n
).
elt_type
()) {
100
case
PRMClassElement
<
GUM_SCALAR
>::
prm_slotchain
: {
101
if
(!
_getMark_
(
marks
,
i
,
n
).
first
) {
102
_getMark_
(
marks
,
i
,
n
).
first
=
true
;
103
104
for
(
const
auto
inst
:
i
->
getInstances
(
n
))
105
_fromChild_
(
inst
,
inst
->
get
(
_getSC_
(
i
,
n
).
lastElt
().
safeName
()).
id
(),
marks
);
106
}
107
108
if
(!
_getMark_
(
marks
,
i
,
n
).
second
) {
109
_getMark_
(
marks
,
i
,
n
).
second
=
true
;
110
111
for
(
const
auto
chi
:
i
->
type
().
containerDag
().
children
(
n
))
112
_fromParent_
(
i
,
chi
,
marks
);
113
}
114
115
break
;
116
}
117
118
case
PRMClassElement
<
GUM_SCALAR
>::
prm_aggregate
:
119
case
PRMClassElement
<
GUM_SCALAR
>::
prm_attribute
: {
120
if
(!
_getMark_
(
marks
,
i
,
n
).
first
) {
121
_getMark_
(
marks
,
i
,
n
).
first
=
true
;
122
123
if
(!
_isHardEvidence_
(
i
,
n
))
124
for
(
const
auto
par
:
i
->
type
().
containerDag
().
parents
(
n
))
125
_fromChild_
(
i
,
par
,
marks
);
126
}
127
128
if
(!
_getMark_
(
marks
,
i
,
n
).
second
) {
129
_getMark_
(
marks
,
i
,
n
).
second
=
true
;
130
131
// In i.
132
for
(
const
auto
chi
:
i
->
type
().
containerDag
().
children
(
n
))
133
_fromParent_
(
i
,
chi
,
marks
);
134
135
// Out of i.
136
try
{
137
const
auto
&
refs
=
i
->
getRefAttr
(
n
);
138
139
for
(
auto
iter
=
refs
.
begin
();
iter
!=
refs
.
end
(); ++
iter
)
140
_fromParent_
(
iter
->
first
,
iter
->
first
->
type
().
get
(
iter
->
second
).
id
(),
marks
);
141
}
catch
(
NotFound
&) {
142
// Not an inverse sc
143
}
144
}
145
146
break
;
147
}
148
149
default
: {
150
// We shouldn't reach any other PRMClassElement<GUM_DATA> than
151
// PRMAttribute
152
// or
153
// PRMSlotChain<GUM_SCALAR>.
154
GUM_ERROR
(
FatalError
,
"This case is impossible."
)
155
}
156
}
157
}
158
159
template
<
typename
GUM_SCALAR
>
160
void
StructuredBayesBall
<
GUM_SCALAR
>::
_fromParent_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
161
NodeId
n
,
162
InstanceMap
&
marks
) {
163
if
(!
marks
.
exists
(
i
)) {
marks
.
insert
(
i
,
new
StructuredBayesBall
<
GUM_SCALAR
>::
MarkMap
()); }
164
165
if
(!
marks
[
i
]->
exists
(
n
)) {
marks
[
i
]->
insert
(
n
,
std
::
pair
<
bool
,
bool
>(
false
,
false
)); }
166
167
// Concerns only PRMAttribute (because of the hard evidence)
168
if
((
_isHardEvidence_
(
i
,
n
)) && (!
_getMark_
(
marks
,
i
,
n
).
first
)) {
169
_getMark_
(
marks
,
i
,
n
).
first
=
true
;
170
171
for
(
const
auto
par
:
i
->
type
().
containerDag
().
parents
(
n
))
172
_fromChild_
(
i
,
par
,
marks
);
173
}
else
if
(!
_getMark_
(
marks
,
i
,
n
).
second
) {
174
_getMark_
(
marks
,
i
,
n
).
second
=
true
;
175
176
// In i.
177
for
(
const
auto
chi
:
i
->
type
().
containerDag
().
children
(
n
))
178
_fromParent_
(
i
,
chi
,
marks
);
179
180
// Out of i.
181
try
{
182
for
(
auto
iter
=
i
->
getRefAttr
(
n
).
begin
();
iter
!=
i
->
getRefAttr
(
n
).
end
(); ++
iter
)
183
_fromParent_
(
iter
->
first
,
iter
->
first
->
type
().
get
(
iter
->
second
).
id
(),
marks
);
184
}
catch
(
NotFound
&) {
185
// Not an inverse sc
186
}
187
}
188
}
189
190
template
<
typename
GUM_SCALAR
>
191
void
StructuredBayesBall
<
GUM_SCALAR
>::
_fillMaps_
(
InstanceMap
&
marks
) {
192
// First find for each instance it's requisite nodes
193
HashTable
<
const
PRMInstance
<
GUM_SCALAR
>*,
Set
<
NodeId
>* >
req_map
;
194
195
for
(
const
auto
&
elt
:
marks
) {
196
Set
<
NodeId
>*
req_set
=
new
Set
<
NodeId
>();
197
198
for
(
const
auto
&
elt2
: *
elt
.
second
)
199
if
(
elt2
.
second
.
first
)
req_set
->
insert
(
elt2
.
first
);
200
201
req_map
.
insert
(
elt
.
first
,
req_set
);
202
}
203
204
// Remove all instances with 0 requisite nodes
205
Set
<
const
PRMInstance
<
GUM_SCALAR
>* >
to_remove
;
206
207
for
(
const
auto
&
elt
:
req_map
)
208
if
(
elt
.
second
->
size
() == 0)
to_remove
.
insert
(
elt
.
first
);
209
210
for
(
const
auto
remo
:
to_remove
) {
211
delete
req_map
[
remo
];
212
req_map
.
erase
(
remo
);
213
}
214
215
// Fill _reqMap_ and _keyMap_
216
for
(
const
auto
&
elt
:
req_map
) {
217
std
::
string
key
=
_buildHashKey_
(
elt
.
first
, *
elt
.
second
);
218
219
if
(
_reqMap_
.
exists
(
key
)) {
220
_keyMap_
.
insert
(
elt
.
first
,
221
std
::
pair
<
std
::
string
,
Set
<
NodeId
>* >(
key
,
_reqMap_
[
key
].
first
));
222
_reqMap_
[
key
].
second
+= 1;
223
delete
elt
.
second
;
224
req_map
[
elt
.
first
] = 0;
225
}
else
{
226
_reqMap_
.
insert
(
key
,
std
::
pair
<
Set
<
NodeId
>*,
Size
>(
elt
.
second
, 1));
227
_keyMap_
.
insert
(
elt
.
first
,
std
::
pair
<
std
::
string
,
Set
<
NodeId
>* >(
key
,
elt
.
second
));
228
}
229
}
230
}
231
232
template
<
typename
GUM_SCALAR
>
233
std
::
string
234
StructuredBayesBall
<
GUM_SCALAR
>::
_buildHashKey_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
235
Set
<
NodeId
>&
req_nodes
) {
236
std
::
stringstream
sBuff
;
237
sBuff
<<
i
->
type
().
name
();
238
239
for
(
const
auto
node
:
i
->
type
().
containerDag
().
nodes
())
240
if
(
req_nodes
.
exists
(
node
))
sBuff
<<
"-"
<<
node
;
241
242
return
sBuff
.
str
();
243
}
244
245
template
<
typename
GUM_SCALAR
>
246
INLINE
StructuredBayesBall
<
GUM_SCALAR
>::
StructuredBayesBall
(
247
const
PRMInference
<
GUM_SCALAR
>&
inference
) :
248
_inf_
(&
inference
) {
249
GUM_CONSTRUCTOR
(
StructuredBayesBall
);
250
}
251
252
template
<
typename
GUM_SCALAR
>
253
INLINE
StructuredBayesBall
<
GUM_SCALAR
>::
StructuredBayesBall
(
254
const
StructuredBayesBall
<
GUM_SCALAR
>&
source
) :
255
_inf_
(0) {
256
GUM_CONS_CPY
(
StructuredBayesBall
);
257
GUM_ERROR
(
FatalError
,
"Not allowed."
)
258
}
259
260
template
<
typename
GUM_SCALAR
>
261
INLINE
StructuredBayesBall
<
GUM_SCALAR
>&
StructuredBayesBall
<
GUM_SCALAR
>::
operator
=(
262
const
StructuredBayesBall
<
GUM_SCALAR
>&
source
) {
263
GUM_ERROR
(
FatalError
,
"Not allowed."
)
264
}
265
266
template
<
typename
GUM_SCALAR
>
267
INLINE
const
std
::
string
&
268
StructuredBayesBall
<
GUM_SCALAR
>::
key
(
const
PRMInstance
<
GUM_SCALAR
>*
i
)
const
{
269
return
_keyMap_
[
i
].
first
;
270
}
271
272
template
<
typename
GUM_SCALAR
>
273
INLINE
const
std
::
string
&
274
StructuredBayesBall
<
GUM_SCALAR
>::
key
(
const
PRMInstance
<
GUM_SCALAR
>&
i
)
const
{
275
return
_keyMap_
[&
i
].
first
;
276
}
277
278
template
<
typename
GUM_SCALAR
>
279
INLINE
const
Set
<
NodeId
>&
280
StructuredBayesBall
<
GUM_SCALAR
>::
requisiteNodes
(
const
PRMInstance
<
GUM_SCALAR
>*
i
)
const
{
281
return
*(
_keyMap_
[
i
].
second
);
282
}
283
284
template
<
typename
GUM_SCALAR
>
285
INLINE
const
Set
<
NodeId
>&
286
StructuredBayesBall
<
GUM_SCALAR
>::
requisiteNodes
(
const
PRMInstance
<
GUM_SCALAR
>&
i
)
const
{
287
return
*(
_keyMap_
[&
i
].
second
);
288
}
289
290
template
<
typename
GUM_SCALAR
>
291
INLINE
Size
StructuredBayesBall
<
GUM_SCALAR
>::
occurrence
(
const
std
::
string
&
key
)
const
{
292
return
_reqMap_
[
key
].
second
;
293
}
294
295
template
<
typename
GUM_SCALAR
>
296
INLINE
float
StructuredBayesBall
<
GUM_SCALAR
>::
liftRatio
()
const
{
297
return
((
float
)
_reqMap_
.
size
()) / ((
float
)
_keyMap_
.
size
());
298
}
299
300
template
<
typename
GUM_SCALAR
>
301
INLINE
bool
302
StructuredBayesBall
<
GUM_SCALAR
>::
exists
(
const
PRMInstance
<
GUM_SCALAR
>*
i
)
const
{
303
return
_keyMap_
.
exists
(
i
);
304
}
305
306
template
<
typename
GUM_SCALAR
>
307
INLINE
bool
308
StructuredBayesBall
<
GUM_SCALAR
>::
exists
(
const
PRMInstance
<
GUM_SCALAR
>&
i
)
const
{
309
return
_keyMap_
.
exists
(&
i
);
310
}
311
312
template
<
typename
GUM_SCALAR
>
313
INLINE
void
StructuredBayesBall
<
GUM_SCALAR
>::
compute
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
314
NodeId
n
) {
315
_compute_
(
i
,
n
);
316
}
317
318
template
<
typename
GUM_SCALAR
>
319
INLINE
void
StructuredBayesBall
<
GUM_SCALAR
>::
compute
(
const
PRMInstance
<
GUM_SCALAR
>&
i
,
320
NodeId
n
) {
321
_compute_
(&
i
,
n
);
322
}
323
324
template
<
typename
GUM_SCALAR
>
325
INLINE
const
PRMSlotChain
<
GUM_SCALAR
>&
326
StructuredBayesBall
<
GUM_SCALAR
>::
_getSC_
(
const
PRMInstance
<
GUM_SCALAR
>*
i
,
NodeId
n
) {
327
return
static_cast
<
const
PRMSlotChain
<
GUM_SCALAR
>& >(
i
->
type
().
get
(
n
));
328
}
329
330
template
<
typename
GUM_SCALAR
>
331
INLINE
std
::
pair
<
bool
,
bool
>&
332
StructuredBayesBall
<
GUM_SCALAR
>::
_getMark_
(
InstanceMap
&
marks
,
333
const
PRMInstance
<
GUM_SCALAR
>*
i
,
334
NodeId
n
) {
335
return
(*(
marks
[
i
]))[
n
];
336
}
337
338
}
/* namespace prm */
339
}
/* 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