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