aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
score_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
/** @file
23
* @brief the base class for all the scores used for learning (BIC, BDeu, etc)
24
*
25
* @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26
*/
27
#
ifndef
DOXYGEN_SHOULD_SKIP_THIS
28
29
namespace
gum
{
30
31
namespace
learning
{
32
33
/// returns the allocator used by the translator
34
template
<
template
<
typename
>
class
ALLOC
>
35
INLINE
typename
Score
<
ALLOC
>::
allocator_type
36
Score
<
ALLOC
>::
getAllocator
()
const
{
37
return
counter_
.
getAllocator
();
38
}
39
40
41
/// default constructor
42
template
<
template
<
typename
>
class
ALLOC
>
43
INLINE
Score
<
ALLOC
>::
Score
(
44
const
DBRowGeneratorParser
<
ALLOC
>&
parser
,
45
const
Apriori
<
ALLOC
>&
apriori
,
46
const
std
::
vector
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
>,
47
ALLOC
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
> > >&
ranges
,
48
const
Bijection
<
NodeId
,
std
::
size_t
,
ALLOC
<
std
::
size_t
> >&
49
nodeId2columns
,
50
const
typename
Score
<
ALLOC
>::
allocator_type
&
alloc
) :
51
apriori_
(
apriori
.
clone
(
alloc
)),
52
counter_
(
parser
,
ranges
,
nodeId2columns
,
alloc
),
cache_
(
alloc
) {
53
GUM_CONSTRUCTOR
(
Score
);
54
}
55
56
57
/// default constructor
58
template
<
template
<
typename
>
class
ALLOC
>
59
INLINE
Score
<
ALLOC
>::
Score
(
60
const
DBRowGeneratorParser
<
ALLOC
>&
parser
,
61
const
Apriori
<
ALLOC
>&
apriori
,
62
const
Bijection
<
NodeId
,
std
::
size_t
,
ALLOC
<
std
::
size_t
> >&
63
nodeId2columns
,
64
const
typename
Score
<
ALLOC
>::
allocator_type
&
alloc
) :
65
apriori_
(
apriori
.
clone
(
alloc
)),
66
counter_
(
parser
,
nodeId2columns
,
alloc
),
cache_
(
alloc
) {
67
GUM_CONSTRUCTOR
(
Score
);
68
}
69
70
71
/// copy constructor with a given allocator
72
template
<
template
<
typename
>
class
ALLOC
>
73
INLINE
Score
<
ALLOC
>::
Score
(
74
const
Score
<
ALLOC
>&
from
,
75
const
typename
Score
<
ALLOC
>::
allocator_type
&
alloc
) :
76
apriori_
(
from
.
apriori_
->
clone
(
alloc
)),
77
counter_
(
from
.
counter_
,
alloc
),
cache_
(
from
.
cache_
,
alloc
),
78
use_cache_
(
from
.
use_cache_
) {
79
GUM_CONS_CPY
(
Score
);
80
}
81
82
83
/// copy constructor
84
template
<
template
<
typename
>
class
ALLOC
>
85
INLINE
Score
<
ALLOC
>::
Score
(
const
Score
<
ALLOC
>&
from
) :
86
Score
(
from
,
from
.
getAllocator
()) {}
87
88
89
/// move constructor
90
template
<
template
<
typename
>
class
ALLOC
>
91
INLINE
Score
<
ALLOC
>::
Score
(
92
Score
<
ALLOC
>&&
from
,
93
const
typename
Score
<
ALLOC
>::
allocator_type
&
alloc
) :
94
apriori_
(
from
.
apriori_
),
95
counter_
(
std
::
move
(
from
.
counter_
),
alloc
),
96
cache_
(
std
::
move
(
from
.
cache_
),
alloc
),
use_cache_
(
from
.
use_cache_
) {
97
from
.
apriori_
=
nullptr
;
98
GUM_CONS_MOV
(
Score
);
99
}
100
101
102
/// move constructor
103
template
<
template
<
typename
>
class
ALLOC
>
104
INLINE
Score
<
ALLOC
>::
Score
(
Score
<
ALLOC
>&&
from
) :
105
Score
(
std
::
move
(
from
),
from
.
getAllocator
()) {}
106
107
108
/// destructor
109
template
<
template
<
typename
>
class
ALLOC
>
110
INLINE
Score
<
ALLOC
>::~
Score
() {
111
if
(
apriori_
!=
nullptr
) {
112
ALLOC
<
Apriori
<
ALLOC
> >
allocator
(
this
->
getAllocator
());
113
allocator
.
destroy
(
apriori_
);
114
allocator
.
deallocate
(
apriori_
, 1);
115
}
116
GUM_DESTRUCTOR
(
Score
);
117
}
118
119
120
/// copy operator
121
template
<
template
<
typename
>
class
ALLOC
>
122
Score
<
ALLOC
>&
Score
<
ALLOC
>::
operator
=(
const
Score
<
ALLOC
>&
from
) {
123
if
(
this
!= &
from
) {
124
Apriori
<
ALLOC
>*
new_apriori
=
from
.
apriori_
->
clone
();
125
RecordCounter
<
ALLOC
>
new_counter
=
from
.
counter_
;
126
ScoringCache
<
ALLOC
>
new_cache
=
from
.
cache_
;
127
128
if
(
apriori_
!=
nullptr
) {
129
ALLOC
<
Apriori
<
ALLOC
> >
allocator
(
this
->
getAllocator
());
130
allocator
.
destroy
(
apriori_
);
131
allocator
.
deallocate
(
apriori_
, 1);
132
}
133
134
apriori_
=
new_apriori
;
135
counter_
=
std
::
move
(
new_counter
);
136
cache_
=
std
::
move
(
new_cache
);
137
138
use_cache_
=
from
.
use_cache_
;
139
}
140
return
*
this
;
141
}
142
143
144
/// move operator
145
template
<
template
<
typename
>
class
ALLOC
>
146
Score
<
ALLOC
>&
Score
<
ALLOC
>::
operator
=(
Score
<
ALLOC
>&&
from
) {
147
if
(
this
!= &
from
) {
148
std
::
swap
(
apriori_
,
from
.
apriori_
);
149
150
counter_
=
std
::
move
(
from
.
counter_
);
151
cache_
=
std
::
move
(
from
.
cache_
);
152
use_cache_
=
from
.
use_cache_
;
153
}
154
return
*
this
;
155
}
156
157
158
/// changes the max number of threads used to parse the database
159
template
<
template
<
typename
>
class
ALLOC
>
160
INLINE
void
Score
<
ALLOC
>::
setMaxNbThreads
(
std
::
size_t
nb
)
const
{
161
counter_
.
setMaxNbThreads
(
nb
);
162
}
163
164
165
/// returns the number of threads used to parse the database
166
template
<
template
<
typename
>
class
ALLOC
>
167
INLINE
std
::
size_t
Score
<
ALLOC
>::
nbThreads
()
const
{
168
return
counter_
.
nbThreads
();
169
}
170
171
172
/** @brief changes the number min of rows a thread should process in a
173
* multithreading context */
174
template
<
template
<
typename
>
class
ALLOC
>
175
INLINE
void
Score
<
ALLOC
>::
setMinNbRowsPerThread
(
const
std
::
size_t
nb
)
const
{
176
counter_
.
setMinNbRowsPerThread
(
nb
);
177
}
178
179
180
/// returns the minimum of rows that each thread should process
181
template
<
template
<
typename
>
class
ALLOC
>
182
INLINE
std
::
size_t
Score
<
ALLOC
>::
minNbRowsPerThread
()
const
{
183
return
counter_
.
minNbRowsPerThread
();
184
}
185
186
187
/// sets new ranges to perform the countings used by the score
188
/** @param ranges a set of pairs {(X1,Y1),...,(Xn,Yn)} of database's rows
189
* indices. The countings are then performed only on the union of the
190
* rows [Xi,Yi), i in {1,...,n}. This is useful, e.g, when performing
191
* cross validation tasks, in which part of the database should be ignored.
192
* An empty set of ranges is equivalent to an interval [X,Y) ranging over
193
* the whole database. */
194
template
<
template
<
typename
>
class
ALLOC
>
195
template
<
template
<
typename
>
class
XALLOC
>
196
void
Score
<
ALLOC
>::
setRanges
(
197
const
std
::
vector
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
>,
198
XALLOC
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
> > >&
199
new_ranges
) {
200
std
::
vector
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
>,
201
ALLOC
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
> > >
202
old_ranges
=
ranges
();
203
counter_
.
setRanges
(
new_ranges
);
204
if
(
old_ranges
!=
ranges
())
clear
();
205
}
206
207
208
/// reset the ranges to the one range corresponding to the whole database
209
template
<
template
<
typename
>
class
ALLOC
>
210
void
Score
<
ALLOC
>::
clearRanges
() {
211
std
::
vector
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
>,
212
ALLOC
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
> > >
213
old_ranges
=
ranges
();
214
counter_
.
clearRanges
();
215
if
(
old_ranges
!=
ranges
())
clear
();
216
}
217
218
219
/// returns the current ranges
220
template
<
template
<
typename
>
class
ALLOC
>
221
INLINE
const
std
::
vector
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
>,
222
ALLOC
<
std
::
pair
<
std
::
size_t
,
std
::
size_t
> > >&
223
Score
<
ALLOC
>::
ranges
()
const
{
224
return
counter_
.
ranges
();
225
}
226
227
228
/// returns the score of a single node
229
template
<
template
<
typename
>
class
ALLOC
>
230
INLINE
double
Score
<
ALLOC
>::
score
(
const
NodeId
var
) {
231
IdCondSet
<
ALLOC
>
idset
(
var
,
empty_ids_
,
true
,
this
->
getAllocator
());
232
if
(
use_cache_
) {
233
try
{
234
return
cache_
.
score
(
idset
);
235
}
catch
(
NotFound
&) {}
236
double
the_score
=
score_
(
idset
);
237
cache_
.
insert
(
std
::
move
(
idset
),
the_score
);
238
return
the_score
;
239
}
else
{
240
return
score_
(
std
::
move
(
idset
));
241
}
242
}
243
244
245
/// returns the score of a single node given some other nodes
246
/** @param var1 the variable on the left side of the conditioning bar
247
* @param rhs_ids the set of variables on the right side of the
248
* conditioning bar */
249
template
<
template
<
typename
>
class
ALLOC
>
250
INLINE
double
Score
<
ALLOC
>::
score
(
251
const
NodeId
var
,
252
const
std
::
vector
<
NodeId
,
ALLOC
<
NodeId
> >&
rhs_ids
) {
253
IdCondSet
<
ALLOC
>
idset
(
var
,
rhs_ids
,
false
,
this
->
getAllocator
());
254
if
(
use_cache_
) {
255
try
{
256
return
cache_
.
score
(
idset
);
257
}
catch
(
NotFound
&) {}
258
double
the_score
=
score_
(
idset
);
259
cache_
.
insert
(
std
::
move
(
idset
),
the_score
);
260
return
the_score
;
261
}
else
{
262
return
score_
(
idset
);
263
}
264
}
265
266
267
/// clears all the data structures from memory
268
template
<
template
<
typename
>
class
ALLOC
>
269
INLINE
void
Score
<
ALLOC
>::
clear
() {
270
counter_
.
clear
();
271
cache_
.
clear
();
272
}
273
274
275
/// clears the current cache (clear nodesets as well)
276
template
<
template
<
typename
>
class
ALLOC
>
277
INLINE
void
Score
<
ALLOC
>::
clearCache
() {
278
cache_
.
clear
();
279
}
280
281
282
/// turn on/off the use of a cache of the previously computed score
283
template
<
template
<
typename
>
class
ALLOC
>
284
INLINE
void
Score
<
ALLOC
>::
useCache
(
const
bool
on_off
) {
285
use_cache_
=
on_off
;
286
}
287
288
289
/// indicates whether the score uses a cache
290
template
<
template
<
typename
>
class
ALLOC
>
291
INLINE
bool
Score
<
ALLOC
>::
isUsingCache
()
const
{
292
return
use_cache_
;
293
}
294
295
296
/// return the mapping between the columns of the database and the node ids
297
template
<
template
<
typename
>
class
ALLOC
>
298
INLINE
const
Bijection
<
NodeId
,
std
::
size_t
,
ALLOC
<
std
::
size_t
> >&
299
Score
<
ALLOC
>::
nodeId2Columns
()
const
{
300
return
counter_
.
nodeId2Columns
();
301
}
302
303
304
/// return the database used by the score
305
template
<
template
<
typename
>
class
ALLOC
>
306
INLINE
const
DatabaseTable
<
ALLOC
>&
Score
<
ALLOC
>::
database
()
const
{
307
return
counter_
.
database
();
308
}
309
310
/// returns a counting vector where variables are marginalized from N_xyz
311
/** @param X_size the domain size of the variable to marginalize (this
312
* is the first variable in table N_xyz
313
* @param N_xyz a counting vector of dimension X * cond_vars (in this order)
314
*/
315
template
<
template
<
typename
>
class
ALLOC
>
316
std
::
vector
<
double
,
ALLOC
<
double
> >
Score
<
ALLOC
>::
marginalize_
(
317
const
NodeId
X_id
,
318
const
std
::
vector
<
double
,
ALLOC
<
double
> >&
N_xyz
)
const
{
319
// compute the domain sizes of the varible on the left hand side
320
// of the conditioning bar
321
const
auto
&
nodeId2cols
=
this
->
counter_
.
nodeId2Columns
();
322
const
auto
&
database
=
this
->
counter_
.
database
();
323
const
std
::
size_t
X_size
=
database
.
domainSize
(
324
nodeId2cols
.
empty
() ?
X_id
:
nodeId2cols
.
second
(
X_id
));
325
326
// determine the size of the output vector
327
std
::
size_t
out_size
=
N_xyz
.
size
() /
X_size
;
328
329
// allocate the output vector
330
std
::
vector
<
double
,
ALLOC
<
double
> >
res
(
out_size
, 0.0);
331
332
// fill the vector:
333
std
::
size_t
xyz
=
std
::
size_t
(0);
334
for
(
std
::
size_t
z
=
std
::
size_t
(0);
z
<
out_size
; ++
z
) {
335
for
(
std
::
size_t
x
=
std
::
size_t
(0);
x
<
X_size
; ++
x
, ++
xyz
) {
336
res
[
z
] +=
N_xyz
[
xyz
];
337
}
338
}
339
340
return
res
;
341
}
342
343
344
}
/* namespace learning */
345
346
}
/* namespace gum */
347
348
#
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