aGrUM  0.16.0
scorefNML_tpl.h
Go to the documentation of this file.
1 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
32 
33 namespace gum {
34 
35  namespace learning {
36 
38  template < template < typename > class ALLOC >
40  const DBRowGeneratorParser< ALLOC >& parser,
41  const Apriori< ALLOC >& apriori,
42  const std::vector< std::pair< std::size_t, std::size_t >,
43  ALLOC< std::pair< std::size_t, std::size_t > > >& ranges,
44  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
45  nodeId2columns,
46  const typename ScorefNML< ALLOC >::allocator_type& alloc) :
47  Score< ALLOC >(parser, apriori, ranges, nodeId2columns, alloc),
48  __internal_apriori(parser.database(), nodeId2columns) {
49  GUM_CONSTRUCTOR(ScorefNML);
50  }
51 
52 
54  template < template < typename > class ALLOC >
56  const DBRowGeneratorParser< ALLOC >& parser,
57  const Apriori< ALLOC >& apriori,
58  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
59  nodeId2columns,
60  const typename ScorefNML< ALLOC >::allocator_type& alloc) :
61  Score< ALLOC >(parser, apriori, nodeId2columns, alloc),
62  __internal_apriori(parser.database(), nodeId2columns) {
63  GUM_CONSTRUCTOR(ScorefNML);
64  }
65 
66 
68  template < template < typename > class ALLOC >
70  const ScorefNML< ALLOC >& from,
71  const typename ScorefNML< ALLOC >::allocator_type& alloc) :
72  Score< ALLOC >(from, alloc),
73  __internal_apriori(from.__internal_apriori, alloc) {
74  GUM_CONS_CPY(ScorefNML);
75  }
76 
77 
79  template < template < typename > class ALLOC >
80  INLINE ScorefNML< ALLOC >::ScorefNML(const ScorefNML< ALLOC >& from) :
81  ScorefNML< ALLOC >(from, from.getAllocator()) {}
82 
83 
85  template < template < typename > class ALLOC >
87  ScorefNML< ALLOC >&& from,
88  const typename ScorefNML< ALLOC >::allocator_type& alloc) :
89  Score< ALLOC >(std::move(from), alloc),
90  __internal_apriori(std::move(from.__internal_apriori), alloc) {
91  GUM_CONS_MOV(ScorefNML);
92  }
93 
94 
96  template < template < typename > class ALLOC >
97  INLINE ScorefNML< ALLOC >::ScorefNML(ScorefNML< ALLOC >&& from) :
98  ScorefNML< ALLOC >(std::move(from), from.getAllocator()) {}
99 
100 
102  template < template < typename > class ALLOC >
103  ScorefNML< ALLOC >* ScorefNML< ALLOC >::clone(
104  const typename ScorefNML< ALLOC >::allocator_type& alloc) const {
105  ALLOC< ScorefNML< ALLOC > > allocator(alloc);
106  ScorefNML< 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  ScorefNML< ALLOC >* ScorefNML< ALLOC >::clone() const {
121  return clone(this->getAllocator());
122  }
123 
124 
126  template < template < typename > class ALLOC >
128  GUM_DESTRUCTOR(ScorefNML);
129  }
130 
131 
133  template < template < typename > class ALLOC >
134  ScorefNML< ALLOC >& ScorefNML< ALLOC >::
135  operator=(const ScorefNML< 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  ScorefNML< ALLOC >& ScorefNML< ALLOC >::operator=(ScorefNML< ALLOC >&& from) {
147  if (this != &from) {
148  Score< ALLOC >::operator=(std::move(from));
149  __internal_apriori = std::move(from.__internal_apriori);
150  }
151  return *this;
152  }
153 
154 
156  template < template < typename > class ALLOC >
157  std::string
158  ScorefNML< ALLOC >::isAprioriCompatible(const std::string& apriori_type,
159  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 os Score fNML";
171  return msg.str();
172  }
173 
174 
176  template < template < typename > class ALLOC >
177  INLINE std::string
178  ScorefNML< ALLOC >::isAprioriCompatible(const Apriori< ALLOC >& apriori) {
179  return isAprioriCompatible(apriori.getType(), apriori.weight());
180  }
181 
182 
184  template < template < typename > class ALLOC >
185  INLINE std::string ScorefNML< ALLOC >::isAprioriCompatible() const {
186  return isAprioriCompatible(*(this->_apriori));
187  }
188 
189 
191  template < template < typename > class ALLOC >
192  INLINE const Apriori< ALLOC >& ScorefNML< ALLOC >::internalApriori() const {
193  return __internal_apriori;
194  }
195 
196 
198  template < template < typename > class ALLOC >
199  double ScorefNML< ALLOC >::_score(const IdSet< ALLOC >& idset) {
200  // get the counts for all the nodes in the idset and add the apriori
201  std::vector< double, ALLOC< double > > N_ijk(
202  this->_counter.counts(idset, true));
203  const bool informative_external_apriori = this->_apriori->isInformative();
204  if (informative_external_apriori)
205  this->_apriori->addAllApriori(idset, N_ijk);
206  const std::size_t all_size = N_ijk.size();
207 
208  // here, we distinguish idsets with conditioning nodes from those
209  // without conditioning nodes
210  if (idset.hasConditioningSet()) {
211  // get the counts for the conditioning nodes
212  std::vector< double, ALLOC< double > > N_ij(
213  this->_marginalize(idset[0], N_ijk));
214  const std::size_t target_domsize = all_size / N_ij.size();
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  // finally, remove the penalty
232  double penalty = 0.0;
233  for (const auto n_ij : N_ij) {
234  penalty += __ctable.log2Cnr(target_domsize, n_ij);
235  }
236 
237  score -= penalty;
238 
239  return score;
240  } else {
241  // here, there are no conditioning nodes
242 
243  // compute the score: it remains to compute the log likelihood, i.e.,
244  // sum_k=1^r_i N_ijk log (N_ijk / N), which is also
245  // equivalent to:
246  // sum_j=1^q_i sum_k=1^r_i N_ijk log N_ijk - N log N
247  double N = 0.0;
248  double score = 0.0;
249  for (const auto n_ijk : N_ijk) {
250  if (n_ijk) {
251  score += n_ijk * std::log(n_ijk);
252  N += n_ijk;
253  }
254  }
255  score -= N * std::log(N);
256 
257  // divide by log(2), since the log likelihood uses log_2
258  score *= this->_1log2;
259 
260  // finally, remove the penalty
261  score -= __ctable.log2Cnr(all_size, N);
262 
263  return score;
264  }
265  }
266 
267  } /* namespace learning */
268 
269 } /* namespace gum */
270 
271 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
const DatabaseTable< ALLOC > & database() const
return the database used by the score
double score(const NodeId var)
returns the score of a single node
virtual std::string isAprioriCompatible() const final
indicates whether the apriori is compatible (meaningful) with the score
static const std::string type
Definition: aprioriTypes.h:43
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
virtual ScorefNML< ALLOC > * clone() const
virtual copy constructor
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
static const std::string type
Definition: aprioriTypes.h:48
STL namespace.
const double _1log2
1 / log(2)
Definition: score.h:239
virtual ~ScorefNML()
destructor
virtual const Apriori< ALLOC > & internalApriori() const final
returns the internal apriori of the score
ScorefNML(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
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
ScorefNML< ALLOC > & operator=(const ScorefNML< ALLOC > &from)
copy operator
ALLOC< NodeId > allocator_type
type for the allocators passed in arguments of methods
Definition: scorefNML.h:57
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
virtual double _score(const IdSet< ALLOC > &idset) final
returns the score for a given IdSet
allocator_type getAllocator() const
returns the allocator used by 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
Size NodeId
Type for node ids.
Definition: graphElements.h:98