aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
graphicalModelInference_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 Implementation of the non pure virtual methods of class
25
* GraphicalModelInference.
26
*/
27
28
#
include
<
agrum
/
tools
/
graphicalModels
/
inference
/
graphicalModelInference
.
h
>
29
30
namespace
gum
{
31
32
33
// Default Constructor
34
template
<
typename
GUM_SCALAR >
35
GraphicalModelInference< GUM_SCALAR >::GraphicalModelInference(
const
GraphicalModel* model) :
36
_model_(model) {
37
_computeDomainSizes_();
38
39
GUM_CONSTRUCTOR(GraphicalModelInference);
40
}
41
42
43
// Default Constructor
44
template
<
typename
GUM_SCALAR
>
45
GraphicalModelInference
<
GUM_SCALAR
>::
GraphicalModelInference
() {
46
GUM_CONSTRUCTOR
(
GraphicalModelInference
);
47
}
48
49
50
// Destructor
51
template
<
typename
GUM_SCALAR
>
52
GraphicalModelInference
<
GUM_SCALAR
>::~
GraphicalModelInference
() {
53
// clear all evidence.
54
// Warning: Do not use method eraseAllEvidence () because it contains a call
55
// to pure virtual method onAllEvidenceErased_ which belongs to an inherited
56
// instance and, therefore, does not exist anymore when
57
// ~GraphicalModelInference () is called
58
for
(
const
auto
&
pair
:
_evidence_
) {
59
if
(
pair
.
second
!=
nullptr
) {
delete
(
pair
.
second
); }
60
}
61
62
GUM_DESTRUCTOR
(
GraphicalModelInference
);
63
}
64
65
66
// returns whether the inference object is in a ready state
67
template
<
typename
GUM_SCALAR
>
68
INLINE
bool
GraphicalModelInference
<
GUM_SCALAR
>::
isInferenceReady
()
const
noexcept
{
69
return
(
_state_
==
StateOfInference
::
ReadyForInference
);
70
}
71
// returns whether the inference object is in a OutdatedStructure state
72
template
<
typename
GUM_SCALAR
>
73
INLINE
bool
GraphicalModelInference
<
GUM_SCALAR
>::
isInferenceOutdatedStructure
()
const
noexcept
{
74
return
(
_state_
==
StateOfInference
::
OutdatedStructure
);
75
}
76
// returns whether the inference object is in a OutdatedPotential state
77
template
<
typename
GUM_SCALAR
>
78
INLINE
bool
79
GraphicalModelInference
<
GUM_SCALAR
>::
isInferenceOutdatedPotentials
()
const
noexcept
{
80
return
(
_state_
==
StateOfInference
::
OutdatedPotentials
);
81
}
82
// returns whether the inference object is in a InferenceDone state
83
template
<
typename
GUM_SCALAR
>
84
INLINE
bool
GraphicalModelInference
<
GUM_SCALAR
>::
isInferenceDone
()
const
noexcept
{
85
return
(
_state_
==
StateOfInference
::
Done
);
86
}
87
88
89
// returns the state of the inference engine
90
template
<
typename
GUM_SCALAR
>
91
INLINE
typename
GraphicalModelInference
<
GUM_SCALAR
>::
StateOfInference
92
GraphicalModelInference
<
GUM_SCALAR
>::
state
()
const
noexcept
{
93
return
_state_
;
94
}
95
96
// set the state of the inference
97
template
<
typename
GUM_SCALAR
>
98
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
setState_
(
const
StateOfInference
state
) {
99
if
(
_state_
!=
state
) {
100
_state_
=
state
;
101
onStateChanged_
();
102
}
103
}
104
105
// Returns a constant reference over the IBayesNet referenced by this class
106
template
<
typename
GUM_SCALAR
>
107
INLINE
const
GraphicalModel
&
GraphicalModelInference
<
GUM_SCALAR
>::
model
()
const
{
108
if
(
_model_
==
nullptr
)
109
GUM_ERROR
(
UndefinedElement
,
110
"No Bayes net has been assigned to "
111
"the inference algorithm."
);
112
return
*
_model_
;
113
}
114
115
116
// assigns a new BN to the inference engine
117
template
<
typename
GUM_SCALAR
>
118
void
GraphicalModelInference
<
GUM_SCALAR
>::
setModel_
(
const
GraphicalModel
*
model
) {
119
clear
();
120
_model_
=
model
;
121
_computeDomainSizes_
();
122
onModelChanged_
(
model
);
123
setState_
(
StateOfInference
::
OutdatedStructure
);
124
}
125
126
127
// assigns a BN to a newly constructed inference engine
128
template
<
typename
GUM_SCALAR
>
129
void
GraphicalModelInference
<
GUM_SCALAR
>::
setModelDuringConstruction_
(
130
const
GraphicalModel
*
model
) {
131
_model_
=
model
;
132
_computeDomainSizes_
();
133
setState_
(
StateOfInference
::
OutdatedStructure
);
134
}
135
136
137
// clears all the data structures allocated for the last inference
138
template
<
typename
GUM_SCALAR
>
139
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
clear
() {
140
eraseAllEvidence
();
141
setState_
(
StateOfInference
::
OutdatedStructure
);
142
}
143
144
145
/// computes the domain sizes of the random variables
146
template
<
typename
GUM_SCALAR
>
147
void
GraphicalModelInference
<
GUM_SCALAR
>::
_computeDomainSizes_
() {
148
_domain_sizes_
.
clear
();
149
if
(!
hasNoModel_
()) {
150
for
(
auto
node
:
_model_
->
nodes
()) {
151
_domain_sizes_
.
insert
(
node
,
_model_
->
variable
(
node
).
domainSize
());
152
}
153
}
154
}
155
156
157
// get the domain sizes of the random variables of the BN
158
template
<
typename
GUM_SCALAR
>
159
INLINE
const
NodeProperty
<
Size
>&
GraphicalModelInference
<
GUM_SCALAR
>::
domainSizes
()
const
{
160
return
_domain_sizes_
;
161
}
162
163
164
// ##############################################################################
165
// Evidence
166
// ##############################################################################
167
168
// create the internal structure for a hard evidence
169
template
<
typename
GUM_SCALAR
>
170
Potential
<
GUM_SCALAR
>
171
GraphicalModelInference
<
GUM_SCALAR
>::
_createHardEvidence_
(
NodeId
id
,
const
Idx
val
)
const
{
172
// check that it is possible to create the evidence
173
if
(
_model_
==
nullptr
)
174
GUM_ERROR
(
NullElement
,
175
"No Bayes net has been assigned to the "
176
"inference algorithm"
);
177
178
if
(!
_model_
->
exists
(
id
)) {
GUM_ERROR
(
UndefinedElement
,
id
<<
" is not a NodeId in the model"
) }
179
180
if
(
_model_
->
variable
(
id
).
domainSize
() <=
val
) {
181
GUM_ERROR
(
InvalidArgument
,
182
"node "
<<
_model_
->
variable
(
id
) <<
" has fewer possible values than "
<<
val
);
183
}
184
185
// create the deterministic potential
186
Potential
<
GUM_SCALAR
>
pot
;
187
pot
.
beginMultipleChanges
();
188
pot
<<
_model_
->
variable
(
id
);
189
pot
.
endMultipleChanges
(0.0);
190
191
Instantiation
I
(
pot
);
192
I
.
chgVal
(
_model_
->
variable
(
id
),
val
);
193
pot
.
set
(
I
, 1.0);
194
195
return
pot
;
196
}
197
198
199
// checks wether a potential corresponds to a hard evidence
200
template
<
typename
GUM_SCALAR
>
201
bool
GraphicalModelInference
<
GUM_SCALAR
>::
_isHardEvidence_
(
const
Potential
<
GUM_SCALAR
>&
pot
,
202
Idx
&
val
)
const
{
203
// checking if pot is determininstic
204
bool
notZero
=
false
;
205
Instantiation
I
(
pot
);
206
207
for
(
I
.
setFirst
(); !
I
.
end
();
I
.
inc
()) {
208
if
(
pot
[
I
] != 0.0) {
209
if
(
notZero
) {
// we already met a non-zero value
210
return
false
;
211
}
else
{
212
val
=
I
.
val
(0);
213
notZero
=
true
;
// this is the first met non-zero value
214
}
215
}
216
}
217
218
if
(!
notZero
) {
// we met no non-zero value
219
GUM_ERROR
(
FatalError
,
"Evidence of impossibility (vector of 0s)"
)
220
}
221
222
return
true
;
// pot is deterministic
223
}
224
225
226
// adds a new hard evidence on node id
227
template
<
typename
GUM_SCALAR
>
228
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
addEvidence
(
NodeId
id
,
const
Idx
val
) {
229
addEvidence
(
_createHardEvidence_
(
id
,
val
));
230
}
231
232
// adds a new hard evidence on node id
233
template
<
typename
GUM_SCALAR
>
234
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
addEvidence
(
const
std
::
string
&
nodeName
,
235
const
Idx
val
) {
236
addEvidence
(
this
->
model
().
idFromName
(
nodeName
),
val
);
237
}
238
239
// adds a new hard evidence on node id
240
template
<
typename
GUM_SCALAR
>
241
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
addEvidence
(
NodeId
id
,
242
const
std
::
string
&
label
) {
243
addEvidence
(
id
,
this
->
model
().
variable
(
id
)[
label
]);
244
}
245
246
// adds a new hard evidence on node id
247
template
<
typename
GUM_SCALAR
>
248
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
addEvidence
(
const
std
::
string
&
nodeName
,
249
const
std
::
string
&
label
) {
250
NodeId
id
=
this
->
model
().
idFromName
(
nodeName
);
251
addEvidence
(
id
,
this
->
model
().
variable
(
id
)[
label
]);
252
}
253
254
// adds a new evidence on node id (might be soft or hard)
255
template
<
typename
GUM_SCALAR
>
256
void
GraphicalModelInference
<
GUM_SCALAR
>::
addEvidence
(
NodeId
id
,
257
const
std
::
vector
<
GUM_SCALAR
>&
vals
) {
258
// checks that the evidence is meaningful
259
if
(
_model_
==
nullptr
)
260
GUM_ERROR
(
NullElement
,
261
"No Bayes net has been assigned to the "
262
"inference algorithm"
);
263
264
if
(!
_model_
->
exists
(
id
)) {
GUM_ERROR
(
UndefinedElement
,
id
<<
" is not a NodeId in the model"
) }
265
266
if
(
_model_
->
variable
(
id
).
domainSize
() !=
vals
.
size
()) {
267
GUM_ERROR
(
InvalidArgument
,
268
"node "
<<
_model_
->
variable
(
id
)
269
<<
" and its evidence vector have different sizes."
);
270
}
271
272
Potential
<
GUM_SCALAR
>
pot
;
273
pot
.
add
(
_model_
->
variable
(
id
));
274
pot
.
fillWith
(
vals
);
275
addEvidence
(
std
::
move
(
pot
));
276
}
277
278
// adds a new evidence on node id (might be soft or hard)
279
template
<
typename
GUM_SCALAR
>
280
void
GraphicalModelInference
<
GUM_SCALAR
>::
addEvidence
(
const
std
::
string
&
nodeName
,
281
const
std
::
vector
<
GUM_SCALAR
>&
vals
) {
282
addEvidence
(
this
->
model
().
idFromName
(
nodeName
),
vals
);
283
}
284
285
// adds a new evidence on node id (might be soft or hard)
286
template
<
typename
GUM_SCALAR
>
287
void
GraphicalModelInference
<
GUM_SCALAR
>::
addEvidence
(
Potential
<
GUM_SCALAR
>&&
pot
) {
288
// check if the potential corresponds to an evidence
289
if
(
pot
.
nbrDim
() != 1) {
GUM_ERROR
(
InvalidArgument
,
pot
<<
" is not mono-dimensional."
) }
290
if
(
_model_
==
nullptr
)
291
GUM_ERROR
(
NullElement
,
292
"No Bayes net has been assigned to the "
293
"inference algorithm"
);
294
295
NodeId
id
=
_model_
->
nodeId
(
pot
.
variable
(0));
296
297
if
(
hasEvidence
(
id
)) {
298
GUM_ERROR
(
InvalidArgument
,
299
" node "
<<
id
<<
" already has an evidence. Please use chgEvidence()."
);
300
}
301
302
// check whether we have a hard evidence (and also check whether the
303
// potential only contains 0 (in this case, this will automatically raise
304
// an exception) )
305
Idx
val
;
306
bool
is_hard_evidence
=
_isHardEvidence_
(
pot
,
val
);
307
308
// insert the evidence
309
_evidence_
.
insert
(
id
,
310
new
Potential
<
GUM_SCALAR
>(
std
::
forward
<
Potential
<
GUM_SCALAR
> >(
pot
)));
311
if
(
is_hard_evidence
) {
// pot is deterministic
312
_hard_evidence_
.
insert
(
id
,
val
);
313
_hard_evidence_nodes_
.
insert
(
id
);
314
}
else
{
315
_soft_evidence_nodes_
.
insert
(
id
);
316
}
317
setState_
(
StateOfInference
::
OutdatedStructure
);
318
onEvidenceAdded_
(
id
,
is_hard_evidence
);
319
}
320
321
322
// adds a new evidence on node id (might be soft or hard)
323
template
<
typename
GUM_SCALAR
>
324
INLINE
void
325
GraphicalModelInference
<
GUM_SCALAR
>::
addEvidence
(
const
Potential
<
GUM_SCALAR
>&
pot
) {
326
Potential
<
GUM_SCALAR
>
new_pot
(
pot
);
327
addEvidence
(
std
::
move
(
new_pot
));
328
}
329
330
331
/// adds a new list of evidence
332
template
<
typename
GUM_SCALAR
>
333
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
addListOfEvidence
(
334
const
List
<
const
Potential
<
GUM_SCALAR
>* >&
potlist
) {
335
for
(
const
auto
pot
:
potlist
)
336
addEvidence
(*
pot
);
337
}
338
339
340
/// adds a new set of evidence
341
template
<
typename
GUM_SCALAR
>
342
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
addSetOfEvidence
(
343
const
Set
<
const
Potential
<
GUM_SCALAR
>* >&
potset
) {
344
for
(
const
auto
pot
:
potset
)
345
addEvidence
(*
pot
);
346
}
347
348
349
// indicates whether some node(s) have received evidence
350
template
<
typename
GUM_SCALAR
>
351
INLINE
bool
GraphicalModelInference
<
GUM_SCALAR
>::
hasEvidence
()
const
{
352
return
!
_evidence_
.
empty
();
353
}
354
355
356
// indicates whether node id has received an evidence
357
template
<
typename
GUM_SCALAR
>
358
INLINE
bool
GraphicalModelInference
<
GUM_SCALAR
>::
hasEvidence
(
NodeId
id
)
const
{
359
return
_evidence_
.
exists
(
id
);
360
}
361
362
363
// indicates whether node id has received a hard evidence
364
template
<
typename
GUM_SCALAR
>
365
INLINE
bool
GraphicalModelInference
<
GUM_SCALAR
>::
hasHardEvidence
(
NodeId
id
)
const
{
366
return
_hard_evidence_nodes_
.
exists
(
id
);
367
}
368
369
370
// indicates whether node id has received a soft evidence
371
template
<
typename
GUM_SCALAR
>
372
INLINE
bool
GraphicalModelInference
<
GUM_SCALAR
>::
hasSoftEvidence
(
NodeId
id
)
const
{
373
return
_soft_evidence_nodes_
.
exists
(
id
);
374
}
375
376
377
// indicates whether node id has received an evidence
378
template
<
typename
GUM_SCALAR
>
379
INLINE
bool
380
GraphicalModelInference
<
GUM_SCALAR
>::
hasEvidence
(
const
std
::
string
&
nodeName
)
const
{
381
return
hasEvidence
(
this
->
model
().
idFromName
(
nodeName
));
382
}
383
384
385
// indicates whether node id has received a hard evidence
386
template
<
typename
GUM_SCALAR
>
387
INLINE
bool
388
GraphicalModelInference
<
GUM_SCALAR
>::
hasHardEvidence
(
const
std
::
string
&
nodeName
)
const
{
389
return
hasHardEvidence
(
this
->
model
().
idFromName
(
nodeName
));
390
}
391
392
393
// indicates whether node id has received a soft evidence
394
template
<
typename
GUM_SCALAR
>
395
INLINE
bool
396
GraphicalModelInference
<
GUM_SCALAR
>::
hasSoftEvidence
(
const
std
::
string
&
nodeName
)
const
{
397
return
hasSoftEvidence
(
this
->
model
().
idFromName
(
nodeName
));
398
}
399
400
// change the value of an already existing hard evidence
401
template
<
typename
GUM_SCALAR
>
402
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
chgEvidence
(
NodeId
id
,
const
Idx
val
) {
403
chgEvidence
(
_createHardEvidence_
(
id
,
val
));
404
}
405
406
// change the value of an already existing hard evidence
407
template
<
typename
GUM_SCALAR
>
408
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
chgEvidence
(
const
std
::
string
&
nodeName
,
409
const
Idx
val
) {
410
chgEvidence
(
this
->
model
().
idFromName
(
nodeName
),
val
);
411
}
412
413
// change the value of an already existing hard evidence
414
template
<
typename
GUM_SCALAR
>
415
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
chgEvidence
(
NodeId
id
,
416
const
std
::
string
&
label
) {
417
chgEvidence
(
id
,
this
->
model
().
variable
(
id
)[
label
]);
418
}
419
420
// change the value of an already existing hard evidence
421
template
<
typename
GUM_SCALAR
>
422
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
chgEvidence
(
const
std
::
string
&
nodeName
,
423
const
std
::
string
&
label
) {
424
NodeId
id
=
this
->
model
().
idFromName
(
nodeName
);
425
chgEvidence
(
id
,
this
->
model
().
variable
(
id
)[
label
]);
426
}
427
428
// change the value of an already existing evidence (might be soft or hard)
429
template
<
typename
GUM_SCALAR
>
430
INLINE
void
431
GraphicalModelInference
<
GUM_SCALAR
>::
chgEvidence
(
NodeId
id
,
432
const
std
::
vector
<
GUM_SCALAR
>&
vals
) {
433
// check whether this corresponds to an evidence
434
if
(
_model_
==
nullptr
)
435
GUM_ERROR
(
NullElement
,
436
"No Bayes net has been assigned to the "
437
"inference algorithm"
);
438
439
if
(!
_model_
->
exists
(
id
)) {
GUM_ERROR
(
UndefinedElement
,
id
<<
" is not a NodeId in the model"
) }
440
441
if
(
_model_
->
variable
(
id
).
domainSize
() !=
vals
.
size
()) {
442
GUM_ERROR
(
InvalidArgument
,
443
"node "
<<
_model_
->
variable
(
id
) <<
" and its evidence have different sizes."
);
444
}
445
446
// create the potential corresponding to vals
447
Potential
<
GUM_SCALAR
>
pot
;
448
pot
.
add
(
_model_
->
variable
(
id
));
449
pot
.
fillWith
(
vals
);
450
chgEvidence
(
pot
);
451
}
452
453
// change the value of an already existing evidence (might be soft or hard)
454
template
<
typename
GUM_SCALAR
>
455
INLINE
void
456
GraphicalModelInference
<
GUM_SCALAR
>::
chgEvidence
(
const
std
::
string
&
nodeName
,
457
const
std
::
vector
<
GUM_SCALAR
>&
vals
) {
458
chgEvidence
(
this
->
model
().
idFromName
(
nodeName
),
vals
);
459
}
460
461
462
// change the value of an already existing evidence (might be soft or hard)
463
template
<
typename
GUM_SCALAR
>
464
void
GraphicalModelInference
<
GUM_SCALAR
>::
chgEvidence
(
const
Potential
<
GUM_SCALAR
>&
pot
) {
465
// check if the potential corresponds to an evidence
466
if
(
pot
.
nbrDim
() != 1) {
467
GUM_ERROR
(
InvalidArgument
,
pot
<<
" is not a mono-dimensional potential."
)
468
}
469
if
(
_model_
==
nullptr
)
470
GUM_ERROR
(
NullElement
,
471
"No Bayes net has been assigned to the "
472
"inference algorithm"
);
473
474
NodeId
id
=
_model_
->
nodeId
(
pot
.
variable
(0));
475
476
if
(!
hasEvidence
(
id
)) {
477
GUM_ERROR
(
InvalidArgument
,
id
<<
" has no evidence. Please use addEvidence()."
)
478
}
479
480
// check whether we have a hard evidence (and also check whether the
481
// potential only contains 0 (in this case, this will automatically raise
482
// an exception) )
483
Idx
val
;
484
bool
is_hard_evidence
=
_isHardEvidence_
(
pot
,
val
);
485
486
// modify the evidence already stored
487
const
Potential
<
GUM_SCALAR
>*
localPot
=
_evidence_
[
id
];
488
Instantiation
I
(
pot
);
489
for
(
I
.
setFirst
(); !
I
.
end
();
I
.
inc
()) {
490
localPot
->
set
(
I
,
pot
[
I
]);
491
}
492
493
// the inference state will be different
494
// whether evidence change from Hard to Soft or not.
495
bool
hasChangedSoftHard
=
false
;
496
497
if
(
is_hard_evidence
) {
498
if
(!
hasHardEvidence
(
id
)) {
499
hasChangedSoftHard
=
true
;
500
_hard_evidence_
.
insert
(
id
,
val
);
501
_hard_evidence_nodes_
.
insert
(
id
);
502
_soft_evidence_nodes_
.
erase
(
id
);
503
}
else
{
504
_hard_evidence_
[
id
] =
val
;
505
}
506
}
else
{
507
if
(
hasHardEvidence
(
id
)) {
// evidence was hard
508
_hard_evidence_
.
erase
(
id
);
509
_hard_evidence_nodes_
.
erase
(
id
);
510
_soft_evidence_nodes_
.
insert
(
id
);
511
hasChangedSoftHard
=
true
;
512
}
513
}
514
515
if
(
hasChangedSoftHard
) {
516
setState_
(
StateOfInference
::
OutdatedStructure
);
517
}
else
{
518
if
(!
isInferenceOutdatedStructure
()) {
setState_
(
StateOfInference
::
OutdatedPotentials
); }
519
}
520
521
onEvidenceChanged_
(
id
,
hasChangedSoftHard
);
522
}
523
524
525
// removed the evidence, if any, corresponding to node id
526
template
<
typename
GUM_SCALAR
>
527
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
eraseEvidence
(
NodeId
id
) {
528
if
(
hasEvidence
(
id
)) {
529
if
(
hasHardEvidence
(
id
)) {
530
onEvidenceErased_
(
id
,
true
);
531
_hard_evidence_
.
erase
(
id
);
532
_hard_evidence_nodes_
.
erase
(
id
);
533
setState_
(
StateOfInference
::
OutdatedStructure
);
534
}
else
{
535
onEvidenceErased_
(
id
,
false
);
536
_soft_evidence_nodes_
.
erase
(
id
);
537
if
(!
isInferenceOutdatedStructure
()) {
setState_
(
StateOfInference
::
OutdatedPotentials
); }
538
}
539
540
delete
(
_evidence_
[
id
]);
541
_evidence_
.
erase
(
id
);
542
}
543
}
544
// removed the evidence, if any, corresponding to node of name nodeName
545
template
<
typename
GUM_SCALAR
>
546
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
eraseEvidence
(
const
std
::
string
&
nodeName
) {
547
eraseEvidence
(
this
->
model
().
idFromName
(
nodeName
));
548
}
549
550
551
// removes all the evidence entered into the network
552
template
<
typename
GUM_SCALAR
>
553
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
eraseAllEvidence
() {
554
bool
has_hard_evidence
= !
_hard_evidence_
.
empty
();
555
this
->
onAllEvidenceErased_
(
has_hard_evidence
);
556
557
for
(
const
auto
&
pair
:
_evidence_
) {
558
if
(
pair
.
second
!=
nullptr
) {
delete
(
pair
.
second
); }
559
}
560
561
_evidence_
.
clear
();
562
_hard_evidence_
.
clear
();
563
_hard_evidence_nodes_
.
clear
();
564
_soft_evidence_nodes_
.
clear
();
565
566
if
(
has_hard_evidence
) {
567
setState_
(
StateOfInference
::
OutdatedStructure
);
568
}
else
{
569
if
(!
isInferenceOutdatedStructure
()) {
setState_
(
StateOfInference
::
OutdatedPotentials
); }
570
}
571
}
572
573
574
// returns the number of evidence entered into the Bayesian network
575
template
<
typename
GUM_SCALAR
>
576
INLINE
Size
GraphicalModelInference
<
GUM_SCALAR
>::
nbrEvidence
()
const
{
577
return
_evidence_
.
size
();
578
}
579
580
581
// returns the number of hard evidence entered into the Bayesian network
582
template
<
typename
GUM_SCALAR
>
583
INLINE
Size
GraphicalModelInference
<
GUM_SCALAR
>::
nbrHardEvidence
()
const
{
584
return
_hard_evidence_nodes_
.
size
();
585
}
586
587
588
// returns the number of soft evidence entered into the Bayesian network
589
template
<
typename
GUM_SCALAR
>
590
INLINE
Size
GraphicalModelInference
<
GUM_SCALAR
>::
nbrSoftEvidence
()
const
{
591
return
_soft_evidence_nodes_
.
size
();
592
}
593
594
595
// indicate for each node with hard evidence which value it took
596
template
<
typename
GUM_SCALAR
>
597
INLINE
const
NodeProperty
<
Idx
>&
GraphicalModelInference
<
GUM_SCALAR
>::
hardEvidence
()
const
{
598
return
_hard_evidence_
;
599
}
600
601
602
// the set of evidence entered into the network
603
template
<
typename
GUM_SCALAR
>
604
INLINE
const
NodeProperty
<
const
Potential
<
GUM_SCALAR
>* >&
605
GraphicalModelInference
<
GUM_SCALAR
>::
evidence
()
const
{
606
return
_evidence_
;
607
}
608
609
610
/// the set of nodes that received soft evidence
611
template
<
typename
GUM_SCALAR
>
612
INLINE
const
NodeSet
&
GraphicalModelInference
<
GUM_SCALAR
>::
softEvidenceNodes
()
const
{
613
return
_soft_evidence_nodes_
;
614
}
615
616
617
/// the set of nodes that received hard evidence
618
template
<
typename
GUM_SCALAR
>
619
INLINE
const
NodeSet
&
GraphicalModelInference
<
GUM_SCALAR
>::
hardEvidenceNodes
()
const
{
620
return
_hard_evidence_nodes_
;
621
}
622
623
624
// ##############################################################################
625
// Inference
626
// ##############################################################################
627
628
// put the inference into an unprepared state
629
template
<
typename
GUM_SCALAR
>
630
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
setOutdatedStructureState_
() {
631
setState_
(
StateOfInference
::
OutdatedStructure
);
632
}
633
634
635
/** puts the inference into an OutdatedPotentials state if it is not
636
* already in an OutdatedStructure state */
637
template
<
typename
GUM_SCALAR
>
638
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
setOutdatedPotentialsState_
() {
639
setState_
(
StateOfInference
::
OutdatedPotentials
);
640
}
641
642
643
// prepare the internal inference structures for the next inference
644
template
<
typename
GUM_SCALAR
>
645
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
prepareInference
() {
646
if
(
isInferenceReady
() ||
isInferenceDone
()) {
return
; }
647
648
if
(
_model_
==
nullptr
)
649
GUM_ERROR
(
NullElement
,
650
"No model been assigned to the "
651
"inference algorithm"
);
652
653
if
(
_state_
==
StateOfInference
::
OutdatedStructure
)
654
updateOutdatedStructure_
();
655
else
656
updateOutdatedPotentials_
();
657
658
setState_
(
StateOfInference
::
ReadyForInference
);
659
}
660
661
662
// perform the heavy computations needed to compute the targets' posteriors
663
template
<
typename
GUM_SCALAR
>
664
INLINE
void
GraphicalModelInference
<
GUM_SCALAR
>::
makeInference
() {
665
if
(
isInferenceDone
()) {
return
; }
666
667
if
(!
isInferenceReady
()) {
prepareInference
(); }
668
669
makeInference_
();
670
671
setState_
(
StateOfInference
::
Done
);
672
}
673
674
675
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643