aGrUM  0.16.0
independenceTest_tpl.h
Go to the documentation of this file.
1 
28 #ifndef DOXYGEN_SHOULD_SKIP_THIS
29 
30 namespace gum {
31 
32  namespace learning {
33 
35  template < template < typename > class ALLOC >
38  return _counter.getAllocator();
39  }
40 
41 
43  template < template < typename > class ALLOC >
45  const DBRowGeneratorParser< ALLOC >& parser,
46  const Apriori< ALLOC >& apriori,
47  const std::vector< std::pair< std::size_t, std::size_t >,
48  ALLOC< std::pair< std::size_t, std::size_t > > >& ranges,
49  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
50  nodeId2columns,
51  const typename IndependenceTest< ALLOC >::allocator_type& alloc) :
52  _apriori(apriori.clone(alloc)),
53  _counter(parser, ranges, nodeId2columns, alloc), _cache(alloc) {
54  GUM_CONSTRUCTOR(IndependenceTest);
55  }
56 
57 
59  template < template < typename > class ALLOC >
61  const DBRowGeneratorParser< ALLOC >& parser,
62  const Apriori< ALLOC >& apriori,
63  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
64  nodeId2columns,
65  const typename IndependenceTest< ALLOC >::allocator_type& alloc) :
66  _apriori(apriori.clone(alloc)),
67  _counter(parser, nodeId2columns, alloc), _cache(alloc) {
68  GUM_CONSTRUCTOR(IndependenceTest);
69  }
70 
71 
73  template < template < typename > class ALLOC >
75  const IndependenceTest< ALLOC >& from,
76  const typename IndependenceTest< ALLOC >::allocator_type& alloc) :
77  _apriori(from._apriori->clone(alloc)),
78  _counter(from._counter, alloc), _cache(from._cache, alloc),
79  _use_cache(from._use_cache) {
80  GUM_CONS_CPY(IndependenceTest);
81  }
82 
83 
85  template < template < typename > class ALLOC >
87  const IndependenceTest< ALLOC >& from) :
88  IndependenceTest(from, from.getAllocator()) {}
89 
90 
92  template < template < typename > class ALLOC >
94  IndependenceTest< ALLOC >&& from,
95  const typename IndependenceTest< ALLOC >::allocator_type& alloc) :
96  _apriori(from._apriori),
97  _counter(std::move(from._counter), alloc),
98  _cache(std::move(from._cache), alloc), _use_cache(from._use_cache) {
99  from._apriori = nullptr;
100  GUM_CONS_MOV(IndependenceTest);
101  }
102 
103 
105  template < template < typename > class ALLOC >
107  IndependenceTest< ALLOC >&& from) :
108  IndependenceTest(std::move(from), from.getAllocator()) {}
109 
110 
112  template < template < typename > class ALLOC >
114  if (_apriori != nullptr) {
115  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
116  allocator.destroy(_apriori);
117  allocator.deallocate(_apriori, 1);
118  }
119  GUM_DESTRUCTOR(IndependenceTest);
120  }
121 
122 
124  template < template < typename > class ALLOC >
125  IndependenceTest< ALLOC >& IndependenceTest< ALLOC >::
126  operator=(const IndependenceTest< ALLOC >& from) {
127  if (this != &from) {
128  Apriori< ALLOC >* new_apriori = from._apriori->clone();
129  RecordCounter< ALLOC > new_counter = from._counter;
130  ScoringCache< ALLOC > new_cache = from._cache;
131 
132  if (_apriori != nullptr) {
133  ALLOC< Apriori< ALLOC > > allocator(this->getAllocator());
134  allocator.destroy(_apriori);
135  allocator.deallocate(_apriori, 1);
136  }
137 
138  _apriori = new_apriori;
139  _counter = std::move(new_counter);
140  _cache = std::move(new_cache);
141 
142  _use_cache = from._use_cache;
143  }
144  return *this;
145  }
146 
147 
149  template < template < typename > class ALLOC >
150  IndependenceTest< ALLOC >& IndependenceTest< ALLOC >::
151  operator=(IndependenceTest< ALLOC >&& from) {
152  if (this != &from) {
153  std::swap(_apriori, from._apriori);
154 
155  _counter = std::move(from._counter);
156  _cache = std::move(from._cache);
157  _use_cache = from._use_cache;
158  }
159  return *this;
160  }
161 
162 
164  template < template < typename > class ALLOC >
165  INLINE void IndependenceTest< ALLOC >::setMaxNbThreads(std::size_t nb) const {
166  _counter.setMaxNbThreads(nb);
167  }
168 
169 
171  template < template < typename > class ALLOC >
172  INLINE std::size_t IndependenceTest< ALLOC >::nbThreads() const {
173  return _counter.nbThreads();
174  }
175 
176 
179  template < template < typename > class ALLOC >
181  const std::size_t nb) const {
182  _counter.setMinNbRowsPerThread(nb);
183  }
184 
185 
187  template < template < typename > class ALLOC >
188  INLINE std::size_t IndependenceTest< ALLOC >::minNbRowsPerThread() const {
189  return _counter.minNbRowsPerThread();
190  }
191 
192 
194 
200  template < template < typename > class ALLOC >
201  template < template < typename > class XALLOC >
203  const std::vector< std::pair< std::size_t, std::size_t >,
204  XALLOC< std::pair< std::size_t, std::size_t > > >&
205  new_ranges) {
206  std::vector< std::pair< std::size_t, std::size_t >,
207  ALLOC< std::pair< std::size_t, std::size_t > > >
208  old_ranges = ranges();
209  _counter.setRanges(new_ranges);
210  if (old_ranges != ranges()) clear();
211  }
212 
213 
215  template < template < typename > class ALLOC >
217  std::vector< std::pair< std::size_t, std::size_t >,
218  ALLOC< std::pair< std::size_t, std::size_t > > >
219  old_ranges = ranges();
220  _counter.clearRanges();
221  if (old_ranges != ranges()) clear();
222  }
223 
224 
226  template < template < typename > class ALLOC >
227  INLINE const std::vector< std::pair< std::size_t, std::size_t >,
228  ALLOC< std::pair< std::size_t, std::size_t > > >&
230  return _counter.ranges();
231  }
232 
233 
235  template < template < typename > class ALLOC >
236  INLINE double IndependenceTest< ALLOC >::score(const NodeId var1,
237  const NodeId var2) {
238  IdSet< ALLOC > idset(
239  var1, var2, _empty_ids, false, true, this->getAllocator());
240  if (_use_cache) {
241  try {
242  return _cache.score(idset);
243  } catch (NotFound&) {}
244  double the_score = _score(idset);
245  _cache.insert(std::move(idset), the_score);
246  return the_score;
247  } else {
248  return _score(std::move(idset));
249  }
250  }
251 
252 
254  template < template < typename > class ALLOC >
255  INLINE double IndependenceTest< ALLOC >::score(
256  const NodeId var1,
257  const NodeId var2,
258  const std::vector< NodeId, ALLOC< NodeId > >& rhs_ids) {
259  IdSet< ALLOC > idset(
260  var1, var2, rhs_ids, false, false, this->getAllocator());
261  if (_use_cache) {
262  try {
263  return _cache.score(idset);
264  } catch (NotFound&) {}
265  double the_score = _score(idset);
266  _cache.insert(std::move(idset), the_score);
267  return the_score;
268  } else {
269  return _score(idset);
270  }
271  }
272 
273 
275  template < template < typename > class ALLOC >
276  INLINE void IndependenceTest< ALLOC >::clear() {
277  _counter.clear();
278  _cache.clear();
279  }
280 
281 
283  template < template < typename > class ALLOC >
285  _cache.clear();
286  }
287 
288 
290  template < template < typename > class ALLOC >
291  INLINE void IndependenceTest< ALLOC >::useCache(const bool on_off) {
292  _use_cache = on_off;
293  }
294 
295 
297  template < template < typename > class ALLOC >
298  INLINE const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
300  return _counter.nodeId2Columns();
301  }
302 
303 
305  template < template < typename > class ALLOC >
306  INLINE const DatabaseTable< ALLOC >&
308  return _counter.database();
309  }
310 
311 
313 
318  template < template < typename > class ALLOC >
319  std::vector< double, ALLOC< double > > IndependenceTest< ALLOC >::_marginalize(
320  const std::size_t node_2_marginalize,
321  const std::size_t X_size,
322  const std::size_t Y_size,
323  const std::size_t Z_size,
324  const std::vector< double, ALLOC< double > >& N_xyz) const {
325  // determine the size of the output vector
326  std::size_t out_size = Z_size;
327  if (node_2_marginalize == std::size_t(0))
328  out_size *= Y_size;
329  else if (node_2_marginalize == std::size_t(1))
330  out_size *= X_size;
331 
332  // allocate the output vector
333  std::vector< double, ALLOC< double > > res(out_size, 0.0);
334 
335  // fill the vector:
336  if (node_2_marginalize == std::size_t(0)) { // marginalize X
337  for (std::size_t yz = std::size_t(0), xyz = std::size_t(0); yz < out_size;
338  ++yz) {
339  for (std::size_t x = std::size_t(0); x < X_size; ++x, ++xyz) {
340  res[yz] += N_xyz[xyz];
341  }
342  }
343  } else if (node_2_marginalize == std::size_t(1)) { // marginalize Y
344  for (std::size_t z = std::size_t(0),
345  xyz = std::size_t(0),
346  beg_xz = std::size_t(0);
347  z < Z_size;
348  ++z, beg_xz += X_size) {
349  for (std::size_t y = std::size_t(0); y < Y_size; ++y) {
350  for (std::size_t x = std::size_t(0), xz = beg_xz; x < X_size;
351  ++x, ++xz, ++xyz) {
352  res[xz] += N_xyz[xyz];
353  }
354  }
355  }
356  } else if (node_2_marginalize == std::size_t(2)) { // marginalize X and Y
357  const std::size_t XY_size = X_size * Y_size;
358  for (std::size_t z = std::size_t(0), xyz = std::size_t(0); z < out_size;
359  ++z) {
360  for (std::size_t xy = std::size_t(0); xy < XY_size; ++xy, ++xyz) {
361  res[z] += N_xyz[xyz];
362  }
363  }
364  } else {
365  GUM_ERROR(NotImplementedYet,
366  "_marginalize not implemented for nodeset "
367  << node_2_marginalize);
368  }
369 
370  return res;
371  }
372 
373  } /* namespace learning */
374 
375 } /* namespace gum */
376 
377 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
ScoringCache< ALLOC > _cache
the scoring cache
std::vector< double, ALLOC< double > > _marginalize(const std::size_t node_2_marginalize, const std::size_t X_size, const std::size_t Y_size, const std::size_t Z_size, const std::vector< double, ALLOC< double > > &N_xyz) const
returns a counting vector where variables are marginalized from N_xyz
ALLOC< NodeId > allocator_type
type for the allocators passed in arguments of methods
RecordCounter< ALLOC > _counter
the record counter used for the countings over discrete variables
virtual std::size_t minNbRowsPerThread() const
returns the minimum of rows that each thread should process
STL namespace.
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 swap(HashTable< LpCol, double > *&a, HashTable< LpCol, double > *&b)
Swap the addresses of two pointers to hashTables.
virtual void clearCache()
clears the current cache
const DatabaseTable< ALLOC > & database() const
return the database used by the score
const Bijection< NodeId, std::size_t, ALLOC< std::size_t > > & nodeId2Columns() const
return the mapping between the columns of the database and the node ids
virtual void setMinNbRowsPerThread(const std::size_t nb) const
changes the number min of rows a thread should process in a multithreading context ...
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
virtual double _score(const IdSet< ALLOC > &idset)=0
returns the score for a given IdSet
const std::vector< NodeId, ALLOC< NodeId > > _empty_ids
an empty vector
IndependenceTest(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
allocator_type getAllocator() const
returns the allocator used by the score
void clearRanges()
reset the ranges to the one range corresponding to the whole database
virtual IndependenceTest< ALLOC > * clone() const =0
virtual copy constructor
virtual void setMaxNbThreads(std::size_t nb) const
changes the max number of threads used to parse the database
IndependenceTest< ALLOC > & operator=(const IndependenceTest< ALLOC > &from)
copy operator
double score(const NodeId var1, const NodeId var2)
returns the score of a pair of nodes
virtual ~IndependenceTest()
destructor
bool _use_cache
a Boolean indicating whether we wish to use the cache
virtual void useCache(const bool on_off)
turn on/off the use of a cache of the previously computed score
virtual std::size_t nbThreads() const
returns the number of threads used to parse the database
Size NodeId
Type for node ids.
Definition: graphElements.h:98
virtual void clear()
clears all the data structures from memory, including the cache
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
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 independence test
Apriori< ALLOC > * _apriori
the expert knowledge a priori we add to the contongency tables