aGrUM  0.16.0
paramEstimator_tpl.h
Go to the documentation of this file.
1 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
31 namespace gum {
32 
33  namespace learning {
34 
36  template < template < typename > class ALLOC >
39  return _counter.getAllocator();
40  }
41 
42 
44  template < template < typename > class ALLOC >
46  const DBRowGeneratorParser< ALLOC >& parser,
47  const Apriori< ALLOC >& external_apriori,
48  const Apriori< ALLOC >& score_internal_apriori,
49  const std::vector< std::pair< std::size_t, std::size_t >,
50  ALLOC< std::pair< std::size_t, std::size_t > > >& ranges,
51  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
52  nodeId2columns,
53  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
54  _counter(parser, ranges, nodeId2columns, alloc) {
55  // copy the a prioris
56  _external_apriori = external_apriori.clone(alloc);
57  try {
58  _score_internal_apriori = score_internal_apriori.clone();
59  } catch (...) {
60  ALLOC< Apriori< ALLOC > > allocator(alloc);
61  allocator.destroy(_external_apriori);
62  allocator.deallocate(_external_apriori, 1);
63  throw;
64  }
65 
66  GUM_CONSTRUCTOR(ParamEstimator);
67  }
68 
69 
71  template < template < typename > class ALLOC >
73  const DBRowGeneratorParser< ALLOC >& parser,
74  const Apriori< ALLOC >& external_apriori,
75  const Apriori< ALLOC >& score_internal_apriori,
76  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
77  nodeId2columns,
78  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
79  _counter(parser, nodeId2columns, alloc) {
80  // copy the a prioris
81  _external_apriori = external_apriori.clone(alloc);
82  try {
83  _score_internal_apriori = score_internal_apriori.clone();
84  } catch (...) {
85  ALLOC< Apriori< ALLOC > > allocator(alloc);
86  allocator.destroy(_external_apriori);
87  allocator.deallocate(_external_apriori, 1);
88  throw;
89  }
90 
91  GUM_CONSTRUCTOR(ParamEstimator);
92  }
93 
94 
96  template < template < typename > class ALLOC >
98  const ParamEstimator< ALLOC >& from,
99  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
102  _counter(from._counter, alloc) {
103  GUM_CONS_CPY(ParamEstimator);
104  }
105 
106 
108  template < template < typename > class ALLOC >
110  const ParamEstimator< ALLOC >& from) :
111  ParamEstimator< ALLOC >(from, from.getAllocator()) {}
112 
113 
115  template < template < typename > class ALLOC >
117  ParamEstimator< ALLOC >&& from,
118  const typename ParamEstimator< ALLOC >::allocator_type& alloc) :
121  _counter(std::move(from._counter), alloc) {
122  from._external_apriori = nullptr;
123  from._score_internal_apriori = nullptr;
124  GUM_CONS_MOV(ParamEstimator);
125  }
126 
127 
129  template < template < typename > class ALLOC >
130  INLINE
131  ParamEstimator< ALLOC >::ParamEstimator(ParamEstimator< ALLOC >&& from) :
132  ParamEstimator< ALLOC >(std::move(from), from.getAllocator()) {}
133 
134 
136  template < template < typename > class ALLOC >
138  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
139  if (_external_apriori != nullptr) {
140  allocator.destroy(_external_apriori);
141  allocator.deallocate(_external_apriori, 1);
142  }
143 
144  if (_score_internal_apriori != nullptr) {
145  allocator.destroy(_score_internal_apriori);
146  allocator.deallocate(_score_internal_apriori, 1);
147  }
148 
149  GUM_DESTRUCTOR(ParamEstimator);
150  }
151 
152 
154  template < template < typename > class ALLOC >
155  ParamEstimator< ALLOC >& ParamEstimator< ALLOC >::
156  operator=(const ParamEstimator< ALLOC >& from) {
157  if (this != &from) {
158  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
159  if (_external_apriori != nullptr) {
160  allocator.destroy(_external_apriori);
161  allocator.deallocate(_external_apriori, 1);
162  _external_apriori = nullptr;
163  }
164  _external_apriori = from._external_apriori->clone(this->getAllocator());
165 
166  if (_score_internal_apriori != nullptr) {
167  allocator.destroy(_score_internal_apriori);
168  allocator.deallocate(_score_internal_apriori, 1);
169  _external_apriori = nullptr;
170  }
172  from._score_internal_apriori->clone(this->getAllocator());
173 
174  _counter = from._counter;
175  }
176  return *this;
177  }
178 
179 
181  template < template < typename > class ALLOC >
182  ParamEstimator< ALLOC >& ParamEstimator< ALLOC >::
183  operator=(ParamEstimator< ALLOC >&& from) {
184  if (this != &from) {
185  _external_apriori = from._external_apriori;
186  _score_internal_apriori = from._score_internal_apriori;
187  _counter = std::move(from._counter);
188  from._external_apriori = nullptr;
189  from._score_internal_apriori = nullptr;
190  }
191  return *this;
192  }
193 
194 
196  template < template < typename > class ALLOC >
197  INLINE void ParamEstimator< ALLOC >::clear() {
198  _counter.clear();
199  }
200 
201 
203  template < template < typename > class ALLOC >
204  void ParamEstimator< ALLOC >::setMaxNbThreads(std::size_t nb) const {
205  _counter.setMaxNbThreads(nb);
206  }
207 
208 
210  template < template < typename > class ALLOC >
211  std::size_t ParamEstimator< ALLOC >::nbThreads() const {
212  return _counter.nbThreads();
213  }
214 
215 
218  template < template < typename > class ALLOC >
219  INLINE void
220  ParamEstimator< ALLOC >::setMinNbRowsPerThread(const std::size_t nb) const {
221  _counter.setMinNbRowsPerThread(nb);
222  }
223 
224 
226  template < template < typename > class ALLOC >
227  INLINE std::size_t ParamEstimator< ALLOC >::minNbRowsPerThread() const {
228  return _counter.minNbRowsPerThread();
229  }
230 
231 
233 
239  template < template < typename > class ALLOC >
240  template < template < typename > class XALLOC >
242  const std::vector< std::pair< std::size_t, std::size_t >,
243  XALLOC< std::pair< std::size_t, std::size_t > > >&
244  new_ranges) {
245  std::vector< std::pair< std::size_t, std::size_t >,
246  ALLOC< std::pair< std::size_t, std::size_t > > >
247  old_ranges = ranges();
248  _counter.setRanges(new_ranges);
249  if (old_ranges != ranges()) clear();
250  }
251 
252 
254  template < template < typename > class ALLOC >
256  std::vector< std::pair< std::size_t, std::size_t >,
257  ALLOC< std::pair< std::size_t, std::size_t > > >
258  old_ranges = ranges();
259  _counter.clearRanges();
260  if (old_ranges != ranges()) clear();
261  }
262 
263 
265  template < template < typename > class ALLOC >
266  INLINE const std::vector< std::pair< std::size_t, std::size_t >,
267  ALLOC< std::pair< std::size_t, std::size_t > > >&
269  return _counter.ranges();
270  }
271 
272 
274  template < template < typename > class ALLOC >
275  INLINE std::vector< double, ALLOC< double > >
276  ParamEstimator< ALLOC >::parameters(const NodeId target_node) {
277  return parameters(target_node, _empty_nodevect);
278  }
279 
280 
281  // check the coherency between the parameters passed to setParameters functions
282  template < template < typename > class ALLOC >
283  template < typename GUM_SCALAR >
284  void ParamEstimator< ALLOC >::__checkParameters(
285  const NodeId target_node,
286  const std::vector< NodeId, ALLOC< NodeId > >& conditioning_nodes,
287  Potential< GUM_SCALAR >& pot) {
288  // check that the nodes passed in arguments correspond to those of pot
289  const Sequence< const DiscreteVariable* >& vars = pot.variablesSequence();
290  if (vars.size() == 0) {
291  GUM_ERROR(SizeError, "the potential contains no variable");
292  }
293 
294  const auto& database = _counter.database();
295  const auto& node2cols = _counter.nodeId2Columns();
296  if (node2cols.empty()) {
297  if (database.domainSize(target_node) != vars[0]->domainSize()) {
298  GUM_ERROR(SizeError,
299  "Variable "
300  << vars[0]->name() << "of the potential to be filled "
301  << "has a domain size of " << vars[0]->domainSize()
302  << ", which is different from that of node " << target_node
303  << " which is equal to "
304  << database.domainSize(target_node));
305  }
306  for (std::size_t i = 1; i < vars.size(); ++i) {
307  if (database.domainSize(conditioning_nodes[i - 1])
308  != vars[i]->domainSize()) {
309  GUM_ERROR(SizeError,
310  "Variable "
311  << vars[i]->name() << "of the potential to be filled "
312  << "has a domain size of " << vars[i]->domainSize()
313  << ", which is different from that of node "
314  << conditioning_nodes[i - 1] << " which is equal to "
315  << database.domainSize(conditioning_nodes[i - 1]));
316  }
317  }
318  } else {
319  std::size_t col = node2cols.second(target_node);
320  if (database.domainSize(col) != vars[0]->domainSize()) {
321  GUM_ERROR(SizeError,
322  "Variable "
323  << vars[0]->name() << "of the potential to be filled "
324  << "has a domain size of " << vars[0]->domainSize()
325  << ", which is different from that of node " << target_node
326  << " which is equal to " << database.domainSize(col));
327  }
328  for (std::size_t i = 1; i < vars.size(); ++i) {
329  col = node2cols.second(conditioning_nodes[i - 1]);
330  if (database.domainSize(col) != vars[i]->domainSize()) {
331  GUM_ERROR(SizeError,
332  "Variable "
333  << vars[i]->name() << "of the potential to be filled "
334  << "has a domain size of " << vars[i]->domainSize()
335  << ", which is different from that of node "
336  << conditioning_nodes[i - 1] << " which is equal to "
337  << database.domainSize(col));
338  }
339  }
340  }
341  }
342 
343 
345  template < template < typename > class ALLOC >
346  template < typename GUM_SCALAR >
347  INLINE typename std::enable_if< !std::is_same< GUM_SCALAR, double >::value,
348  void >::type
349  ParamEstimator< ALLOC >::__setParameters(
350  const NodeId target_node,
351  const std::vector< NodeId, ALLOC< NodeId > >& conditioning_nodes,
352  Potential< GUM_SCALAR >& pot) {
353  __checkParameters(target_node, conditioning_nodes, pot);
354 
355  const std::vector< double, ALLOC< double > > params(
356  parameters(target_node, conditioning_nodes));
357 
358  // transform the vector of double into a vector of GUM_SCALAR
359  const std::size_t size = params.size();
360  std::vector< GUM_SCALAR, ALLOC< GUM_SCALAR > > xparams(size);
361  for (std::size_t i = std::size_t(0); i < size; ++i)
362  xparams[i] = GUM_SCALAR(params[i]);
363 
364  pot.fillWith(xparams);
365  }
366 
367 
369  template < template < typename > class ALLOC >
370  template < typename GUM_SCALAR >
371  INLINE typename std::enable_if< std::is_same< GUM_SCALAR, double >::value,
372  void >::type
373  ParamEstimator< ALLOC >::__setParameters(
374  const NodeId target_node,
375  const std::vector< NodeId, ALLOC< NodeId > >& conditioning_nodes,
376  Potential< GUM_SCALAR >& pot) {
377  __checkParameters(target_node, conditioning_nodes, pot);
378 
379  const std::vector< double, ALLOC< double > > params(
380  parameters(target_node, conditioning_nodes));
381  pot.fillWith(params);
382  }
383 
384 
386  template < template < typename > class ALLOC >
387  template < typename GUM_SCALAR >
389  const NodeId target_node,
390  const std::vector< NodeId, ALLOC< NodeId > >& conditioning_nodes,
391  Potential< GUM_SCALAR >& pot) {
392  __setParameters(target_node, conditioning_nodes, pot);
393  }
394 
395 
397  template < template < typename > class ALLOC >
398  INLINE const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
400  return _counter.nodeId2Columns();
401  }
402 
403 
405  template < template < typename > class ALLOC >
406  INLINE const DatabaseTable< ALLOC >&
408  return _counter.database();
409  }
410 
411 
413  template < template < typename > class ALLOC >
414  template < typename GUM_SCALAR >
415  INLINE void
416  ParamEstimator< ALLOC >::setBayesNet(const BayesNet< GUM_SCALAR >& new_bn) {
417  _counter.setBayesNet(new_bn);
418  }
419 
420 
421  } /* namespace learning */
422 
423 } /* namespace gum */
424 
425 #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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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:98
RecordCounter< ALLOC > _counter
the record counter used to parse the database
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
const std::vector< NodeId, ALLOC< NodeId > > _empty_nodevect
an empty vector of nodes, used for empty conditioning