aGrUM  0.14.2
scoreLog2Likelihood_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 
29 # include <sstream>
30 
31 namespace gum {
32 
33  namespace learning {
34 
36  template < template < typename > class ALLOC >
38  const DBRowGeneratorParser< ALLOC >& parser,
39  const Apriori< ALLOC >& apriori,
40  const std::vector< std::pair< std::size_t, std::size_t >,
41  ALLOC< std::pair< std::size_t, std::size_t > > >& ranges,
42  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
43  nodeId2columns,
44  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) :
45  Score< ALLOC >(parser, apriori, ranges, nodeId2columns, alloc),
46  __internal_apriori(parser.database(), nodeId2columns) {
47  GUM_CONSTRUCTOR(ScoreLog2Likelihood);
48  }
49 
50 
52  template < template < typename > class ALLOC >
54  const DBRowGeneratorParser< ALLOC >& parser,
55  const Apriori< ALLOC >& apriori,
56  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
57  nodeId2columns,
58  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) :
59  Score< ALLOC >(parser, apriori, nodeId2columns, alloc),
60  __internal_apriori(parser.database(), nodeId2columns) {
61  GUM_CONSTRUCTOR(ScoreLog2Likelihood);
62  }
63 
64 
66  template < template < typename > class ALLOC >
68  const ScoreLog2Likelihood< ALLOC >& from,
69  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) :
70  Score< ALLOC >(from, alloc),
71  __internal_apriori(from.__internal_apriori, alloc) {
72  GUM_CONS_CPY(ScoreLog2Likelihood);
73  }
74 
75 
77  template < template < typename > class ALLOC >
79  const ScoreLog2Likelihood< ALLOC >& from) :
80  ScoreLog2Likelihood< ALLOC >(from, from.getAllocator()) {}
81 
82 
84  template < template < typename > class ALLOC >
86  ScoreLog2Likelihood< ALLOC >&& from,
87  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) :
88  Score< ALLOC >(std::move(from), alloc),
89  __internal_apriori(std::move(from.__internal_apriori), alloc) {
90  GUM_CONS_MOV(ScoreLog2Likelihood);
91  }
92 
93 
95  template < template < typename > class ALLOC >
97  ScoreLog2Likelihood< ALLOC >&& from) :
98  ScoreLog2Likelihood< ALLOC >(std::move(from), from.getAllocator()) {}
99 
100 
102  template < template < typename > class ALLOC >
103  ScoreLog2Likelihood< ALLOC >* ScoreLog2Likelihood< ALLOC >::clone(
104  const typename ScoreLog2Likelihood< ALLOC >::allocator_type& alloc) const {
105  ALLOC< ScoreLog2Likelihood< ALLOC > > allocator(alloc);
106  ScoreLog2Likelihood< ALLOC >* new_score = allocator.allocate(1);
107  try {
108  allocator.construct(new_score, *this, alloc);
109  } catch (...) {
110  allocator.deallocate(new_score, 1);
111  throw;
112  }
113 
114  return new_score;
115  }
116 
117 
119  template < template < typename > class ALLOC >
120  ScoreLog2Likelihood< ALLOC >* ScoreLog2Likelihood< ALLOC >::clone() const {
121  return clone(this->getAllocator());
122  }
123 
124 
126  template < template < typename > class ALLOC >
128  GUM_DESTRUCTOR(ScoreLog2Likelihood);
129  }
130 
131 
133  template < template < typename > class ALLOC >
134  ScoreLog2Likelihood< ALLOC >& ScoreLog2Likelihood< ALLOC >::
135  operator=(const ScoreLog2Likelihood< ALLOC >& from) {
136  if (this != &from) {
138  __internal_apriori = from.__internal_apriori;
139  }
140  return *this;
141  }
142 
143 
145  template < template < typename > class ALLOC >
146  ScoreLog2Likelihood< ALLOC >& ScoreLog2Likelihood< ALLOC >::
147  operator=(ScoreLog2Likelihood< ALLOC >&& from) {
148  if (this != &from) {
149  Score< ALLOC >::operator=(std::move(from));
150  __internal_apriori = std::move(from.__internal_apriori);
151  }
152  return *this;
153  }
154 
155 
157  template < template < typename > class ALLOC >
159  const std::string& apriori_type, double weight) {
160  // check that the apriori is compatible with the score
161  if ((apriori_type == AprioriDirichletType::type)
162  || (apriori_type == AprioriSmoothingType::type)
163  || (apriori_type == AprioriNoAprioriType::type)) {
164  return "";
165  }
166 
167  // apriori types unsupported by the type checker
168  std::stringstream msg;
169  msg << "The apriori '" << apriori_type
170  << "' is not yet supported by method isAprioriCompatible of "
171  << "Score Log2Likelihood";
172  return msg.str();
173  }
174 
175 
177  template < template < typename > class ALLOC >
179  const Apriori< ALLOC >& apriori) {
180  return isAprioriCompatible(apriori.getType(), apriori.weight());
181  }
182 
183 
185  template < template < typename > class ALLOC >
186  INLINE std::string ScoreLog2Likelihood< ALLOC >::isAprioriCompatible() const {
187  return isAprioriCompatible(*(this->_apriori));
188  }
189 
190 
192  template < template < typename > class ALLOC >
193  INLINE const Apriori< ALLOC >&
195  return __internal_apriori;
196  }
197 
198 
200  template < template < typename > class ALLOC >
201  double ScoreLog2Likelihood< ALLOC >::_score(const IdSet< ALLOC >& idset) {
202  // get the counts for all the nodes in the idset and add the apriori
203  std::vector< double, ALLOC< double > > N_ijk(
204  this->_counter.counts(idset, true));
205  const bool informative_external_apriori = this->_apriori->isInformative();
206  if (informative_external_apriori)
207  this->_apriori->addAllApriori(idset, N_ijk);
208 
209  // here, we distinguish idsets with conditioning nodes from those
210  // without conditioning nodes
211  if (idset.hasConditioningSet()) {
212  // get the counts for the conditioning nodes
213  std::vector< double, ALLOC< double > > N_ij(
214  this->_marginalize(idset[0], N_ijk));
215 
216  // compute the score: it remains to compute the log likelihood, i.e.,
217  // sum_k=1^r_i sum_j=1^q_i N_ijk log (N_ijk / N_ij), which is also
218  // equivalent to:
219  // 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
220  double score = 0.0;
221  for (const auto n_ijk : N_ijk) {
222  if (n_ijk) { score += n_ijk * std::log(n_ijk); }
223  }
224  for (const auto n_ij : N_ij) {
225  if (n_ij) { score -= n_ij * std::log(n_ij); }
226  }
227 
228  // divide by log(2), since the log likelihood uses log_2
229  score *= this->_1log2;
230 
231  return score;
232  } else {
233  // here, there are no conditioning nodes
234 
235  // compute the score: it remains to compute the log likelihood, i.e.,
236  // sum_k=1^r_i N_ijk log (N_ijk / N), which is also
237  // equivalent to:
238  // sum_j=1^q_i sum_k=1^r_i N_ijk log N_ijk - N log N
239  double N = 0.0;
240  double score = 0.0;
241  for (const auto n_ijk : N_ijk) {
242  if (n_ijk) {
243  score += n_ijk * std::log(n_ijk);
244  N += n_ijk;
245  }
246  }
247  score -= N * std::log(N);
248 
249  // divide by log(2), since the log likelihood uses log_2
250  score *= this->_1log2;
251 
252  return score;
253  }
254  }
255 
256 
258  template < template < typename > class ALLOC >
259  INLINE double
260  ScoreLog2Likelihood< ALLOC >::score(const IdSet< ALLOC >& idset) {
261  return _score(idset);
262  }
263 
264 
265  } /* namespace learning */
266 
267 } /* namespace gum */
268 
269 #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:40
the class for computing Log2-likelihood scores
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:45
STL namespace.
const double _1log2
1 / log(2)
Definition: score.h:236
virtual ~ScoreLog2Likelihood()
destructor
virtual const Apriori< ALLOC > & internalApriori() const final
returns the internal apriori of the score
gum is the global namespace for all aGrUM entities
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:239
static const std::string type
Definition: aprioriTypes.h:35
RecordCounter< ALLOC > _counter
the record counter used for the countings over discrete variables
Definition: score.h:242
virtual double _score(const IdSet< ALLOC > &idset) final
returns the score for a given IdSet
Size NodeId
Type for node ids.
Definition: graphElements.h:97