aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
DBCell.cpp
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
/** @file
23
* @brief The implementation of DBCells
24
*
25
* @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26
*/
27
#
include
<
cstdio
>
28
#
include
<
agrum
/
tools
/
database
/
DBCell
.
h
>
29
30
31
#
ifndef
DOXYGEN_SHOULD_SKIP_THIS
32
33
/// include the inlined functions if necessary
34
#
ifdef
GUM_NO_INLINE
35
#
include
<
agrum
/
tools
/
database
/
DBCell_inl
.
h
>
36
#
endif
/* GUM_NO_INLINE */
37
38
namespace
gum
{
39
40
namespace
learning
{
41
42
// create the static members
43
int
DBCell
::
string_max_index__
= 0;
44
45
46
Bijection
<
std
::
string
,
int
>&
DBCell
::
strings__
() {
47
#
ifdef
GUM_DEBUG_MODE
48
static
bool
first_time
=
true
;
49
if
(
first_time
) {
50
first_time
=
false
;
51
__debug__
::
dec_creation__
(
"Bijection"
,
52
"__strings"
,
53
0,
54
"BCell string bijection"
,
55
0);
56
__debug__
::
dec_creation__
(
"BijectionImplementation"
,
57
"__strings"
,
58
0,
59
"BCell string bijection"
,
60
0);
61
__debug__
::
dec_creation__
(
"HashTable"
,
62
"__strings"
,
63
0,
64
"BCell string bijection"
,
65
0);
66
__debug__
::
dec_creation__
(
"HashTable"
,
67
"__strings"
,
68
0,
69
"BCell string bijection"
,
70
0);
71
}
72
#
endif
73
static
Bijection
<
std
::
string
,
int
>
strings
;
74
return
strings
;
75
}
76
77
78
// determines whether a string corresponds to an integer
79
bool
DBCell
::
isInteger
(
const
std
::
string
&
str
) {
80
if
(
str
.
empty
())
return
false
;
81
82
// trim the string
83
auto
start_iter
=
str
.
begin
() +
str
.
find_first_not_of
(
" \t"
);
84
auto
end_iter
=
str
.
begin
() +
str
.
find_last_not_of
(
" \t\r\n"
) + 1;
85
86
if
(
start_iter
==
end_iter
)
return
false
;
87
88
// if the number is negative, pass the '-' sign
89
if
(*
start_iter
==
'-'
) ++
start_iter
;
90
91
// check wether we have a number
92
for
(;
start_iter
!=
end_iter
; ++
start_iter
) {
93
if
((*
start_iter
<
'0'
) || (*
start_iter
>
'9'
))
return
false
;
94
}
95
96
return
true
;
97
}
98
99
100
// determines whether a string corresponds to an integer
101
bool
DBCell
::
isReal
(
const
std
::
string
&
str
) {
102
if
(
str
.
empty
())
return
false
;
103
104
// trim the string
105
auto
start_iter
=
str
.
begin
() +
str
.
find_first_not_of
(
" \t"
);
106
auto
end_iter
=
str
.
begin
() +
str
.
find_last_not_of
(
" \t\r\n"
) + 1;
107
108
if
(
start_iter
==
end_iter
)
return
false
;
109
110
// check wether we have a number
111
bool
has_dot
=
false
;
112
bool
has_exponent
=
false
;
113
bool
has_digit
=
false
;
114
bool
has_negation
=
false
;
115
for
(;
start_iter
!=
end_iter
; ++
start_iter
) {
116
if
(*
start_iter
==
'-'
) {
117
if
(
has_negation
)
return
false
;
118
}
else
if
(*
start_iter
==
'.'
) {
119
if
(
has_dot
||
has_exponent
)
return
false
;
120
has_dot
=
true
;
121
}
else
if
((*
start_iter
==
'e'
) || (*
start_iter
==
'E'
)) {
122
if
(
has_exponent
|| !
has_digit
)
return
false
;
123
has_exponent
=
true
;
124
has_negation
=
false
;
125
}
else
if
((*
start_iter
<
'0'
) || (*
start_iter
>
'9'
))
126
return
false
;
127
else
128
has_digit
=
true
;
129
}
130
131
return
true
;
132
}
133
134
135
// try to convert the content of the DBCell into another type
136
bool
DBCell
::
convertType
(
const
EltType
new_type
) {
137
if
(
new_type
==
type__
)
return
true
;
138
switch
(
new_type
) {
139
// ===================================
140
case
EltType
::
REAL
:
141
switch
(
type__
) {
142
case
EltType
::
INTEGER
:
143
val_real__
=
float
(
val_integer__
);
144
type__
=
EltType
::
REAL
;
145
return
true
;
146
147
case
EltType
::
STRING
:
148
try
{
149
const
std
::
string
&
str
=
strings__
().
first
(
val_index__
);
150
if
(!
isReal
(
str
))
return
false
;
151
val_real__
=
std
::
stof
(
str
);
152
type__
=
EltType
::
REAL
;
153
return
true
;
154
}
catch
(
std
::
invalid_argument
&) {
return
false
; }
155
156
case
EltType
::
MISSING
:
157
return
false
;
158
159
default
:
160
GUM_ERROR
(
NotImplementedYet
,
161
"type not supported by DBCell convertType"
);
162
}
163
164
// ===================================
165
case
EltType
::
INTEGER
:
166
switch
(
type__
) {
167
case
EltType
::
REAL
: {
168
const
int
nb
=
int
(
val_real__
);
169
if
(
nb
==
val_real__
) {
170
val_integer__
=
nb
;
171
type__
=
EltType
::
INTEGER
;
172
return
true
;
173
}
else
174
return
false
;
175
}
176
177
case
EltType
::
STRING
:
178
try
{
179
const
std
::
string
&
str
=
strings__
().
first
(
val_index__
);
180
if
(!
isInteger
(
str
))
return
false
;
181
val_integer__
=
std
::
stoi
(
str
);
182
type__
=
EltType
::
INTEGER
;
183
return
true
;
184
}
catch
(
std
::
invalid_argument
&) {
return
false
; }
185
186
case
EltType
::
MISSING
:
187
return
false
;
188
189
default
:
190
GUM_ERROR
(
NotImplementedYet
,
191
"type not supported by DBCell convertType"
);
192
}
193
194
// ===================================
195
case
EltType
::
STRING
:
196
switch
(
type__
) {
197
case
EltType
::
REAL
: {
198
char
buffer
[100];
199
sprintf
(
buffer
,
"%g"
,
val_real__
);
200
const
std
::
string
str
(
buffer
);
201
if
(!
strings__
().
existsFirst
(
str
)) {
202
strings__
().
insert
(
str
,
string_max_index__
);
203
val_index__
=
string_max_index__
;
204
++
string_max_index__
;
205
}
else
{
206
val_index__
=
strings__
().
second
(
str
);
207
}
208
}
209
type__
=
EltType
::
STRING
;
210
return
true
;
211
212
case
EltType
::
INTEGER
: {
213
const
std
::
string
str
=
std
::
to_string
(
val_integer__
);
214
if
(!
strings__
().
existsFirst
(
str
)) {
215
strings__
().
insert
(
str
,
string_max_index__
);
216
val_index__
=
string_max_index__
;
217
++
string_max_index__
;
218
}
else
{
219
val_index__
=
strings__
().
second
(
str
);
220
}
221
}
222
type__
=
EltType
::
STRING
;
223
return
true
;
224
225
case
EltType
::
MISSING
:
226
return
false
;
227
228
default
:
229
GUM_ERROR
(
NotImplementedYet
,
230
"type not supported by DBCell convertType"
);
231
}
232
233
// ===================================
234
case
EltType
::
MISSING
:
235
type__
=
EltType
::
MISSING
;
236
return
true
;
237
238
default
:
239
GUM_ERROR
(
NotImplementedYet
,
"type not supported by DBCell convertType"
);
240
}
241
242
return
false
;
243
}
244
245
246
// raises an appropriate exception when encountering a type error
247
std
::
string
DBCell
::
typeErrorMsg__
(
const
std
::
string
&
true_type
)
const
{
248
std
::
stringstream
str
;
249
switch
(
type__
) {
250
case
EltType
::
REAL
:
251
str
<<
"The DBCell contains a real number instead of "
<<
true_type
;
252
break
;
253
254
case
EltType
::
INTEGER
:
255
str
<<
"The DBCell contains an integer instead of "
<<
true_type
;
256
break
;
257
258
case
EltType
::
STRING
:
259
str
<<
"The DBCell contains a string instead of "
<<
true_type
;
260
break
;
261
262
case
EltType
::
MISSING
:
263
str
<<
"The DBCell contains a missing value instead of "
<<
true_type
;
264
break
;
265
266
default
:
267
GUM_ERROR
(
NotImplementedYet
,
"DBCell type not implemented yet"
);
268
}
269
270
return
str
.
str
();
271
}
272
273
}
/* namespace learning */
274
275
}
/* namespace gum */
276
277
#
endif
/* DOXYGEN_SHOULD_SKIP_THIS */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669
gum::learning::genericBNLearner::Database::Database
Database(const std::string &filename, const BayesNet< GUM_SCALAR > &bn, const std::vector< std::string > &missing_symbols)
Definition:
genericBNLearner_tpl.h:31