aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
paramEstimator_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 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,
51  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
53  // copy the a prioris
55  try {
57  } catch (...) {
61  throw;
62  }
63 
65  }
66 
67 
68  /// default constructor
69  template < template < typename > class ALLOC >
72  const Apriori< ALLOC >& external_apriori,
75  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
77  // copy the a prioris
79  try {
81  } catch (...) {
85  throw;
86  }
87 
89  }
90 
91 
92  /// copy constructor with a given allocator
93  template < template < typename > class ALLOC >
95  const ParamEstimator< ALLOC >& from,
96  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
101  }
102 
103 
104  /// copy constructor
105  template < template < typename > class ALLOC >
108 
109 
110  /// move constructor with a given allocator
111  template < template < typename > class ALLOC >
114  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
118  from.external_apriori_ = nullptr;
119  from.score_internal_apriori_ = nullptr;
121  }
122 
123 
124  /// move constructor
125  template < template < typename > class ALLOC >
128 
129 
130  /// destructor
131  template < template < typename > class ALLOC >
133  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
134  if (external_apriori_ != nullptr) {
137  }
138 
139  if (score_internal_apriori_ != nullptr) {
142  }
143 
145  }
146 
147 
148  /// copy operator
149  template < template < typename > class ALLOC >
152  if (this != &from) {
153  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
154  if (external_apriori_ != nullptr) {
157  external_apriori_ = nullptr;
158  }
160 
161  if (score_internal_apriori_ != nullptr) {
164  external_apriori_ = nullptr;
165  }
167 
169  }
170  return *this;
171  }
172 
173 
174  /// move operator
175  template < template < typename > class ALLOC >
177  if (this != &from) {
181  from.external_apriori_ = nullptr;
182  from.score_internal_apriori_ = nullptr;
183  }
184  return *this;
185  }
186 
187 
188  /// clears all the data structures from memory
189  template < template < typename > class ALLOC >
190  INLINE void ParamEstimator< ALLOC >::clear() {
191  counter_.clear();
192  }
193 
194 
195  /// changes the max number of threads used to parse the database
196  template < template < typename > class ALLOC >
197  void ParamEstimator< ALLOC >::setMaxNbThreads(std::size_t nb) const {
199  }
200 
201 
202  /// returns the number of threads used to parse the database
203  template < template < typename > class ALLOC >
204  std::size_t ParamEstimator< ALLOC >::nbThreads() const {
205  return counter_.nbThreads();
206  }
207 
208 
209  /** @brief changes the number min of rows a thread should process in a
210  * multithreading context */
211  template < template < typename > class ALLOC >
212  INLINE void ParamEstimator< ALLOC >::setMinNbRowsPerThread(const std::size_t nb) const {
214  }
215 
216 
217  /// returns the minimum of rows that each thread should process
218  template < template < typename > class ALLOC >
220  return counter_.minNbRowsPerThread();
221  }
222 
223 
224  /// sets new ranges to perform the countings used by the score
225  /** @param ranges a set of pairs {(X1,Y1),...,(Xn,Yn)} of database's rows
226  * indices. The countings are then performed only on the union of the
227  * rows [Xi,Yi), i in {1,...,n}. This is useful, e.g, when performing
228  * cross validation tasks, in which part of the database should be ignored.
229  * An empty set of ranges is equivalent to an interval [X,Y) ranging over
230  * the whole database. */
231  template < template < typename > class ALLOC >
232  template < template < typename > class XALLOC >
233  void ParamEstimator< ALLOC >::setRanges(
234  const std::vector< std::pair< std::size_t, std::size_t >,
235  XALLOC< std::pair< std::size_t, std::size_t > > >& new_ranges) {
236  std::vector< std::pair< std::size_t, std::size_t >,
237  ALLOC< std::pair< std::size_t, std::size_t > > >
238  old_ranges = ranges();
240  if (old_ranges != ranges()) clear();
241  }
242 
243 
244  /// reset the ranges to the one range corresponding to the whole database
245  template < template < typename > class ALLOC >
246  void ParamEstimator< ALLOC >::clearRanges() {
247  std::vector< std::pair< std::size_t, std::size_t >,
248  ALLOC< std::pair< std::size_t, std::size_t > > >
249  old_ranges = ranges();
251  if (old_ranges != ranges()) clear();
252  }
253 
254 
255  /// returns the current ranges
256  template < template < typename > class ALLOC >
257  INLINE const std::vector< std::pair< std::size_t, std::size_t >,
258  ALLOC< std::pair< std::size_t, std::size_t > > >&
259  ParamEstimator< ALLOC >::ranges() const {
260  return counter_.ranges();
261  }
262 
263 
264  /// returns the CPT's parameters corresponding to a given target node
265  template < template < typename > class ALLOC >
266  INLINE std::vector< double, ALLOC< double > >
269  }
270 
271 
272  // check the coherency between the parameters passed to setParameters functions
273  template < template < typename > class ALLOC >
274  template < typename GUM_SCALAR >
276  const NodeId target_node,
278  Potential< GUM_SCALAR >& pot) {
279  // check that the nodes passed in arguments correspond to those of pot
280  const Sequence< const DiscreteVariable* >& vars = pot.variablesSequence();
281  if (vars.size() == 0) { GUM_ERROR(SizeError, "the potential contains no variable") }
282 
283  const auto& database = counter_.database();
284  const auto& node2cols = counter_.nodeId2Columns();
285  if (node2cols.empty()) {
288  "Variable " << vars[0]->name() << "of the potential to be filled "
289  << "has a domain size of " << vars[0]->domainSize()
290  << ", which is different from that of node " << target_node
291  << " which is equal to " << database.domainSize(target_node));
292  }
293  for (std::size_t i = 1; i < vars.size(); ++i) {
296  "Variable " << vars[i]->name() << "of the potential to be filled "
297  << "has a domain size of " << vars[i]->domainSize()
298  << ", which is different from that of node "
299  << conditioning_nodes[i - 1] << " which is equal to "
301  }
302  }
303  } else {
305  if (database.domainSize(col) != vars[0]->domainSize()) {
307  "Variable " << vars[0]->name() << "of the potential to be filled "
308  << "has a domain size of " << vars[0]->domainSize()
309  << ", which is different from that of node " << target_node
310  << " which is equal to " << database.domainSize(col));
311  }
312  for (std::size_t i = 1; i < vars.size(); ++i) {
314  if (database.domainSize(col) != vars[i]->domainSize()) {
316  "Variable " << vars[i]->name() << "of the potential to be filled "
317  << "has a domain size of " << vars[i]->domainSize()
318  << ", which is different from that of node "
319  << conditioning_nodes[i - 1] << " which is equal to "
320  << database.domainSize(col));
321  }
322  }
323  }
324  }
325 
326 
327  /// sets the CPT's parameters corresponding to a given nodeset
328  template < template < typename > class ALLOC >
329  template < typename GUM_SCALAR >
330  INLINE typename std::enable_if< !std::is_same< GUM_SCALAR, double >::value, void >::type
332  const NodeId target_node,
334  Potential< GUM_SCALAR >& pot) {
336 
337  const std::vector< double, ALLOC< double > > params(
339 
340  // transform the vector of double into a vector of GUM_SCALAR
341  const std::size_t size = params.size();
343  for (std::size_t i = std::size_t(0); i < size; ++i)
344  xparams[i] = GUM_SCALAR(params[i]);
345 
347  }
348 
349 
350  /// sets the CPT's parameters corresponding to a given nodeset
351  template < template < typename > class ALLOC >
352  template < typename GUM_SCALAR >
353  INLINE typename std::enable_if< std::is_same< GUM_SCALAR, double >::value, void >::type
355  const NodeId target_node,
357  Potential< GUM_SCALAR >& pot) {
359 
360  const std::vector< double, ALLOC< double > > params(
363  }
364 
365 
366  /// sets the CPT's parameters corresponding to a given nodeset
367  template < template < typename > class ALLOC >
368  template < typename GUM_SCALAR >
370  const NodeId target_node,
372  Potential< GUM_SCALAR >& pot) {
374  }
375 
376 
377  /// returns the mapping from ids to column positions in the database
378  template < template < typename > class ALLOC >
379  INLINE const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
380  ParamEstimator< ALLOC >::nodeId2Columns() const {
381  return counter_.nodeId2Columns();
382  }
383 
384 
385  /// returns the database on which we perform the counts
386  template < template < typename > class ALLOC >
387  INLINE const DatabaseTable< ALLOC >& ParamEstimator< ALLOC >::database() const {
388  return counter_.database();
389  }
390 
391 
392  /// assign a new Bayes net to all the counter's generators depending on a BN
393  template < template < typename > class ALLOC >
394  template < typename GUM_SCALAR >
397  }
398 
399 
400  } /* namespace learning */
401 
402 } /* namespace gum */
403 
404 #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)