aGrUM  0.16.0
scoreLog2Likelihood_tpl.h
Go to the documentation of this file.
1 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
32 # include <sstream>
33 
34 namespace gum {
35 
36  namespace learning {
37 
39  template < template < typename > class ALLOC >
41  const DBRowGeneratorParser< ALLOC >& parser,
42  const Apriori< ALLOC >& apriori,
43  const std::vector< std::pair< std::size_t, std::size_t >,
44  ALLOC< std::pair< std::size_t, std::size_t > > >& ranges,
45  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
46  nodeId2columns,
47  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) :
48  Score< ALLOC >(parser, apriori, ranges, nodeId2columns, alloc),
49  __internal_apriori(parser.database(), nodeId2columns) {
50  GUM_CONSTRUCTOR(ScoreLog2Likelihood);
51  }
52 
53 
55  template < template < typename > class ALLOC >
57  const DBRowGeneratorParser< ALLOC >& parser,
58  const Apriori< ALLOC >& apriori,
59  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
60  nodeId2columns,
61  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) :
62  Score< ALLOC >(parser, apriori, nodeId2columns, alloc),
63  __internal_apriori(parser.database(), nodeId2columns) {
64  GUM_CONSTRUCTOR(ScoreLog2Likelihood);
65  }
66 
67 
69  template < template < typename > class ALLOC >
71  const ScoreLog2Likelihood< ALLOC >& from,
72  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) :
73  Score< ALLOC >(from, alloc),
74  __internal_apriori(from.__internal_apriori, alloc) {
75  GUM_CONS_CPY(ScoreLog2Likelihood);
76  }
77 
78 
80  template < template < typename > class ALLOC >
82  const ScoreLog2Likelihood< ALLOC >& from) :
83  ScoreLog2Likelihood< ALLOC >(from, from.getAllocator()) {}
84 
85 
87  template < template < typename > class ALLOC >
89  ScoreLog2Likelihood< ALLOC >&& from,
90  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) :
91  Score< ALLOC >(std::move(from), alloc),
92  __internal_apriori(std::move(from.__internal_apriori), alloc) {
93  GUM_CONS_MOV(ScoreLog2Likelihood);
94  }
95 
96 
98  template < template < typename > class ALLOC >
100  ScoreLog2Likelihood< ALLOC >&& from) :
101  ScoreLog2Likelihood< ALLOC >(std::move(from), from.getAllocator()) {}
102 
103 
105  template < template < typename > class ALLOC >
106  ScoreLog2Likelihood< ALLOC >* ScoreLog2Likelihood< ALLOC >::clone(
107  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) const {
108  ALLOC< ScoreLog2Likelihood< ALLOC > > allocator(alloc);
109  ScoreLog2Likelihood< ALLOC >* new_score = allocator.allocate(1);
110  try {
111  allocator.construct(new_score, *this, alloc);
112  } catch (...) {
113  allocator.deallocate(new_score, 1);
114  throw;
115  }
116 
117  return new_score;
118  }
119 
120 
122  template < template < typename > class ALLOC >
123  ScoreLog2Likelihood< ALLOC >* ScoreLog2Likelihood< ALLOC >::clone() const {
124  return clone(this->getAllocator());
125  }
126 
127 
129  template < template < typename > class ALLOC >
131  GUM_DESTRUCTOR(ScoreLog2Likelihood);
132  }
133 
134 
136  template < template < typename > class ALLOC >
137  ScoreLog2Likelihood< ALLOC >& ScoreLog2Likelihood< ALLOC >::
138  operator=(const ScoreLog2Likelihood< ALLOC >& from) {
139  if (this != &from) {
141  __internal_apriori = from.__internal_apriori;
142  }
143  return *this;
144  }
145 
146 
148  template < template < typename > class ALLOC >
149  ScoreLog2Likelihood< ALLOC >& ScoreLog2Likelihood< ALLOC >::
150  operator=(ScoreLog2Likelihood< ALLOC >&& from) {
151  if (this != &from) {
152  Score< ALLOC >::operator=(std::move(from));
153  __internal_apriori = std::move(from.__internal_apriori);
154  }
155  return *this;
156  }
157 
158 
160  template < template < typename > class ALLOC >
162  const std::string& apriori_type, double weight) {
163  // check that the apriori is compatible with the score
164  if ((apriori_type == AprioriDirichletType::type)
165  || (apriori_type == AprioriSmoothingType::type)
166  || (apriori_type == AprioriNoAprioriType::type)) {
167  return "";
168  }
169 
170  // apriori types unsupported by the type checker
171  std::stringstream msg;
172  msg << "The apriori '" << apriori_type
173  << "' is not yet supported by method isAprioriCompatible of "
174  << "Score Log2Likelihood";
175  return msg.str();
176  }
177 
178 
180  template < template < typename > class ALLOC >
182  const Apriori< ALLOC >& apriori) {
183  return isAprioriCompatible(apriori.getType(), apriori.weight());
184  }
185 
186 
188  template < template < typename > class ALLOC >
189  INLINE std::string ScoreLog2Likelihood< ALLOC >::isAprioriCompatible() const {
190  return isAprioriCompatible(*(this->_apriori));
191  }
192 
193 
195  template < template < typename > class ALLOC >
196  INLINE const Apriori< ALLOC >&
198  return __internal_apriori;
199  }
200 
201 
203  template < template < typename > class ALLOC >
204  double ScoreLog2Likelihood< ALLOC >::_score(const IdSet< ALLOC >& idset) {
205  // get the counts for all the nodes in the idset and add the apriori
206  std::vector< double, ALLOC< double > > N_ijk(
207  this->_counter.counts(idset, true));
208  const bool informative_external_apriori = this->_apriori->isInformative();
209  if (informative_external_apriori)
210  this->_apriori->addAllApriori(idset, N_ijk);
211 
212  // here, we distinguish idsets with conditioning nodes from those
213  // without conditioning nodes
214  if (idset.hasConditioningSet()) {
215  // get the counts for the conditioning nodes
216  std::vector< double, ALLOC< double > > N_ij(
217  this->_marginalize(idset[0], N_ijk));
218 
219  // compute the score: it remains to compute the log likelihood, i.e.,
220  // sum_k=1^r_i sum_j=1^q_i N_ijk log (N_ijk / N_ij), which is also
221  // equivalent to:
222  // sum_j=1^q_i sum_k=1^r_i N_ijk log N_ijk - sum_j=1^q_i N_ij log N_ij
223  double score = 0.0;
224  for (const auto n_ijk : N_ijk) {
225  if (n_ijk) { score += n_ijk * std::log(n_ijk); }
226  }
227  for (const auto n_ij : N_ij) {
228  if (n_ij) { score -= n_ij * std::log(n_ij); }
229  }
230 
231  // divide by log(2), since the log likelihood uses log_2
232  score *= this->_1log2;
233 
234  return score;
235  } else {
236  // here, there are no conditioning nodes
237 
238  // compute the score: it remains to compute the log likelihood, i.e.,
239  // sum_k=1^r_i N_ijk log (N_ijk / N), which is also
240  // equivalent to:
241  // sum_j=1^q_i sum_k=1^r_i N_ijk log N_ijk - N log N
242  double N = 0.0;
243  double score = 0.0;
244  for (const auto n_ijk : N_ijk) {
245  if (n_ijk) {
246  score += n_ijk * std::log(n_ijk);
247  N += n_ijk;
248  }
249  }
250  score -= N * std::log(N);
251 
252  // divide by log(2), since the log likelihood uses log_2
253  score *= this->_1log2;
254 
255  return score;
256  }
257  }
258 
259 
261  template < template < typename > class ALLOC >
262  INLINE double
263  ScoreLog2Likelihood< ALLOC >::score(const IdSet< ALLOC >& idset) {
264  return _score(idset);
265  }
266 
267 
268  } /* namespace learning */
269 
270 } /* namespace gum */
271 
272 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
const DatabaseTable< ALLOC > & database() const
return the database used by the score
double score(const IdSet< ALLOC > &idset)
returns the score for a given IdSet
static const std::string type
Definition: aprioriTypes.h:43
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Score(const DBRowGeneratorParser< ALLOC > &parser, const Apriori< ALLOC > &external_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
virtual ScoreLog2Likelihood< ALLOC > * clone() const
virtual copy constructor
ALLOC< NodeId > allocator_type
type for the allocators passed in arguments of methods
static const std::string type
Definition: aprioriTypes.h:48
STL namespace.
const double _1log2
1 / log(2)
Definition: score.h:239
virtual ~ScoreLog2Likelihood()
destructor
virtual const Apriori< ALLOC > & internalApriori() const final
returns the internal apriori of the score
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
std::vector< double, ALLOC< double > > _marginalize(const NodeId X_id, const std::vector< double, ALLOC< double > > &N_xyz) const
returns a counting vector where variables are marginalized from N_xyz
Score< ALLOC > & operator=(const Score< ALLOC > &from)
copy operator
ScoreLog2Likelihood< ALLOC > & operator=(const ScoreLog2Likelihood< ALLOC > &from)
copy operator
ScoreLog2Likelihood(const DBRowGeneratorParser< ALLOC > &parser, const Apriori< ALLOC > &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
allocator_type getAllocator() const
returns the allocator used by the score
virtual std::string isAprioriCompatible() const final
indicates whether the apriori is compatible (meaningful) with the score
Apriori< ALLOC > * _apriori
the expert knowledge a priori we add to the score
Definition: score.h:242
static const std::string type
Definition: aprioriTypes.h:38
RecordCounter< ALLOC > _counter
the record counter used for the countings over discrete variables
Definition: score.h:245
virtual double _score(const IdSet< ALLOC > &idset) final
returns the score for a given IdSet
Size NodeId
Type for node ids.
Definition: graphElements.h:98