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(
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,
48  const typename Score< ALLOC >::allocator_type& alloc) :
52  }
53 
54 
55  /// default constructor
56  template < template < typename > class ALLOC >
57  INLINE Score< ALLOC >::Score(
59  const Apriori< ALLOC >& apriori,
61  const typename Score< ALLOC >::allocator_type& alloc) :
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) :
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 >
86  const typename Score< ALLOC >::allocator_type& alloc) :
90  from.apriori_ = nullptr;
92  }
93 
94 
95  /// move constructor
96  template < template < typename > class ALLOC >
97  INLINE Score< ALLOC >::Score(Score< ALLOC >&& from) :
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());
108  }
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) {
120 
121  if (apriori_ != nullptr) {
122  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
125  }
126 
129  cache_ = std::move(new_cache);
130 
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) {
142 
144  cache_ = std::move(from.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 {
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 {
170  }
171 
172 
173  /// returns the minimum of rows that each thread should process
174  template < template < typename > class ALLOC >
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();
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();
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);
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);
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
316 
317  // determine the size of the output vector
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 */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
Database(const std::string &filename, const BayesNet< GUM_SCALAR > &bn, const std::vector< std::string > &missing_symbols)