aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
UAIBNReader_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
#
ifndef
DOXYGEN_SHOULD_SKIP_THIS
23
24
namespace
gum
{
25
26
template
<
typename
GUM_SCALAR >
27
UAIBNReader< GUM_SCALAR >::UAIBNReader(
BayesNet
<
GUM_SCALAR
>*
bn
,
28
const
std
::
string
&
filename
) :
29
BNReader
<
GUM_SCALAR
>(
bn
,
filename
) {
30
GUM_CONSTRUCTOR
(
UAIBNReader
);
31
bn__
=
bn
;
32
streamName__
=
filename
;
33
parseDone__
=
false
;
34
35
ioerror__
=
false
;
36
37
try
{
38
scanner__
=
new
UAIBN
::
Scanner
(
streamName__
.
c_str
());
39
parser__
=
new
UAIBN
::
Parser
(
scanner__
);
40
}
catch
(
IOError
&) {
ioerror__
=
true
; }
41
}
42
43
template
<
typename
GUM_SCALAR
>
44
UAIBNReader
<
GUM_SCALAR
>::~
UAIBNReader
() {
45
GUM_DESTRUCTOR
(
UAIBNReader
);
46
47
if
(!
ioerror__
) {
48
// this could lead to memory leak !!
49
if
(
parser__
)
delete
(
parser__
);
50
51
if
(
scanner__
)
delete
(
scanner__
);
52
}
53
}
54
55
template
<
typename
GUM_SCALAR
>
56
INLINE
UAIBN
::
Scanner
&
UAIBNReader
<
GUM_SCALAR
>::
scanner
() {
57
if
(
ioerror__
) {
GUM_ERROR
(
gum
::
IOError
,
"No such file "
+
streamName
()); }
58
59
return
*
scanner__
;
60
}
61
62
template
<
typename
GUM_SCALAR
>
63
INLINE
const
std
::
string
&
UAIBNReader
<
GUM_SCALAR
>::
streamName
()
const
{
64
return
streamName__
;
65
}
66
67
template
<
typename
GUM_SCALAR
>
68
INLINE
bool
UAIBNReader
<
GUM_SCALAR
>::
trace
()
const
{
69
return
traceScanning__
;
70
}
71
72
template
<
typename
GUM_SCALAR
>
73
INLINE
void
UAIBNReader
<
GUM_SCALAR
>::
trace
(
bool
b
) {
74
traceScanning__
=
b
;
75
scanner
().
setTrace
(
b
);
76
}
77
78
template
<
typename
GUM_SCALAR
>
79
Size
UAIBNReader
<
GUM_SCALAR
>::
proceed
() {
80
if
(
ioerror__
) {
GUM_ERROR
(
gum
::
IOError
,
"No such file "
+
streamName
()); }
81
82
if
(!
parseDone__
) {
83
try
{
84
parser__
->
Parse
();
85
parseDone__
=
true
;
86
buildFromQuartets
(
parser__
->
getQuartets
());
87
}
catch
(
gum
::
Exception
&
e
) {
88
GUM_SHOWERROR
(
e
);
89
return
1 +
parser__
->
errors
().
error_count
;
90
}
91
}
92
93
return
(
parser__
->
errors
().
error_count
);
94
}
95
96
template
<
typename
GUM_SCALAR
>
97
void
UAIBNReader
<
GUM_SCALAR
>::
buildFromQuartets
(
98
std
::
vector
<
std
::
tuple
<
float
,
int
,
int
,
int
> >
quartets
) {
99
Idx
current
;
100
Size
max
=
quartets
.
size
();
101
if
(
max
== 0) {
102
addWarning__
(1, 1,
"Empty BayesNet"
);
103
return
;
104
}
105
106
auto
isInt
= [&]() ->
bool
{
107
return
(
std
::
get
< 0 >(
quartets
[
current
]) == -1);
108
};
109
auto
lig
= [&]() ->
int
{
110
return
std
::
get
< 2 >(
quartets
[
current
]);
111
};
112
auto
col
= [&]() ->
int
{
113
return
std
::
get
< 3 >(
quartets
[
current
]);
114
};
115
116
auto
getInt
= [&]() ->
int
{
117
if
(!
isInt
())
this
->
addFatalError__
(
lig
(),
col
(),
"int expected"
);
118
return
std
::
get
< 1 >(
quartets
[
current
]);
119
};
120
auto
getVal
= [&]() ->
GUM_SCALAR
{
121
return
(
isInt
()) ? (
std
::
get
< 1 >(
quartets
[
current
]))
122
: (
std
::
get
< 0 >(
quartets
[
current
]));
123
};
124
auto
incCurrent
= [&]() {
125
current
+= 1;
126
if
(
current
>=
max
)
127
this
->
addFatalError__
(
lig
(),
col
(),
"Not enough data in UAI file"
);
128
};
129
130
current
= 0;
131
Size
nbrNode
= (
Size
)
getInt
();
132
133
for
(
NodeId
i
= 0;
i
<
nbrNode
;
i
++) {
134
incCurrent
();
135
int
mod
=
getInt
();
136
if
(
mod
< 2)
137
addError__
(
lig
(),
col
(),
"Number of modalities should be greater than 2."
);
138
bn__
->
add
(
gum
::
LabelizedVariable
(
std
::
to_string
(
i
),
""
,
mod
));
139
}
140
141
incCurrent
();
142
Size
nbrPot
= (
Size
)
getInt
();
143
if
(
nbrPot
!=
nbrNode
)
144
addWarning__
(
lig
(),
145
col
(),
146
"Number of CPTs should be the same as number of nodes"
);
147
148
Set
<
NodeId
>
s
;
149
for
(
NodeId
i
= 0;
i
<
nbrPot
;
i
++) {
150
incCurrent
();
151
Size
nbrPar
= (
Size
)
getInt
();
152
if
(
nbrPar
== 0)
addError__
(
lig
(),
col
(),
"0 is not possible here"
);
153
154
std
::
vector
<
NodeId
>
papas
;
155
for
(
NodeId
j
= 1;
j
<
nbrPar
;
j
++) {
156
incCurrent
();
157
NodeId
papa
= (
NodeId
)
getInt
();
158
if
(
papa
>=
nbrNode
)
159
addError__
(
lig
(),
col
(),
"Not enough variables in the BayesNet"
);
160
papas
.
push_back
(
papa
);
161
}
162
163
incCurrent
();
164
NodeId
nodePot
= (
Size
)
getInt
();
165
if
(
nodePot
>=
nbrNode
)
166
addError__
(
lig
(),
col
(),
"Not enough variables in the BayesNet"
);
167
if
(
s
.
contains
(
nodePot
))
addError__
(
lig
(),
col
(),
"Parents already defined"
);
168
s
.
insert
(
nodePot
);
169
170
for
(
const
auto
papa
:
papas
) {
171
bn__
->
addArc
(
papa
,
nodePot
);
172
}
173
}
174
175
std
::
vector
<
GUM_SCALAR
>
v
;
176
for
(
NodeId
i
= 0;
i
<
nbrPot
;
i
++) {
177
incCurrent
();
178
Size
nbrParam
= (
Size
)
getInt
();
179
if
(
nbrParam
!=
bn__
->
cpt
(
i
).
domainSize
())
180
addFatalError__
(
lig
(),
181
col
(),
182
"Size does not fit between parents and parameters"
);
183
for
(
Idx
j
= 0;
j
<
nbrParam
;
j
++) {
184
incCurrent
();
185
v
.
push_back
(
getVal
());
186
}
187
bn__
->
cpt
(
i
).
fillWith
(
v
);
188
v
.
clear
();
189
}
190
191
if
(
current
!=
max
- 1)
addError__
(
lig
(),
col
(),
"Too many data in this file"
);
192
}
193
194
// @{
195
// publishing Errors API
196
template
<
typename
GUM_SCALAR
>
197
INLINE
Idx
UAIBNReader
<
GUM_SCALAR
>::
errLine
(
Idx
i
) {
198
if
(
parseDone__
)
199
return
parser__
->
errors
().
error
(
i
).
line
;
200
else
{
201
GUM_ERROR
(
OperationNotAllowed
,
"UAI file not parsed yet"
);
202
}
203
}
204
205
template
<
typename
GUM_SCALAR
>
206
INLINE
Idx
UAIBNReader
<
GUM_SCALAR
>::
errCol
(
Idx
i
) {
207
if
(
parseDone__
)
208
return
parser__
->
errors
().
error
(
i
).
column
;
209
else
{
210
GUM_ERROR
(
OperationNotAllowed
,
"UAI file not parsed yet"
);
211
}
212
}
213
214
template
<
typename
GUM_SCALAR
>
215
INLINE
bool
UAIBNReader
<
GUM_SCALAR
>::
errIsError
(
Idx
i
) {
216
if
(
parseDone__
)
217
return
parser__
->
errors
().
error
(
i
).
is_error
;
218
else
{
219
GUM_ERROR
(
OperationNotAllowed
,
"UAI file not parsed yet"
);
220
}
221
}
222
223
template
<
typename
GUM_SCALAR
>
224
INLINE
std
::
string
UAIBNReader
<
GUM_SCALAR
>::
errMsg
(
Idx
i
) {
225
if
(
parseDone__
)
226
return
parser__
->
errors
().
error
(
i
).
msg
;
227
else
{
228
GUM_ERROR
(
OperationNotAllowed
,
"UAI file not parsed yet"
);
229
}
230
}
231
232
template
<
typename
GUM_SCALAR
>
233
INLINE
void
UAIBNReader
<
GUM_SCALAR
>::
showElegantErrors
(
std
::
ostream
&
o
) {
234
if
(
parseDone__
)
235
parser__
->
errors
().
elegantErrors
(
o
);
236
else
{
237
GUM_ERROR
(
OperationNotAllowed
,
"UAI file not parsed yet"
);
238
}
239
}
240
241
template
<
typename
GUM_SCALAR
>
242
INLINE
void
243
UAIBNReader
<
GUM_SCALAR
>::
showElegantErrorsAndWarnings
(
std
::
ostream
&
o
) {
244
if
(
parseDone__
)
245
parser__
->
errors
().
elegantErrorsAndWarnings
(
o
);
246
else
{
247
GUM_ERROR
(
OperationNotAllowed
,
"UAI file not parsed yet"
);
248
}
249
}
250
251
template
<
typename
GUM_SCALAR
>
252
INLINE
void
UAIBNReader
<
GUM_SCALAR
>::
showErrorsAndWarnings
(
std
::
ostream
&
o
) {
253
if
(
parseDone__
)
254
parser__
->
errors
().
simpleErrorsAndWarnings
(
o
);
255
else
{
256
GUM_ERROR
(
OperationNotAllowed
,
"UAI file not parsed yet"
);
257
}
258
}
259
260
template
<
typename
GUM_SCALAR
>
261
INLINE
void
UAIBNReader
<
GUM_SCALAR
>::
showErrorCounts
(
std
::
ostream
&
o
) {
262
if
(
parseDone__
)
263
parser__
->
errors
().
syntheticResults
(
o
);
264
else
{
265
GUM_ERROR
(
OperationNotAllowed
,
"UAI file not parsed yet"
);
266
}
267
}
268
269
template
<
typename
GUM_SCALAR
>
270
INLINE
Size
UAIBNReader
<
GUM_SCALAR
>::
errors
() {
271
return
(!
parseDone__
) ? (
Size
)0 :
parser__
->
errors
().
error_count
;
272
}
273
274
template
<
typename
GUM_SCALAR
>
275
INLINE
Size
UAIBNReader
<
GUM_SCALAR
>::
warnings
() {
276
return
(!
parseDone__
) ? (
Size
)0 :
parser__
->
errors
().
warning_count
;
277
}
278
279
template
<
typename
GUM_SCALAR
>
280
INLINE
void
UAIBNReader
<
GUM_SCALAR
>::
addFatalError__
(
Idx
lig
,
281
Idx
col
,
282
const
std
::
string
&
s
) {
283
parser__
->
errors
().
addError
(
s
,
streamName__
,
lig
,
col
);
284
GUM_ERROR
(
gum
::
OperationNotAllowed
,
""
);
285
}
286
template
<
typename
GUM_SCALAR
>
287
INLINE
void
UAIBNReader
<
GUM_SCALAR
>::
addError__
(
Idx
lig
,
288
Idx
col
,
289
const
std
::
string
&
s
) {
290
parser__
->
errors
().
addError
(
s
,
streamName__
,
lig
,
col
);
291
}
292
template
<
typename
GUM_SCALAR
>
293
INLINE
void
UAIBNReader
<
GUM_SCALAR
>::
addWarning__
(
Idx
lig
,
294
Idx
col
,
295
const
std
::
string
&
s
) {
296
parser__
->
errors
().
addWarning
(
s
,
streamName__
,
lig
,
col
);
297
}
298
299
// @}
300
}
// namespace gum
301
302
#
endif
// DOXYGEN_SHOULD_SKIP_THIS
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669