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(
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 > >&
50  const typename Score< ALLOC >::allocator_type& alloc) :
54  }
55 
56 
57  /// default constructor
58  template < template < typename > class ALLOC >
59  INLINE Score< ALLOC >::Score(
61  const Apriori< ALLOC >& apriori,
62  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
64  const typename Score< ALLOC >::allocator_type& alloc) :
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) :
80  }
81 
82 
83  /// copy constructor
84  template < template < typename > class ALLOC >
85  INLINE Score< ALLOC >::Score(const Score< ALLOC >& from) :
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) :
97  from.apriori_ = nullptr;
99  }
100 
101 
102  /// move constructor
103  template < template < typename > class ALLOC >
104  INLINE Score< ALLOC >::Score(Score< ALLOC >&& from) :
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());
115  }
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) {
127 
128  if (apriori_ != nullptr) {
129  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
132  }
133 
136  cache_ = std::move(new_cache);
137 
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) {
149 
151  cache_ = std::move(from.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 {
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 {
177  }
178 
179 
180  /// returns the minimum of rows that each thread should process
181  template < template < typename > class ALLOC >
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();
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();
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);
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);
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();
325 
326  // determine the size of the output vector
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 */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
Database(const std::string &filename, const BayesNet< GUM_SCALAR > &bn, const std::vector< std::string > &missing_symbols)