aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
paramEstimator_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 estimating parameters of CPTs
24  *
25  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 
28 #ifndef DOXYGEN_SHOULD_SKIP_THIS
29 
30 namespace gum {
31 
32  namespace learning {
33 
34  /// returns the allocator used by the score
35  template < template < typename > class ALLOC >
37  ParamEstimator< ALLOC >::getAllocator() const {
38  return counter_.getAllocator();
39  }
40 
41 
42  /// default constructor
43  template < template < typename > class ALLOC >
46  const Apriori< ALLOC >& external_apriori,
48  const std::vector< std::pair< std::size_t, std::size_t >,
49  ALLOC< std::pair< std::size_t, std::size_t > > >& ranges,
50  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
52  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
54  // copy the a prioris
56  try {
58  } catch (...) {
62  throw;
63  }
64 
66  }
67 
68 
69  /// default constructor
70  template < template < typename > class ALLOC >
73  const Apriori< ALLOC >& external_apriori,
75  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
77  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
79  // copy the a prioris
81  try {
83  } catch (...) {
87  throw;
88  }
89 
91  }
92 
93 
94  /// copy constructor with a given allocator
95  template < template < typename > class ALLOC >
97  const ParamEstimator< ALLOC >& from,
98  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
103  }
104 
105 
106  /// copy constructor
107  template < template < typename > class ALLOC >
109  const ParamEstimator< ALLOC >& from) :
111 
112 
113  /// move constructor with a given allocator
114  template < template < typename > class ALLOC >
117  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
121  from.external_apriori_ = nullptr;
122  from.score_internal_apriori_ = nullptr;
124  }
125 
126 
127  /// move constructor
128  template < template < typename > class ALLOC >
129  INLINE
132 
133 
134  /// destructor
135  template < template < typename > class ALLOC >
137  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
138  if (external_apriori_ != nullptr) {
141  }
142 
143  if (score_internal_apriori_ != nullptr) {
146  }
147 
149  }
150 
151 
152  /// copy operator
153  template < template < typename > class ALLOC >
156  if (this != &from) {
157  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
158  if (external_apriori_ != nullptr) {
161  external_apriori_ = nullptr;
162  }
164 
165  if (score_internal_apriori_ != nullptr) {
168  external_apriori_ = nullptr;
169  }
172 
174  }
175  return *this;
176  }
177 
178 
179  /// move operator
180  template < template < typename > class ALLOC >
183  if (this != &from) {
187  from.external_apriori_ = nullptr;
188  from.score_internal_apriori_ = nullptr;
189  }
190  return *this;
191  }
192 
193 
194  /// clears all the data structures from memory
195  template < template < typename > class ALLOC >
196  INLINE void ParamEstimator< ALLOC >::clear() {
197  counter_.clear();
198  }
199 
200 
201  /// changes the max number of threads used to parse the database
202  template < template < typename > class ALLOC >
203  void ParamEstimator< ALLOC >::setMaxNbThreads(std::size_t nb) const {
205  }
206 
207 
208  /// returns the number of threads used to parse the database
209  template < template < typename > class ALLOC >
210  std::size_t ParamEstimator< ALLOC >::nbThreads() const {
211  return counter_.nbThreads();
212  }
213 
214 
215  /** @brief changes the number min of rows a thread should process in a
216  * multithreading context */
217  template < template < typename > class ALLOC >
218  INLINE void
221  }
222 
223 
224  /// returns the minimum of rows that each thread should process
225  template < template < typename > class ALLOC >
227  return counter_.minNbRowsPerThread();
228  }
229 
230 
231  /// sets new ranges to perform the countings used by the score
232  /** @param ranges a set of pairs {(X1,Y1),...,(Xn,Yn)} of database's rows
233  * indices. The countings are then performed only on the union of the
234  * rows [Xi,Yi), i in {1,...,n}. This is useful, e.g, when performing
235  * cross validation tasks, in which part of the database should be ignored.
236  * An empty set of ranges is equivalent to an interval [X,Y) ranging over
237  * the whole database. */
238  template < template < typename > class ALLOC >
239  template < template < typename > class XALLOC >
240  void ParamEstimator< ALLOC >::setRanges(
241  const std::vector< std::pair< std::size_t, std::size_t >,
242  XALLOC< std::pair< std::size_t, std::size_t > > >&
243  new_ranges) {
244  std::vector< std::pair< std::size_t, std::size_t >,
245  ALLOC< std::pair< std::size_t, std::size_t > > >
246  old_ranges = ranges();
248  if (old_ranges != ranges()) clear();
249  }
250 
251 
252  /// reset the ranges to the one range corresponding to the whole database
253  template < template < typename > class ALLOC >
254  void ParamEstimator< ALLOC >::clearRanges() {
255  std::vector< std::pair< std::size_t, std::size_t >,
256  ALLOC< std::pair< std::size_t, std::size_t > > >
257  old_ranges = ranges();
259  if (old_ranges != ranges()) clear();
260  }
261 
262 
263  /// returns the current ranges
264  template < template < typename > class ALLOC >
265  INLINE const std::vector< std::pair< std::size_t, std::size_t >,
266  ALLOC< std::pair< std::size_t, std::size_t > > >&
267  ParamEstimator< ALLOC >::ranges() const {
268  return counter_.ranges();
269  }
270 
271 
272  /// returns the CPT's parameters corresponding to a given target node
273  template < template < typename > class ALLOC >
274  INLINE std::vector< double, ALLOC< double > >
277  }
278 
279 
280  // check the coherency between the parameters passed to setParameters functions
281  template < template < typename > class ALLOC >
282  template < typename GUM_SCALAR >
284  const NodeId target_node,
286  Potential< GUM_SCALAR >& pot) {
287  // check that the nodes passed in arguments correspond to those of pot
288  const Sequence< const DiscreteVariable* >& vars = pot.variablesSequence();
289  if (vars.size() == 0) {
290  GUM_ERROR(SizeError, "the potential contains no variable");
291  }
292 
293  const auto& database = counter_.database();
294  const auto& node2cols = counter_.nodeId2Columns();
295  if (node2cols.empty()) {
298  "Variable "
299  << vars[0]->name() << "of the potential to be filled "
300  << "has a domain size of " << vars[0]->domainSize()
301  << ", which is different from that of node " << target_node
302  << " which is equal to "
304  }
305  for (std::size_t i = 1; i < vars.size(); ++i) {
307  != vars[i]->domainSize()) {
309  "Variable "
310  << vars[i]->name() << "of the potential to be filled "
311  << "has a domain size of " << vars[i]->domainSize()
312  << ", which is different from that of node "
313  << conditioning_nodes[i - 1] << " which is equal to "
315  }
316  }
317  } else {
319  if (database.domainSize(col) != vars[0]->domainSize()) {
321  "Variable "
322  << vars[0]->name() << "of the potential to be filled "
323  << "has a domain size of " << vars[0]->domainSize()
324  << ", which is different from that of node " << target_node
325  << " which is equal to " << database.domainSize(col));
326  }
327  for (std::size_t i = 1; i < vars.size(); ++i) {
329  if (database.domainSize(col) != vars[i]->domainSize()) {
331  "Variable "
332  << vars[i]->name() << "of the potential to be filled "
333  << "has a domain size of " << vars[i]->domainSize()
334  << ", which is different from that of node "
335  << conditioning_nodes[i - 1] << " which is equal to "
336  << database.domainSize(col));
337  }
338  }
339  }
340  }
341 
342 
343  /// sets the CPT's parameters corresponding to a given nodeset
344  template < template < typename > class ALLOC >
345  template < typename GUM_SCALAR >
346  INLINE typename std::enable_if< !std::is_same< GUM_SCALAR, double >::value,
347  void >::type
349  const NodeId target_node,
351  Potential< GUM_SCALAR >& pot) {
353 
354  const std::vector< double, ALLOC< double > > params(
356 
357  // transform the vector of double into a vector of GUM_SCALAR
358  const std::size_t size = params.size();
360  for (std::size_t i = std::size_t(0); i < size; ++i)
361  xparams[i] = GUM_SCALAR(params[i]);
362 
364  }
365 
366 
367  /// sets the CPT's parameters corresponding to a given nodeset
368  template < template < typename > class ALLOC >
369  template < typename GUM_SCALAR >
370  INLINE typename std::enable_if< std::is_same< GUM_SCALAR, double >::value,
371  void >::type
373  const NodeId target_node,
375  Potential< GUM_SCALAR >& pot) {
377 
378  const std::vector< double, ALLOC< double > > params(
381  }
382 
383 
384  /// sets the CPT's parameters corresponding to a given nodeset
385  template < template < typename > class ALLOC >
386  template < typename GUM_SCALAR >
388  const NodeId target_node,
390  Potential< GUM_SCALAR >& pot) {
392  }
393 
394 
395  /// returns the mapping from ids to column positions in the database
396  template < template < typename > class ALLOC >
397  INLINE const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
398  ParamEstimator< ALLOC >::nodeId2Columns() const {
399  return counter_.nodeId2Columns();
400  }
401 
402 
403  /// returns the database on which we perform the counts
404  template < template < typename > class ALLOC >
405  INLINE const DatabaseTable< ALLOC >&
406  ParamEstimator< ALLOC >::database() const {
407  return counter_.database();
408  }
409 
410 
411  /// assign a new Bayes net to all the counter's generators depending on a BN
412  template < template < typename > class ALLOC >
413  template < typename GUM_SCALAR >
414  INLINE void
417  }
418 
419 
420  } /* namespace learning */
421 
422 } /* namespace gum */
423 
424 #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)