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