aGrUM  0.16.0
aprioriDirichletFromDatabase_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 
34 
36  template < template < typename > class ALLOC >
38  const DatabaseTable< ALLOC >& learning_db,
39  const DBRowGeneratorParser< ALLOC >& apriori_parser,
40  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
41  nodeId2columns,
43  alloc) :
44  Apriori< ALLOC >(apriori_parser.database(),
45  Bijection< NodeId, std::size_t, ALLOC< std::size_t > >(),
46  alloc),
47  __counter(
48  apriori_parser,
49  std::vector< std::pair< std::size_t, std::size_t >,
50  ALLOC< std::pair< std::size_t, std::size_t > > >(alloc),
51  nodeId2columns,
52  alloc) {
53  // we check that the variables in the learning database also exist in the
54  // apriori database and that they are precisely equal.
55  const DatabaseTable< ALLOC >& apriori_db = apriori_parser.database();
56  const auto& apriori_names = apriori_db.variableNames();
57  const std::size_t apriori_size = apriori_names.size();
58  HashTable< std::string, std::size_t > names2col(apriori_size);
59  for (std::size_t i = std::size_t(0); i < apriori_size; ++i)
60  names2col.insert(apriori_names[i], i);
61 
62  const auto& learning_names = learning_db.variableNames();
63  const std::size_t learning_size = learning_names.size();
64  HashTable< std::size_t, std::size_t > learning2apriori_index(learning_size);
65  bool different_index = false;
66  for (std::size_t i = std::size_t(0); i < learning_size; ++i) {
67  // get the column of the variable in the apriori database
68  std::size_t apriori_col;
69  try {
70  apriori_col = names2col[learning_names[i]];
71  } catch (...) {
72  GUM_ERROR(DatabaseError,
73  "Variable " << learning_names[i]
74  << " could not be found in the apriori database");
75  }
76 
77  // check that both variables are the same
78  const Variable& learning_var = learning_db.variable(i);
79  const Variable& apriori_var = apriori_db.variable(apriori_col);
80  if (learning_var.varType() != apriori_var.varType()) {
81  GUM_ERROR(DatabaseError,
82  "Variable "
83  << learning_names[i]
84  << " has not the same type in the learning database "
85  " and the apriori database");
86  }
87  if (learning_var.domain() != apriori_var.domain()) {
88  GUM_ERROR(DatabaseError,
89  "Variable " << learning_names[i] << " has domain "
90  << learning_var.domain()
91  << " in the learning database and domain "
92  << apriori_var.domain()
93  << " in the aprioi database");
94  }
95 
96  // save the mapping from i to col
97  learning2apriori_index.insert(i, apriori_col);
98  if (i != apriori_col) different_index = true;
99  }
100 
101  // here we are guaranteed that the variables in the learning database
102  // have their equivalent in the a priori database. Now, we should
103  // fill the bijection from ids to columns
104  if (!different_index) {
105  this->_nodeId2columns = nodeId2columns;
106  } else {
107  if (nodeId2columns.empty()) {
108  for (std::size_t i = std::size_t(0); i < learning_size; ++i) {
109  this->_nodeId2columns.insert(NodeId(i), learning2apriori_index[i]);
110  }
111  } else {
112  for (auto iter = nodeId2columns.begin(); iter != nodeId2columns.end();
113  ++iter) {
114  this->_nodeId2columns.insert(iter.first(),
115  learning2apriori_index[iter.second()]);
116  }
117  }
118  }
119 
120  // recreate the record counter with the appropriate node2col mapping
121  std::vector< std::pair< std::size_t, std::size_t >,
122  ALLOC< std::pair< std::size_t, std::size_t > > >
123  ranges(alloc);
124  RecordCounter< ALLOC > good_counter(
125  apriori_parser, ranges, this->_nodeId2columns, alloc);
126  __counter = std::move(good_counter);
127 
128  if (apriori_db.nbRows() == std::size_t(0))
129  __internal_weight = 0.0;
130  else
131  __internal_weight = this->_weight / apriori_db.nbRows();
132 
133  GUM_CONSTRUCTOR(AprioriDirichletFromDatabase);
134  }
135 
136 
138  template < template < typename > class ALLOC >
140  const AprioriDirichletFromDatabase< ALLOC >& from,
142  alloc) :
143  Apriori< ALLOC >(from, alloc),
144  __counter(from.__counter, alloc),
145  __internal_weight(from.__internal_weight) {
146  GUM_CONS_CPY(AprioriDirichletFromDatabase);
147  }
148 
149 
151  template < template < typename > class ALLOC >
153  const AprioriDirichletFromDatabase< ALLOC >& from) :
154  AprioriDirichletFromDatabase< ALLOC >(from, from.getAllocator()) {}
155 
156 
158  template < template < typename > class ALLOC >
160  AprioriDirichletFromDatabase< ALLOC >&& from,
162  alloc) :
163  Apriori< ALLOC >(std::move(from), alloc),
164  __counter(std::move(from.__counter), alloc),
165  __internal_weight(from.__internal_weight) {
166  GUM_CONS_MOV(AprioriDirichletFromDatabase);
167  }
168 
169 
171  template < template < typename > class ALLOC >
173  AprioriDirichletFromDatabase< ALLOC >&& from) :
174  AprioriDirichletFromDatabase< ALLOC >(std::move(from),
175  from.getAllocator()) {}
176 
177 
179  template < template < typename > class ALLOC >
180  AprioriDirichletFromDatabase< ALLOC >*
183  alloc) const {
184  ALLOC< AprioriDirichletFromDatabase< ALLOC > > allocator(alloc);
185  AprioriDirichletFromDatabase< ALLOC >* apriori = allocator.allocate(1);
186  try {
187  allocator.construct(apriori, *this, alloc);
188  } catch (...) {
189  allocator.deallocate(apriori, 1);
190  throw;
191  }
192 
193  return apriori;
194  }
195 
196 
198  template < template < typename > class ALLOC >
199  INLINE AprioriDirichletFromDatabase< ALLOC >*
201  return clone(this->getAllocator());
202  }
203 
204 
206  template < template < typename > class ALLOC >
208  GUM_DESTRUCTOR(AprioriDirichletFromDatabase);
209  }
210 
211 
213  template < template < typename > class ALLOC >
214  INLINE AprioriDirichletFromDatabase< ALLOC >&
216  operator=(const AprioriDirichletFromDatabase< ALLOC >& from) {
217  if (this != &from) {
219  __counter = from.__counter;
220  __internal_weight = from.__internal_weight;
221  }
222  return *this;
223  }
224 
225 
227  template < template < typename > class ALLOC >
228  INLINE AprioriDirichletFromDatabase< ALLOC >&
230  operator=(AprioriDirichletFromDatabase< ALLOC >&& from) {
231  if (this != &from) {
232  Apriori< ALLOC >::operator=(std::move(from));
233  __counter = std::move(from.__counter);
234  __internal_weight = from.__internal_weight;
235  }
236  return *this;
237  }
238 
239 
241  template < template < typename > class ALLOC >
242  INLINE bool
244  return AprioriDirichletType::isOfType(type);
245  }
246 
247 
249  template < template < typename > class ALLOC >
250  INLINE const std::string&
253  }
254 
255 
257  template < template < typename > class ALLOC >
259  return (this->_weight != 0.0);
260  }
261 
262 
264  template < template < typename > class ALLOC >
265  INLINE void
268  if (__counter.database().nbRows() == 0.0)
269  __internal_weight = 0.0;
270  else
271  __internal_weight = this->_weight / __counter.database().nbRows();
272  }
273 
274 
276  template < template < typename > class ALLOC >
278  const IdSet< ALLOC >& idset,
279  std::vector< double, ALLOC< double > >& counts) {
280  if (this->_weight == 0.0) return;
281 
282  const auto& apriori = __counter.counts(idset);
283  const std::size_t size = apriori.size();
284  if (__internal_weight != 1.0) {
285  for (std::size_t i = std::size_t(0); i < size; ++i) {
286  counts[i] += apriori[i] * __internal_weight;
287  }
288  } else {
289  for (std::size_t i = std::size_t(0); i < size; ++i) {
290  counts[i] += apriori[i];
291  }
292  }
293  }
294 
295 
297  template < template < typename > class ALLOC >
299  const IdSet< ALLOC >& idset,
300  std::vector< double, ALLOC< double > >& counts) {
301  if (__internal_weight == 0.0) return;
302 
303  const auto& apriori = __counter.counts(idset.conditionalIdSet());
304  const std::size_t size = apriori.size();
305  if (__internal_weight != 1.0) {
306  for (std::size_t i = std::size_t(0); i < size; ++i) {
307  counts[i] += apriori[i] * __internal_weight;
308  }
309  } else {
310  for (std::size_t i = std::size_t(0); i < size; ++i) {
311  counts[i] += apriori[i];
312  }
313  }
314  }
315 
316 
317  } /* namespace learning */
318 
319 } /* namespace gum */
320 
321 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
virtual void setWeight(const double weight)
sets the weight of the a priori (kind of effective sample size)
virtual bool isOfType(const std::string &type) final
indicates whether an apriori is of a certain type
virtual AprioriDirichletFromDatabase< ALLOC > * clone() const
virtual copy constructor
STL namespace.
AprioriDirichletType type
the type of the a priori
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
virtual bool isInformative() const final
indicates whether the apriori is potentially informative
virtual void setWeight(const double weight) final
sets the weight of the a priori (kind of effective sample size)
static bool isOfType(const std::string &t)
Definition: aprioriTypes.h:39
double weight() const
returns the weight assigned to the apriori
virtual void addConditioningApriori(const IdSet< ALLOC > &idset, std::vector< double, ALLOC< double > > &counts) final
adds the apriori to a counting vectordefined over the right hand side of the idset ...
virtual ~AprioriDirichletFromDatabase()
destructor
double _weight
the weight of the apriori
Definition: apriori.h:143
Apriori< ALLOC > & operator=(const Apriori< ALLOC > &from)
copy operator
AprioriDirichletFromDatabase(const DatabaseTable< ALLOC > &learning_db, const DBRowGeneratorParser< ALLOC > &apriori_parser, 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 internal apriori
virtual const std::string & getType() const final
returns the type of the apriori
Bijection< NodeId, std::size_t, ALLOC< std::size_t > > _nodeId2columns
a mapping from the NodeIds of the variables to the indices of the columns in the database ...
Definition: apriori.h:150
static const std::string type
Definition: aprioriTypes.h:38
virtual void addAllApriori(const IdSet< ALLOC > &idset, std::vector< double, ALLOC< double > > &counts) final
adds the apriori to a counting vector corresponding to the idset
Size NodeId
Type for node ids.
Definition: graphElements.h:98
Apriori(const DatabaseTable< ALLOC > &database, 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
ALLOC< NodeId > allocator_type
type for the allocators passed in arguments of methods
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
AprioriDirichletFromDatabase< ALLOC > & operator=(const AprioriDirichletFromDatabase< ALLOC > &from)
copy operator