aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
IMarkovNet_tpl.h
Go to the documentation of this file.
1
/**
2
*
3
* Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) et Christophe GONZALES(@AMU)
4
* (@AMU) 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 Template implementation of bns/bayesNet.h classes.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) and Lionel TORTI
27
*/
28
29
#
include
<
limits
>
30
31
#
include
<
agrum
/
MN
/
IMarkovNet
.
h
>
32
#
include
<
agrum
/
tools
/
multidim
/
potential
.
h
>
33
34
#
define
EF
get
35
namespace
gum
{
36
37
// IMarkovNet
38
39
template
<
typename
GUM_SCALAR >
40
INLINE IMarkovNet<
GUM_SCALAR
>::
IMarkovNet
() :
UGmodel
() {
41
GUM_CONSTRUCTOR
(
IMarkovNet
);
42
}
43
44
template
<
typename
GUM_SCALAR
>
45
INLINE
IMarkovNet
<
GUM_SCALAR
>::
IMarkovNet
(
std
::
string
name
) :
UGmodel
() {
46
GUM_CONSTRUCTOR
(
IMarkovNet
);
47
this
->
setProperty
(
"name"
,
name
);
48
}
49
50
template
<
typename
GUM_SCALAR
>
51
IMarkovNet
<
GUM_SCALAR
>::
IMarkovNet
(
const
IMarkovNet
<
GUM_SCALAR
>&
source
) :
UGmodel
(
source
) {
52
GUM_CONS_CPY
(
IMarkovNet
);
53
}
54
55
template
<
typename
GUM_SCALAR
>
56
IMarkovNet
<
GUM_SCALAR
>&
57
IMarkovNet
<
GUM_SCALAR
>::
operator
=(
const
IMarkovNet
<
GUM_SCALAR
>&
source
) {
58
if
(
this
!= &
source
) {
UGmodel
::
operator
=(
source
); }
59
60
return
*
this
;
61
}
62
63
template
<
typename
GUM_SCALAR
>
64
IMarkovNet
<
GUM_SCALAR
>::~
IMarkovNet
() {
65
GUM_DESTRUCTOR
(
IMarkovNet
);
66
}
67
68
template
<
typename
GUM_SCALAR
>
69
INLINE
Size
IMarkovNet
<
GUM_SCALAR
>::
dim
()
const
{
70
Size
res
= 0;
71
for
(
auto
f
:
factors
()) {
72
res
+=
f
.
second
->
domainSize
();
73
}
74
return
res
;
75
}
76
77
template
<
typename
GUM_SCALAR
>
78
INLINE
Size
IMarkovNet
<
GUM_SCALAR
>::
maxVarDomainSize
()
const
{
79
Size
res
= 0;
80
for
(
auto
node
:
nodes
()) {
81
auto
v
=
variable
(
node
).
domainSize
();
82
if
(
v
>
res
) {
res
=
v
; }
83
}
84
return
res
;
85
}
86
87
template
<
typename
GUM_SCALAR
>
88
INLINE
GUM_SCALAR
IMarkovNet
<
GUM_SCALAR
>::
minParam
()
const
{
89
GUM_SCALAR
res
= 1.0;
90
for
(
auto
elt
:
factors
()) {
91
auto
v
=
elt
.
second
->
min
();
92
if
(
v
<
res
) {
res
=
v
; }
93
}
94
return
res
;
95
}
96
97
template
<
typename
GUM_SCALAR
>
98
INLINE
GUM_SCALAR
IMarkovNet
<
GUM_SCALAR
>::
maxParam
()
const
{
99
GUM_SCALAR
res
= 1.0;
100
for
(
auto
elt
:
factors
()) {
101
auto
v
=
elt
.
second
->
max
();
102
if
(
v
>
res
) {
res
=
v
; }
103
}
104
return
res
;
105
}
106
107
template
<
typename
GUM_SCALAR
>
108
INLINE
GUM_SCALAR
IMarkovNet
<
GUM_SCALAR
>::
minNonZeroParam
()
const
{
109
GUM_SCALAR
res
= 1.0;
110
for
(
auto
elt
:
factors
()) {
111
auto
v
=
elt
.
second
->
minNonZero
();
112
if
(
v
<
res
) {
res
=
v
; }
113
}
114
return
res
;
115
}
116
117
template
<
typename
GUM_SCALAR
>
118
INLINE
GUM_SCALAR
IMarkovNet
<
GUM_SCALAR
>::
maxNonOneParam
()
const
{
119
GUM_SCALAR
res
= 0.0;
120
for
(
auto
elt
:
factors
()) {
121
auto
v
=
elt
.
second
->
maxNonOne
();
122
if
(
v
>
res
) {
res
=
v
; }
123
}
124
return
res
;
125
}
126
127
template
<
typename
GUM_SCALAR
>
128
INLINE
std
::
string
IMarkovNet
<
GUM_SCALAR
>::
toString
()
const
{
129
Size
param
= 0;
130
double
dSize
=
log10DomainSize
();
131
132
for
(
auto
factor
:
factors
())
133
param
+=
factor
.
second
->
content
()->
realSize
();
134
135
std
::
stringstream
s
;
136
s
<<
"MN{nodes: "
<<
size
() <<
", edges: "
<<
graph
().
sizeEdges
() <<
", "
;
137
138
if
(
dSize
> 6)
139
s
<<
"domainSize: 10^"
<<
dSize
;
140
else
141
s
<<
"domainSize: "
<<
std
::
round
(
std
::
pow
(10.0,
dSize
));
142
143
s
<<
", dim: "
<<
param
<<
"}"
;
144
145
return
s
.
str
();
146
}
147
148
template
<
typename
GUM_SCALAR
>
149
std
::
string
IMarkovNet
<
GUM_SCALAR
>::
toDot
()
const
{
150
std
::
stringstream
output
;
151
output
<<
"graph \""
;
152
153
std
::
string
mn_name
;
154
155
try
{
156
mn_name
=
this
->
property
(
"name"
);
157
}
catch
(
NotFound
&) {
mn_name
=
"no_name"
; }
158
159
output
<<
mn_name
<<
"\" {"
<<
std
::
endl
;
160
output
<<
" graph [bgcolor=transparent,label=\""
<<
mn_name
<<
"\"];"
<<
std
::
endl
;
161
output
<<
" node [style=filled fillcolor=\"#ffffaa\"];"
<<
std
::
endl
<<
std
::
endl
;
162
163
for
(
auto
node
:
nodes
())
164
output
<<
" \""
<<
variable
(
node
).
name
() <<
"\" [comment=\""
<<
node
<<
":"
165
<<
variable
(
node
).
toStringWithDescription
() <<
"\"];"
<<
std
::
endl
;
166
167
output
<<
std
::
endl
;
168
169
std
::
string
tab
=
" "
;
170
171
for
(
auto
node
:
nodes
()) {
172
if
(
neighbours
(
node
).
size
() > 0) {
173
for
(
auto
nei
:
neighbours
(
node
)) {
174
if
(
variable
(
node
).
name
() <
variable
(
nei
).
name
()) {
175
output
<<
tab
<<
"\""
<<
variable
(
node
).
name
() <<
"\" -- "
176
<<
"\""
<<
variable
(
nei
).
name
() <<
"\";"
<<
std
::
endl
;
177
}
178
}
179
}
else
{
180
output
<<
tab
<<
"\""
<<
variable
(
node
).
name
() <<
"\";"
<<
std
::
endl
;
181
}
182
}
183
184
output
<<
"}"
<<
std
::
endl
;
185
186
return
output
.
str
();
187
}
188
189
190
template
<
typename
GUM_SCALAR
>
191
std
::
string
IMarkovNet
<
GUM_SCALAR
>::
toDotAsFactorGraph
()
const
{
192
std
::
stringstream
output
;
193
std
::
string
mn_name
;
194
try
{
195
mn_name
=
this
->
property
(
"name"
);
196
}
catch
(
NotFound
&) {
mn_name
=
"no_name"
; }
197
198
output
<<
"graph FG_"
<<
mn_name
<<
" {"
<<
std
::
endl
;
199
output
<<
" layout=neato;"
<<
std
::
endl
;
200
output
<<
" graph [bgcolor=transparent,label=\"factor graph for "
<<
mn_name
<<
"\"];"
201
<<
std
::
endl
;
202
203
// the variables
204
output
<<
" node [shape=rectangle,margin=0.04,width=0,height=0, "
205
"style=filled,color=\"coral\"];"
206
<<
std
::
endl
;
207
for
(
auto
nod
:
nodes
()) {
208
output
<<
"\""
<<
variable
(
nod
).
name
() <<
"\";"
<<
std
::
endl
;
209
}
210
output
<<
std
::
endl
;
211
212
// the factor
213
output
<<
"node[shape = point,width = 0.1,height = 0.1,style = filled,color = "
214
"\"burlywood\"];"
215
<<
std
::
endl
;
216
for
(
const
auto
&
kv
:
factors
()) {
217
output
<<
" \"f"
;
218
for
(
NodeId
nod
:
kv
.
first
) {
219
output
<<
"#"
<<
variable
(
nod
).
name
();
220
}
221
output
<<
"\";"
<<
std
::
endl
;
222
}
223
224
// the link variable--factors
225
output
<<
" edge[len = 0.7];"
<<
std
::
endl
;
226
for
(
const
auto
&
kv
:
factors
()) {
227
std
::
string
clicname
=
"\"f"
;
228
for
(
NodeId
nod
:
kv
.
first
) {
229
clicname
+=
"#"
;
230
clicname
+=
variable
(
nod
).
name
();
231
}
232
clicname
+=
"\""
;
233
234
for
(
NodeId
nod
:
kv
.
first
)
235
output
<<
" "
<<
clicname
<<
" -- \""
<<
variable
(
nod
).
name
() <<
"\";"
<<
std
::
endl
;
236
}
237
output
<<
"}"
<<
std
::
endl
;
238
239
return
output
.
str
();
240
}
241
242
template
<
typename
GUM_SCALAR
>
243
bool
IMarkovNet
<
GUM_SCALAR
>::
operator
==(
const
IMarkovNet
&
from
)
const
{
244
if
(
size
() !=
from
.
size
()) {
return
false
; }
245
246
if
(
sizeEdges
() !=
from
.
sizeEdges
()) {
return
false
; }
247
248
// alignment of variables between the 2 BNs
249
Bijection
<
const
DiscreteVariable
*,
const
DiscreteVariable
* >
alignment
;
250
251
for
(
auto
node
:
nodes
()) {
252
try
{
253
alignment
.
insert
(&
variable
(
node
), &
from
.
variableFromName
(
variable
(
node
).
name
()));
254
}
catch
(
NotFound
&) {
255
// a name is not found in from
256
return
false
;
257
}
258
}
259
260
for
(
const
auto
&
elt
:
factors
()) {
261
const
auto
&
key
=
elt
.
first
;
262
const
auto
&
factor
= *
elt
.
second
;
263
264
NodeSet
fromkey
;
265
for
(
const
auto
n
:
key
)
266
fromkey
.
insert
(
from
.
idFromName
(
variable
(
n
).
name
()));
267
268
if
(!
from
.
factors
().
exists
(
fromkey
)) {
return
false
; }
269
270
const
auto
&
fromfactor
=
from
.
factor
(
fromkey
);
271
272
Instantiation
i
(
factor
);
273
Instantiation
j
(
fromfactor
);
274
for
(
i
.
setFirst
(); !
i
.
end
();
i
.
inc
()) {
275
for
(
Idx
indice
= 0;
indice
<
factor
.
nbrDim
(); ++
indice
) {
276
const
DiscreteVariable
*
p
= &(
i
.
variable
(
indice
));
277
j
.
chgVal
(*(
alignment
.
second
(
p
)),
i
.
val
(*
p
));
278
}
279
280
if
(
std
::
pow
(
factor
.
get
(
i
) -
fromfactor
.
get
(
j
), (
GUM_SCALAR
)2) > (
GUM_SCALAR
)1e-6) {
281
return
false
;
282
}
283
}
284
}
285
return
true
;
286
}
287
288
template
<
typename
GUM_SCALAR
>
289
INLINE
bool
IMarkovNet
<
GUM_SCALAR
>::
operator
!=(
const
IMarkovNet
&
from
)
const
{
290
return
!
this
->
operator
==(
from
);
291
}
292
293
template
<
typename
GUM_SCALAR
>
294
INLINE
std
::
ostream
&
operator
<<(
std
::
ostream
&
output
,
const
IMarkovNet
<
GUM_SCALAR
>&
bn
) {
295
output
<<
bn
.
toString
();
296
return
output
;
297
}
298
299
template
<
typename
GUM_SCALAR
>
300
INLINE
const
NodeSet
&
301
IMarkovNet
<
GUM_SCALAR
>::
smallestFactorFromNode
(
const
std
::
string
&
name
)
const
{
302
try
{
303
return
smallestFactorFromNode
(
idFromName
(
name
));
304
}
catch
(
NotFound
) {
GUM_ERROR
(
NotFound
,
"No factor containing the variable <"
<<
name
<<
">"
) }
305
}
306
307
// visit the nodes and add some of node from soids in minimal
308
template
<
typename
GUM_SCALAR
>
309
void
IMarkovNet
<
GUM_SCALAR
>::
_minimalCondSetVisit_
(
NodeId
node
,
310
const
NodeSet
&
soids
,
311
NodeSet
&
minimal
,
312
NodeSet
&
alreadyVisited
)
const
{
313
if
(
alreadyVisited
.
contains
(
node
))
return
;
314
alreadyVisited
<<
node
;
315
316
if
(
soids
.
contains
(
node
)) {
317
minimal
<<
node
;
318
}
else
{
319
for
(
auto
neig
:
graph_
.
neighbours
(
node
))
320
_minimalCondSetVisit_
(
neig
,
soids
,
minimal
,
alreadyVisited
);
321
}
322
}
323
324
325
template
<
typename
GUM_SCALAR
>
326
NodeSet
IMarkovNet
<
GUM_SCALAR
>::
minimalCondSet
(
NodeId
target
,
const
NodeSet
&
soids
)
const
{
327
if
(
soids
.
contains
(
target
))
return
NodeSet
({
target
});
328
329
NodeSet
res
;
330
NodeSet
alreadyVisited
;
331
alreadyVisited
<<
target
;
332
333
for
(
auto
neig
:
graph_
.
neighbours
(
target
))
334
_minimalCondSetVisit_
(
neig
,
soids
,
res
,
alreadyVisited
);
335
return
res
;
336
}
337
338
template
<
typename
GUM_SCALAR
>
339
NodeSet
IMarkovNet
<
GUM_SCALAR
>::
minimalCondSet
(
const
NodeSet
&
targets
,
340
const
NodeSet
&
soids
)
const
{
341
NodeSet
res
;
342
for
(
auto
node
:
targets
) {
343
res
+=
minimalCondSet
(
node
,
soids
);
344
}
345
return
res
;
346
}
347
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643