aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
kNML_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief The class for the NML penalty used in 3off2
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
31 namespace gum {
32 
33  namespace learning {
34 
35  /// default constructor
36  template < template < typename > class ALLOC >
37  INLINE KNML< ALLOC >::KNML(
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 > >&
44  const typename KNML< ALLOC >::allocator_type& alloc) :
48  }
49 
50 
51  /// default constructor
52  template < template < typename > class ALLOC >
53  INLINE KNML< ALLOC >::KNML(
55  const Apriori< ALLOC >& apriori,
56  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
58  const typename KNML< ALLOC >::allocator_type& alloc) :
62  }
63 
64 
65  /// copy constructor with a given allocator
66  template < template < typename > class ALLOC >
67  INLINE
68  KNML< ALLOC >::KNML(const KNML< ALLOC >& from,
69  const typename KNML< ALLOC >::allocator_type& alloc) :
73  }
74 
75 
76  /// copy constructor
77  template < template < typename > class ALLOC >
78  INLINE KNML< ALLOC >::KNML(const KNML< ALLOC >& from) :
79  KNML< ALLOC >(from, from.getAllocator()) {}
80 
81 
82  /// move constructor with a given allocator
83  template < template < typename > class ALLOC >
84  INLINE
85  KNML< ALLOC >::KNML(KNML< ALLOC >&& from,
86  const typename KNML< ALLOC >::allocator_type& alloc) :
90  }
91 
92 
93  /// move constructor
94  template < template < typename > class ALLOC >
95  INLINE KNML< ALLOC >::KNML(KNML< ALLOC >&& from) :
96  KNML< ALLOC >(std::move(from), from.getAllocator()) {}
97 
98 
99  /// virtual copy constructor with a given allocator
100  template < template < typename > class ALLOC >
101  KNML< ALLOC >* KNML< ALLOC >::clone(
102  const typename KNML< ALLOC >::allocator_type& alloc) const {
103  ALLOC< KNML< ALLOC > > allocator(alloc);
105  try {
107  } catch (...) {
109  throw;
110  }
111 
112  return new_score;
113  }
114 
115 
116  /// virtual copy constructor
117  template < template < typename > class ALLOC >
118  KNML< ALLOC >* KNML< ALLOC >::clone() const {
119  return clone(this->getAllocator());
120  }
121 
122 
123  /// destructor
124  template < template < typename > class ALLOC >
125  KNML< ALLOC >::~KNML() {
127  }
128 
129 
130  /// copy operator
131  template < template < typename > class ALLOC >
132  KNML< ALLOC >& KNML< ALLOC >::operator=(const KNML< ALLOC >& from) {
133  if (this != &from) {
136  }
137  return *this;
138  }
139 
140 
141  /// move operator
142  template < template < typename > class ALLOC >
143  KNML< ALLOC >& KNML< ALLOC >::operator=(KNML< ALLOC >&& from) {
144  if (this != &from) {
147  }
148  return *this;
149  }
150 
151 
152  /// clears all the data structures from memory, including the cache
153  template < template < typename > class ALLOC >
154  void KNML< ALLOC >::clear() {
157  }
158 
159 
160  /// clears the current cache
161  template < template < typename > class ALLOC >
162  void KNML< ALLOC >::clearCache() {
165  }
166 
167 
168  /// turn on/off the use of a cache of the previously computed score
169  template < template < typename > class ALLOC >
170  void KNML< ALLOC >::useCache(const bool on_off) {
173  }
174 
175 
176  /// returns the score corresponding to a given nodeset
177  template < template < typename > class ALLOC >
178  double KNML< ALLOC >::score_(const IdCondSet< ALLOC >& idset) {
179  // perform the countings on the database for all the nodes in the idset
180  // This will help optimizing the computations of the Nxui, Nyui and Nui
181  // that we will be needed subsequently
182  this->counter_.counts(idset, true);
183 
185 
186  // get the domain sizes of X and Y
187  const auto& db = this->database();
188  const auto& node2cols = this->nodeId2Columns();
189  std::size_t r_x, r_y;
190  if (!node2cols.empty()) {
193  } else {
194  r_x = db.domainSize(idset[0]);
195  r_y = db.domainSize(idset[1]);
196  }
197 
198 
199  // here, we distinguish idsets with conditioning nodes from those
200  // without conditioning nodes
201  if (idset.hasConditioningSet()) {
202  // now get the Nxui, Nyui and Nui
204  idset_xui.erase(idset[1]);
206  idset_yui.erase(idset[0]);
207 
208  std::vector< double, ALLOC< double > > N_ui
209  = this->counter_.counts(idset.conditionalIdCondSet(), false);
210  std::vector< double, ALLOC< double > > N_xui
211  = this->counter_.counts(idset_xui, false);
212  std::vector< double, ALLOC< double > > N_yui
213  = this->counter_.counts(idset_yui, false);
214 
219  }
220 
221 
222  // the value of kNML is equal to:
223  // 0.5 * sum_Z ( sum_X( log( C^(r_y)_#ZX ) ) - log( C^(r_y)_#Z ) +
224  // sum_Y( log( C^(r_x)_#ZY ) ) - log( C^(r_x)_#Z ) )
225  double score = 0.0;
226  for (auto n_xui: N_xui)
228  for (auto n_yui: N_yui)
230  for (auto n_ui: N_ui) {
233  }
234 
235  score *= 0.5;
236 
237  return score;
238  } else {
239  // here, there is no conditioning set
240  // now get the Nxui, Nyui and Nui
241  IdCondSet< ALLOC > idset_xui(idset[0], this->empty_ids_, true);
242  IdCondSet< ALLOC > idset_yui(idset[1], this->empty_ids_, true);
243 
244  std::vector< double, ALLOC< double > > N_xui
245  = this->counter_.counts(idset_xui, false);
246  std::vector< double, ALLOC< double > > N_yui
247  = this->counter_.counts(idset_yui, false);
248 
252  }
253 
254 
255  // so, the formula for kNML is:
256  // 0.5 * ( sum_X( log( C^(r_y)_#X ) ) - log( C^(r_y)N_ ) +
257  // sum_Y( log( C^(r_x)_#Y ) ) - log( C^(r_x)N_ ) )
258  double N = 0.0;
259  double score = 0.0;
260  for (auto n_xui: N_xui) {
262  N += n_xui;
263  }
264  for (auto n_yui: N_yui)
268 
269  score *= 0.5;
270 
271  return score;
272  }
273  }
274 
275  } /* namespace learning */
276 
277 } /* namespace gum */
278 
279 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
Database(const std::string &filename, const BayesNet< GUM_SCALAR > &bn, const std::vector< std::string > &missing_symbols)