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