aGrUM  0.14.2
paramEstimator_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
26 #ifndef DOXYGEN_SHOULD_SKIP_THIS
27 
28 namespace gum {
29 
30  namespace learning {
31 
33  template < template < typename > class ALLOC >
36  return _counter.getAllocator();
37  }
38 
39 
41  template < template < typename > class ALLOC >
43  const DBRowGeneratorParser< ALLOC >& parser,
44  const Apriori< ALLOC >& external_apriori,
45  const Apriori< ALLOC >& score_internal_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 > >&
49  nodeId2columns,
50  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
51  _counter(parser, ranges, nodeId2columns, alloc) {
52  // copy the a prioris
53  _external_apriori = external_apriori.clone(alloc);
54  try {
55  _score_internal_apriori = score_internal_apriori.clone();
56  } catch (...) {
57  ALLOC< Apriori< ALLOC > > allocator(alloc);
58  allocator.destroy(_external_apriori);
59  allocator.deallocate(_external_apriori, 1);
60  throw;
61  }
62 
63  GUM_CONSTRUCTOR(ParamEstimator);
64  }
65 
66 
68  template < template < typename > class ALLOC >
70  const DBRowGeneratorParser< ALLOC >& parser,
71  const Apriori< ALLOC >& external_apriori,
72  const Apriori< ALLOC >& score_internal_apriori,
73  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
74  nodeId2columns,
75  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
76  _counter(parser, nodeId2columns, alloc) {
77  // copy the a prioris
78  _external_apriori = external_apriori.clone(alloc);
79  try {
80  _score_internal_apriori = score_internal_apriori.clone();
81  } catch (...) {
82  ALLOC< Apriori< ALLOC > > allocator(alloc);
83  allocator.destroy(_external_apriori);
84  allocator.deallocate(_external_apriori, 1);
85  throw;
86  }
87 
88  GUM_CONSTRUCTOR(ParamEstimator);
89  }
90 
91 
93  template < template < typename > class ALLOC >
95  const ParamEstimator< ALLOC >& from,
96  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
99  _counter(from._counter, alloc) {
100  GUM_CONS_CPY(ParamEstimator);
101  }
102 
103 
105  template < template < typename > class ALLOC >
107  const ParamEstimator< ALLOC >& from) :
108  ParamEstimator< ALLOC >(from, from.getAllocator()) {}
109 
110 
112  template < template < typename > class ALLOC >
114  ParamEstimator< ALLOC >&& from,
115  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
118  _counter(std::move(from._counter), alloc) {
119  from._external_apriori = nullptr;
120  from._score_internal_apriori = nullptr;
121  GUM_CONS_MOV(ParamEstimator);
122  }
123 
124 
126  template < template < typename > class ALLOC >
127  INLINE
128  ParamEstimator< ALLOC >::ParamEstimator(ParamEstimator< ALLOC >&& from) :
129  ParamEstimator< ALLOC >(std::move(from), from.getAllocator()) {}
130 
131 
133  template < template < typename > class ALLOC >
135  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
136  if (_external_apriori != nullptr) {
137  allocator.destroy(_external_apriori);
138  allocator.deallocate(_external_apriori, 1);
139  }
140 
141  if (_score_internal_apriori != nullptr) {
142  allocator.destroy(_score_internal_apriori);
143  allocator.deallocate(_score_internal_apriori, 1);
144  }
145 
146  GUM_DESTRUCTOR(ParamEstimator);
147  }
148 
149 
151  template < template < typename > class ALLOC >
152  ParamEstimator< ALLOC >& ParamEstimator< ALLOC >::
153  operator=(const ParamEstimator< ALLOC >& from) {
154  if (this != &from) {
155  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
156  if (_external_apriori != nullptr) {
157  allocator.destroy(_external_apriori);
158  allocator.deallocate(_external_apriori, 1);
159  _external_apriori = nullptr;
160  }
161  _external_apriori = from._external_apriori->clone(this->getAllocator());
162 
163  if (_score_internal_apriori != nullptr) {
164  allocator.destroy(_score_internal_apriori);
165  allocator.deallocate(_score_internal_apriori, 1);
166  _external_apriori = nullptr;
167  }
169  from._score_internal_apriori->clone(this->getAllocator());
170 
171  _counter = from._counter;
172  }
173  return *this;
174  }
175 
176 
178  template < template < typename > class ALLOC >
179  ParamEstimator< ALLOC >& ParamEstimator< ALLOC >::
180  operator=(ParamEstimator< ALLOC >&& from) {
181  if (this != &from) {
182  _external_apriori = from._external_apriori;
183  _score_internal_apriori = from._score_internal_apriori;
184  _counter = std::move(from._counter);
185  from._external_apriori = nullptr;
186  from._score_internal_apriori = nullptr;
187  }
188  return *this;
189  }
190 
191 
193  template < template < typename > class ALLOC >
194  INLINE void ParamEstimator< ALLOC >::clear() {
195  _counter.clear();
196  }
197 
198 
200  template < template < typename > class ALLOC >
201  void ParamEstimator< ALLOC >::setMaxNbThreads(std::size_t nb) const {
202  _counter.setMaxNbThreads(nb);
203  }
204 
205 
207  template < template < typename > class ALLOC >
208  std::size_t ParamEstimator< ALLOC >::nbThreads() const {
209  return _counter.nbThreads();
210  }
211 
212 
215  template < template < typename > class ALLOC >
216  INLINE void
217  ParamEstimator< ALLOC >::setMinNbRowsPerThread(const std::size_t nb) const {
218  _counter.setMinNbRowsPerThread(nb);
219  }
220 
221 
223  template < template < typename > class ALLOC >
224  INLINE std::size_t ParamEstimator< ALLOC >::minNbRowsPerThread() const {
225  return _counter.minNbRowsPerThread();
226  }
227 
228 
230 
236  template < template < typename > class ALLOC >
237  template < template < typename > class XALLOC >
239  const std::vector< std::pair< std::size_t, std::size_t >,
240  XALLOC< std::pair< std::size_t, std::size_t > > >&
241  new_ranges) {
242  std::vector< std::pair< std::size_t, std::size_t >,
243  ALLOC< std::pair< std::size_t, std::size_t > > >
244  old_ranges = ranges();
245  _counter.setRanges(new_ranges);
246  if (old_ranges != ranges()) clear();
247  }
248 
249 
251  template < template < typename > class ALLOC >
253  std::vector< std::pair< std::size_t, std::size_t >,
254  ALLOC< std::pair< std::size_t, std::size_t > > >
255  old_ranges = ranges();
256  _counter.clearRanges();
257  if (old_ranges != ranges()) clear();
258  }
259 
260 
262  template < template < typename > class ALLOC >
263  INLINE const std::vector< std::pair< std::size_t, std::size_t >,
264  ALLOC< std::pair< std::size_t, std::size_t > > >&
266  return _counter.ranges();
267  }
268 
269 
271  template < template < typename > class ALLOC >
272  INLINE std::vector< double, ALLOC< double > >
273  ParamEstimator< ALLOC >::parameters(const NodeId target_node) {
274  return parameters(target_node, _empty_nodevect);
275  }
276 
277 
278  // check the coherency between the parameters passed to setParameters functions
279  template < template < typename > class ALLOC >
280  template < typename GUM_SCALAR >
281  void ParamEstimator< ALLOC >::__checkParameters(
282  const NodeId target_node,
283  const std::vector< NodeId, ALLOC< NodeId > >& conditioning_nodes,
284  Potential< GUM_SCALAR >& pot) {
285  // check that the nodes passed in arguments correspond to those of pot
286  const Sequence< const DiscreteVariable* >& vars = pot.variablesSequence();
287  if (vars.size() == 0) {
288  GUM_ERROR(SizeError, "the potential contains no variable");
289  }
290 
291  const auto& database = _counter.database();
292  const auto& node2cols = _counter.nodeId2Columns();
293  if (node2cols.empty()) {
294  if (database.domainSize(target_node) != vars[0]->domainSize()) {
295  GUM_ERROR(SizeError,
296  "Variable "
297  << vars[0]->name() << "of the potential to be filled "
298  << "has a domain size of " << vars[0]->domainSize()
299  << ", which is different from that of node " << target_node
300  << " which is equal to "
301  << database.domainSize(target_node));
302  }
303  for (std::size_t i = 1; i < vars.size(); ++i) {
304  if (database.domainSize(conditioning_nodes[i - 1])
305  != vars[i]->domainSize()) {
306  GUM_ERROR(SizeError,
307  "Variable "
308  << vars[i]->name() << "of the potential to be filled "
309  << "has a domain size of " << vars[i]->domainSize()
310  << ", which is different from that of node "
311  << conditioning_nodes[i - 1] << " which is equal to "
312  << database.domainSize(conditioning_nodes[i - 1]));
313  }
314  }
315  } else {
316  std::size_t col = node2cols.second(target_node);
317  if (database.domainSize(col) != vars[0]->domainSize()) {
318  GUM_ERROR(SizeError,
319  "Variable "
320  << vars[0]->name() << "of the potential to be filled "
321  << "has a domain size of " << vars[0]->domainSize()
322  << ", which is different from that of node " << target_node
323  << " which is equal to " << database.domainSize(col));
324  }
325  for (std::size_t i = 1; i < vars.size(); ++i) {
326  col = node2cols.second(conditioning_nodes[i - 1]);
327  if (database.domainSize(col) != vars[i]->domainSize()) {
328  GUM_ERROR(SizeError,
329  "Variable "
330  << vars[i]->name() << "of the potential to be filled "
331  << "has a domain size of " << vars[i]->domainSize()
332  << ", which is different from that of node "
333  << conditioning_nodes[i - 1] << " which is equal to "
334  << database.domainSize(col));
335  }
336  }
337  }
338  }
339 
340 
342  template < template < typename > class ALLOC >
343  template < typename GUM_SCALAR >
344  INLINE typename std::enable_if< !std::is_same< GUM_SCALAR, double >::value,
345  void >::type
346  ParamEstimator< ALLOC >::__setParameters(
347  const NodeId target_node,
348  const std::vector< NodeId, ALLOC< NodeId > >& conditioning_nodes,
349  Potential< GUM_SCALAR >& pot) {
350  __checkParameters(target_node, conditioning_nodes, pot);
351 
352  const std::vector< double, ALLOC< double > > params(
353  parameters(target_node, conditioning_nodes));
354 
355  // transform the vector of double into a vector of GUM_SCALAR
356  const std::size_t size = params.size();
357  std::vector< GUM_SCALAR, ALLOC< GUM_SCALAR > > xparams(size);
358  for (std::size_t i = std::size_t(0); i < size; ++i)
359  xparams[i] = GUM_SCALAR(params[i]);
360 
361  pot.fillWith(xparams);
362  }
363 
364 
366  template < template < typename > class ALLOC >
367  template < typename GUM_SCALAR >
368  INLINE typename std::enable_if< std::is_same< GUM_SCALAR, double >::value,
369  void >::type
370  ParamEstimator< ALLOC >::__setParameters(
371  const NodeId target_node,
372  const std::vector< NodeId, ALLOC< NodeId > >& conditioning_nodes,
373  Potential< GUM_SCALAR >& pot) {
374  __checkParameters(target_node, conditioning_nodes, pot);
375 
376  const std::vector< double, ALLOC< double > > params(
377  parameters(target_node, conditioning_nodes));
378  pot.fillWith(params);
379  }
380 
381 
383  template < template < typename > class ALLOC >
384  template < typename GUM_SCALAR >
386  const NodeId target_node,
387  const std::vector< NodeId, ALLOC< NodeId > >& conditioning_nodes,
388  Potential< GUM_SCALAR >& pot) {
389  __setParameters(target_node, conditioning_nodes, pot);
390  }
391 
392 
394  template < template < typename > class ALLOC >
395  INLINE const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
397  return _counter.nodeId2Columns();
398  }
399 
400 
402  template < template < typename > class ALLOC >
403  INLINE const DatabaseTable< ALLOC >&
405  return _counter.database();
406  }
407 
408 
410  template < template < typename > class ALLOC >
411  template < typename GUM_SCALAR >
412  INLINE void
413  ParamEstimator< ALLOC >::setBayesNet(const BayesNet< GUM_SCALAR >& new_bn) {
414  _counter.setBayesNet(new_bn);
415  }
416 
417 
418  } /* namespace learning */
419 
420 } /* namespace gum */
421 
422 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
ParamEstimator< ALLOC > & operator=(const ParamEstimator< ALLOC > &from)
copy operator
const Bijection< NodeId, std::size_t, ALLOC< std::size_t > > & nodeId2Columns() const
returns the mapping from ids to column positions in the database
void setParameters(const NodeId target_node, const std::vector< NodeId, ALLOC< NodeId > > &conditioning_nodes, Potential< GUM_SCALAR > &pot)
sets the CPT&#39;s parameters corresponding to a given Potential
void clearRanges()
reset the ranges to the one range corresponding to the whole database
ParamEstimator(const DBRowGeneratorParser< ALLOC > &parser, const Apriori< ALLOC > &external_apriori, const Apriori< ALLOC > &score_internal__apriori, const std::vector< std::pair< std::size_t, std::size_t >, ALLOC< std::pair< std::size_t, std::size_t > > > &ranges, const Bijection< NodeId, std::size_t, ALLOC< std::size_t > > &nodeId2columns=Bijection< NodeId, std::size_t, ALLOC< std::size_t > >(), const allocator_type &alloc=allocator_type())
default constructor
void setRanges(const std::vector< std::pair< std::size_t, std::size_t >, XALLOC< std::pair< std::size_t, std::size_t > > > &new_ranges)
sets new ranges to perform the countings used by the parameter estimator
STL namespace.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
const std::vector< std::pair< std::size_t, std::size_t >, ALLOC< std::pair< std::size_t, std::size_t > > > & ranges() const
returns the current ranges
void setBayesNet(const BayesNet< GUM_SCALAR > &new_bn)
assign a new Bayes net to all the counter&#39;s generators depending on a BN
Apriori< ALLOC > * _score_internal_apriori
if a score was used for learning the structure of the PGM, this is the a priori internal to the score...
Apriori< ALLOC > * _external_apriori
an external a priori
allocator_type getAllocator() const
returns the allocator used by the score
virtual void setMinNbRowsPerThread(const std::size_t nb) const
changes the number min of rows a thread should process in a multithreading context ...
virtual ~ParamEstimator()
destructor
const DatabaseTable< ALLOC > & database() const
returns the database on which we perform the counts
std::vector< double, ALLOC< double > > parameters(const NodeId target_node)
returns the CPT&#39;s parameters corresponding to a given target node
virtual void clear()
clears all the data structures from memory
virtual std::size_t nbThreads() const
returns the number of threads used to parse the database
virtual ParamEstimator< ALLOC > * clone() const =0
virtual copy constructor
ALLOC< NodeId > allocator_type
type for the allocators passed in arguments of methods
virtual void setMaxNbThreads(std::size_t nb) const
changes the max number of threads used to parse the database
virtual std::size_t minNbRowsPerThread() const
returns the minimum of rows that each thread should process
Size NodeId
Type for node ids.
Definition: graphElements.h:97
RecordCounter< ALLOC > _counter
the record counter used to parse the database
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
const std::vector< NodeId, ALLOC< NodeId > > _empty_nodevect
an empty vector of nodes, used for empty conditioning