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