aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
gibbsOperator_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 Gibbs inference methods in Bayesian networks.
25
*
26
* @author Paul ALAM & Pierre-Henri WUILLEMIN(@LIP6)
27
*/
28
29
30
#
include
<
agrum
/
BN
/
inference
/
tools
/
gibbsOperator
.
h
>
31
#
include
<
agrum
/
tools
/
core
/
utils_random
.
h
>
32
33
namespace
gum
{
34
35
template
<
typename
GUM_SCALAR >
36
GibbsOperator< GUM_SCALAR >::GibbsOperator(
const
IBayesNet< GUM_SCALAR >& BN,
37
const
NodeProperty< Idx >* hardEv,
38
Size nbr,
39
bool
atRandom) :
40
counting_(0),
41
sampling_bn_(BN), hardEv_(hardEv), nbr_(nbr), atRandom_(atRandom) {
42
updateSamplingNodes__();
43
GUM_CONSTRUCTOR(GibbsOperator);
44
}
45
46
template
<
typename
GUM_SCALAR
>
47
GibbsOperator
<
GUM_SCALAR
>::~
GibbsOperator
() {
48
GUM_DESTRUCTOR
(
GibbsOperator
);
49
}
50
51
template
<
typename
GUM_SCALAR
>
52
void
GibbsOperator
<
GUM_SCALAR
>::
updateSamplingNodes__
() {
53
samplingNodes_
.
clear
();
54
for
(
const
auto
node
:
sampling_bn_
.
nodes
())
55
if
(
hardEv_
==
nullptr
|| !
hardEv_
->
exists
(
node
))
56
samplingNodes_
.
insert
(
node
);
57
if
(
samplingNodes_
.
size
() == 0) {
58
GUM_ERROR
(
InvalidArgument
,
59
"No node to sample (too many nodes or too much evidence)!"
)
60
}
61
if
(
nbr_
>
samplingNodes_
.
size
())
nbr_
=
samplingNodes_
.
size
();
62
}
63
64
/// returns a MC sample
65
/// This is not a really sample since we take into account evidence without
66
/// care about parent of evidence, etc.
67
/// This is just a not-so-bad first sample for GibbsSampler
68
template
<
typename
GUM_SCALAR
>
69
Instantiation
GibbsOperator
<
GUM_SCALAR
>::
monteCarloSample
() {
70
gum
::
Instantiation
I
;
71
72
for
(
const
auto
nod
:
sampling_bn_
.
topologicalOrder
()) {
73
I
.
add
(
sampling_bn_
.
variable
(
nod
));
74
if
(
hardEv_
!=
nullptr
&&
hardEv_
->
exists
(
nod
)) {
75
I
.
chgVal
(
sampling_bn_
.
variable
(
nod
), (*
hardEv_
)[
nod
]);
76
}
else
{
77
drawVarMonteCarlo__
(
nod
, &
I
);
78
}
79
}
80
return
I
;
81
}
82
83
template
<
typename
GUM_SCALAR
>
84
void
GibbsOperator
<
GUM_SCALAR
>::
drawVarMonteCarlo__
(
NodeId
nod
,
85
Instantiation
*
I
) {
86
gum
::
Instantiation
Itop
(*
I
);
87
Itop
.
erase
(
sampling_bn_
.
variable
(
nod
));
88
I
->
chgVal
(
sampling_bn_
.
variable
(
nod
),
89
sampling_bn_
.
cpt
(
nod
).
extract
(
Itop
).
draw
());
90
}
91
92
93
template
<
typename
GUM_SCALAR
>
94
Instantiation
GibbsOperator
<
GUM_SCALAR
>::
nextSample
(
Instantiation
prev
) {
95
for
(
Idx
i
= 0;
i
<
nbr_
;
i
++) {
96
auto
pos
=
atRandom_
?
randomValue
(
samplingNodes_
.
size
())
97
: (
counting_
%
samplingNodes_
.
size
());
98
this
->
GibbsSample__
(
samplingNodes_
[
pos
], &
prev
);
99
counting_
++;
100
}
101
return
prev
;
102
}
103
/// change in Instantiation I a new drawn value for id
104
105
template
<
typename
GUM_SCALAR
>
106
void
GibbsOperator
<
GUM_SCALAR
>::
GibbsSample__
(
NodeId
id
,
Instantiation
*
I
) {
107
gum
::
Instantiation
Itop
(*
I
);
108
Itop
.
erase
(
sampling_bn_
.
variable
(
id
));
109
gum
::
Potential
<
GUM_SCALAR
>
p
=
sampling_bn_
.
cpt
(
id
).
extract
(
Itop
);
110
for
(
const
auto
nod
:
sampling_bn_
.
children
(
id
))
111
p
*=
sampling_bn_
.
cpt
(
nod
).
extract
(
Itop
);
112
GUM_ASSERT
(
p
.
nbrDim
() == 1);
113
if
(
p
.
sum
() != 0) {
114
p
.
normalize
();
115
I
->
chgVal
(
sampling_bn_
.
variable
(
id
),
p
.
draw
());
116
}
117
}
118
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669