aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
gibbsOperator_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 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
samplingBn_(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
:
samplingBn_
.
nodes
())
55
if
(
hardEv_
==
nullptr
|| !
hardEv_
->
exists
(
node
))
samplingNodes_
.
insert
(
node
);
56
if
(
samplingNodes_
.
size
() == 0) {
57
GUM_ERROR
(
InvalidArgument
,
"No node to sample (too many nodes or too much evidence)!"
)
58
}
59
if
(
nbr_
>
samplingNodes_
.
size
())
nbr_
=
samplingNodes_
.
size
();
60
}
61
62
/// returns a MC sample
63
/// This is not a really sample since we take into account evidence without
64
/// care about parent of evidence, etc.
65
/// This is just a not-so-bad first sample for GibbsSampler
66
template
<
typename
GUM_SCALAR
>
67
Instantiation
GibbsOperator
<
GUM_SCALAR
>::
monteCarloSample
() {
68
gum
::
Instantiation
I
;
69
70
for
(
const
auto
nod
:
samplingBn_
.
topologicalOrder
()) {
71
I
.
add
(
samplingBn_
.
variable
(
nod
));
72
if
(
hardEv_
!=
nullptr
&&
hardEv_
->
exists
(
nod
)) {
73
I
.
chgVal
(
samplingBn_
.
variable
(
nod
), (*
hardEv_
)[
nod
]);
74
}
else
{
75
_drawVarMonteCarlo_
(
nod
, &
I
);
76
}
77
}
78
return
I
;
79
}
80
81
template
<
typename
GUM_SCALAR
>
82
void
GibbsOperator
<
GUM_SCALAR
>::
_drawVarMonteCarlo_
(
NodeId
nod
,
Instantiation
*
I
) {
83
gum
::
Instantiation
Itop
(*
I
);
84
Itop
.
erase
(
samplingBn_
.
variable
(
nod
));
85
I
->
chgVal
(
samplingBn_
.
variable
(
nod
),
samplingBn_
.
cpt
(
nod
).
extract
(
Itop
).
draw
());
86
}
87
88
89
template
<
typename
GUM_SCALAR
>
90
Instantiation
GibbsOperator
<
GUM_SCALAR
>::
nextSample
(
Instantiation
prev
) {
91
for
(
Idx
i
= 0;
i
<
nbr_
;
i
++) {
92
auto
pos
93
=
atRandom_
?
randomValue
(
samplingNodes_
.
size
()) : (
counting_
%
samplingNodes_
.
size
());
94
this
->
_GibbsSample_
(
samplingNodes_
[
pos
], &
prev
);
95
counting_
++;
96
}
97
return
prev
;
98
}
99
/// change in Instantiation I a new drawn value for id
100
101
template
<
typename
GUM_SCALAR
>
102
void
GibbsOperator
<
GUM_SCALAR
>::
_GibbsSample_
(
NodeId
id
,
Instantiation
*
I
) {
103
gum
::
Instantiation
Itop
(*
I
);
104
Itop
.
erase
(
samplingBn_
.
variable
(
id
));
105
gum
::
Potential
<
GUM_SCALAR
>
p
=
samplingBn_
.
cpt
(
id
).
extract
(
Itop
);
106
for
(
const
auto
nod
:
samplingBn_
.
children
(
id
))
107
p
*=
samplingBn_
.
cpt
(
nod
).
extract
(
Itop
);
108
GUM_ASSERT
(
p
.
nbrDim
() == 1);
109
if
(
p
.
sum
() != 0) {
110
p
.
normalize
();
111
I
->
chgVal
(
samplingBn_
.
variable
(
id
),
p
.
draw
());
112
}
113
}
114
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643