aGrUM  0.14.2
aprioriDirichletFromDatabase_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  ***************************************************************************/
25 #ifndef DOXYGEN_SHOULD_SKIP_THIS
26 
27 namespace gum {
28 
29  namespace learning {
30 
31 
33  template < template < typename > class ALLOC >
35  const DatabaseTable< ALLOC >& learning_db,
36  const DBRowGeneratorParser< ALLOC >& apriori_parser,
37  const Bijection< NodeId, std::size_t, ALLOC< std::size_t > >&
38  nodeId2columns,
40  alloc) :
41  Apriori< ALLOC >(apriori_parser.database(),
42  Bijection< NodeId, std::size_t, ALLOC< std::size_t > >(),
43  alloc),
44  __counter(
45  apriori_parser,
46  std::vector< std::pair< std::size_t, std::size_t >,
47  ALLOC< std::pair< std::size_t, std::size_t > > >(alloc),
48  nodeId2columns,
49  alloc) {
50  // we check that the variables in the learning database also exist in the
51  // apriori database and that they are precisely equal.
52  const DatabaseTable< ALLOC >& apriori_db = apriori_parser.database();
53  const auto& apriori_names = apriori_db.variableNames();
54  const std::size_t apriori_size = apriori_names.size();
55  HashTable< std::string, std::size_t > names2col(apriori_size);
56  for (std::size_t i = std::size_t(0); i < apriori_size; ++i)
57  names2col.insert(apriori_names[i], i);
58 
59  const auto& learning_names = learning_db.variableNames();
60  const std::size_t learning_size = learning_names.size();
61  HashTable< std::size_t, std::size_t > learning2apriori_index(learning_size);
62  bool different_index = false;
63  for (std::size_t i = std::size_t(0); i < learning_size; ++i) {
64  // get the column of the variable in the apriori database
65  std::size_t apriori_col;
66  try {
67  apriori_col = names2col[learning_names[i]];
68  } catch (...) {
69  GUM_ERROR(DatabaseError,
70  "Variable " << learning_names[i]
71  << " could not be found in the apriori database");
72  }
73 
74  // check that both variables are the same
75  const Variable& learning_var = learning_db.variable(i);
76  const Variable& apriori_var = apriori_db.variable(apriori_col);
77  if (learning_var.varType() != apriori_var.varType()) {
78  GUM_ERROR(DatabaseError,
79  "Variable "
80  << learning_names[i]
81  << " has not the same type in the learning database "
82  " and the apriori database");
83  }
84  if (learning_var.domain() != apriori_var.domain()) {
85  GUM_ERROR(DatabaseError,
86  "Variable " << learning_names[i] << " has domain "
87  << learning_var.domain()
88  << " in the learning database and domain "
89  << apriori_var.domain()
90  << " in the aprioi database");
91  }
92 
93  // save the mapping from i to col
94  learning2apriori_index.insert(i, apriori_col);
95  if (i != apriori_col) different_index = true;
96  }
97 
98  // here we are guaranteed that the variables in the learning database
99  // have their equivalent in the a priori database. Now, we should
100  // fill the bijection from ids to columns
101  if (!different_index) {
102  this->_nodeId2columns = nodeId2columns;
103  } else {
104  if (nodeId2columns.empty()) {
105  for (std::size_t i = std::size_t(0); i < learning_size; ++i) {
106  this->_nodeId2columns.insert(NodeId(i), learning2apriori_index[i]);
107  }
108  } else {
109  for (auto iter = nodeId2columns.begin(); iter != nodeId2columns.end();
110  ++iter) {
111  this->_nodeId2columns.insert(iter.first(),
112  learning2apriori_index[iter.second()]);
113  }
114  }
115  }
116 
117  // recreate the record counter with the appropriate node2col mapping
118  std::vector< std::pair< std::size_t, std::size_t >,
119  ALLOC< std::pair< std::size_t, std::size_t > > >
120  ranges(alloc);
121  RecordCounter< ALLOC > good_counter(
122  apriori_parser, ranges, this->_nodeId2columns, alloc);
123  __counter = std::move(good_counter);
124 
125  if (apriori_db.nbRows() == std::size_t(0))
126  __internal_weight = 0.0;
127  else
128  __internal_weight = this->_weight / apriori_db.nbRows();
129 
130  GUM_CONSTRUCTOR(AprioriDirichletFromDatabase);
131  }
132 
133 
135  template < template < typename > class ALLOC >
137  const AprioriDirichletFromDatabase< ALLOC >& from,
139  alloc) :
140  Apriori< ALLOC >(from, alloc),
141  __counter(from.__counter, alloc),
142  __internal_weight(from.__internal_weight) {
143  GUM_CONS_CPY(AprioriDirichletFromDatabase);
144  }
145 
146 
148  template < template < typename > class ALLOC >
150  const AprioriDirichletFromDatabase< ALLOC >& from) :
151  AprioriDirichletFromDatabase< ALLOC >(from, from.getAllocator()) {}
152 
153 
155  template < template < typename > class ALLOC >
157  AprioriDirichletFromDatabase< ALLOC >&& from,
159  alloc) :
160  Apriori< ALLOC >(std::move(from), alloc),
161  __counter(std::move(from.__counter), alloc),
162  __internal_weight(from.__internal_weight) {
163  GUM_CONS_MOV(AprioriDirichletFromDatabase);
164  }
165 
166 
168  template < template < typename > class ALLOC >
170  AprioriDirichletFromDatabase< ALLOC >&& from) :
171  AprioriDirichletFromDatabase< ALLOC >(std::move(from),
172  from.getAllocator()) {}
173 
174 
176  template < template < typename > class ALLOC >
177  AprioriDirichletFromDatabase< ALLOC >*
180  alloc) const {
181  ALLOC< AprioriDirichletFromDatabase< ALLOC > > allocator(alloc);
182  AprioriDirichletFromDatabase< ALLOC >* apriori = allocator.allocate(1);
183  try {
184  allocator.construct(apriori, *this, alloc);
185  } catch (...) {
186  allocator.deallocate(apriori, 1);
187  throw;
188  }
189 
190  return apriori;
191  }
192 
193 
195  template < template < typename > class ALLOC >
196  INLINE AprioriDirichletFromDatabase< ALLOC >*
198  return clone(this->getAllocator());
199  }
200 
201 
203  template < template < typename > class ALLOC >
205  GUM_DESTRUCTOR(AprioriDirichletFromDatabase);
206  }
207 
208 
210  template < template < typename > class ALLOC >
211  INLINE AprioriDirichletFromDatabase< ALLOC >&
213  operator=(const AprioriDirichletFromDatabase< ALLOC >& from) {
214  if (this != &from) {
216  __counter = from.__counter;
217  __internal_weight = from.__internal_weight;
218  }
219  return *this;
220  }
221 
222 
224  template < template < typename > class ALLOC >
225  INLINE AprioriDirichletFromDatabase< ALLOC >&
227  operator=(AprioriDirichletFromDatabase< ALLOC >&& from) {
228  if (this != &from) {
229  Apriori< ALLOC >::operator=(std::move(from));
230  __counter = std::move(from.__counter);
231  __internal_weight = from.__internal_weight;
232  }
233  return *this;
234  }
235 
236 
238  template < template < typename > class ALLOC >
239  INLINE bool
241  return AprioriDirichletType::isOfType(type);
242  }
243 
244 
246  template < template < typename > class ALLOC >
247  INLINE const std::string&
250  }
251 
252 
254  template < template < typename > class ALLOC >
256  return (this->_weight != 0.0);
257  }
258 
259 
261  template < template < typename > class ALLOC >
262  INLINE void
265  if (__counter.database().nbRows() == 0.0)
266  __internal_weight = 0.0;
267  else
268  __internal_weight = this->_weight / __counter.database().nbRows();
269  }
270 
271 
273  template < template < typename > class ALLOC >
275  const IdSet< ALLOC >& idset,
276  std::vector< double, ALLOC< double > >& counts) {
277  if (this->_weight == 0.0) return;
278 
279  const auto& apriori = __counter.counts(idset);
280  const std::size_t size = apriori.size();
281  if (__internal_weight != 1.0) {
282  for (std::size_t i = std::size_t(0); i < size; ++i) {
283  counts[i] += apriori[i] * __internal_weight;
284  }
285  } else {
286  for (std::size_t i = std::size_t(0); i < size; ++i) {
287  counts[i] += apriori[i];
288  }
289  }
290  }
291 
292 
294  template < template < typename > class ALLOC >
296  const IdSet< ALLOC >& idset,
297  std::vector< double, ALLOC< double > >& counts) {
298  if (__internal_weight == 0.0) return;
299 
300  const auto& apriori = __counter.counts(idset.conditionalIdSet());
301  const std::size_t size = apriori.size();
302  if (__internal_weight != 1.0) {
303  for (std::size_t i = std::size_t(0); i < size; ++i) {
304  counts[i] += apriori[i] * __internal_weight;
305  }
306  } else {
307  for (std::size_t i = std::size_t(0); i < size; ++i) {
308  counts[i] += apriori[i];
309  }
310  }
311  }
312 
313 
314  } /* namespace learning */
315 
316 } /* namespace gum */
317 
318 #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
gum is the global namespace for all aGrUM entities
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:36
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:140
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:147
static const std::string type
Definition: aprioriTypes.h:35
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:97
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:52
AprioriDirichletFromDatabase< ALLOC > & operator=(const AprioriDirichletFromDatabase< ALLOC > &from)
copy operator