aGrUM  0.21.0
a C++ library for (probabilistic) graphical models
DBTranslator4IntegerVariable_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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 /** @file
23  * @brief The databases' cell translators for integer variables
24  *
25  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 
28 #include <utility>
29 #include <vector>
30 #include <sstream>
31 
32 #include <agrum/tools/database/DBTranslator4IntegerVariable.h>
33 #include <agrum/tools/database/DBCell.h>
34 
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36 
37 namespace gum {
38 
39  namespace learning {
40 
41 
42  /// default constructor with a integer variable as translator
43  template < template < typename > class ALLOC >
44  template < template < typename > class XALLOC >
45  DBTranslator4IntegerVariable< ALLOC >::DBTranslator4IntegerVariable(
46  const IntegerVariable& var,
47  const std::vector< std::string, XALLOC< std::string > >& missing_symbols,
48  std::size_t max_dico_entries,
49  const typename DBTranslator4IntegerVariable< ALLOC >::allocator_type& alloc) :
50  DBTranslator< ALLOC >(DBTranslatedValueType::DISCRETE,
51  true,
52  missing_symbols,
53  false,
54  max_dico_entries,
55  alloc),
56  _variable_(var) {
57  // check that the variable has not too many entries
58  if (var.domainSize() > max_dico_entries) {
59  GUM_ERROR(SizeError, "the dictionary induced by the variable is too large")
60  }
61 
62  // remove all the missing symbols corresponding to a number belonging to the variable
63  for (auto iter = this->missing_symbols_.beginSafe(); iter != this->missing_symbols_.endSafe();
64  ++iter) {
65  if (DBCell::isInteger(*iter)) {
66  const int missing_val = std::stoi(*iter);
67  if (_variable_.integerDomain().exists(missing_val)) {
68  this->missing_symbols_.erase(iter);
69  }
70  }
71  }
72 
73  // add the content of the variable into the back dictionary
74  std::size_t size = 0;
75  for (const auto& label: var.labels()) {
76  // if the label corresponds to a missing value, then remove it from
77  // the set of missing symbols. If, in addition, it has already
78  // been entered into the back_dictionary, then, this has been done
79  // because the label corresponded to a missing value, so we should
80  // remove the label as well from the back_dictionary.
81  if (this->missing_symbols_.exists(label)) { this->missing_symbols_.erase(label); }
82 
83  this->back_dico_.insert(size, label);
84  ++size;
85  }
86 
87  // for debugging purposes
88  GUM_CONSTRUCTOR(DBTranslator4IntegerVariable);
89  }
90 
91 
92  /// default constructor with an integer variable as translator but no missing value
93  template < template < typename > class ALLOC >
94  DBTranslator4IntegerVariable< ALLOC >::DBTranslator4IntegerVariable(
95  const IntegerVariable& var,
96  std::size_t max_dico_entries,
97  const typename DBTranslator4IntegerVariable< ALLOC >::allocator_type& alloc) :
98  DBTranslator< ALLOC >(DBTranslatedValueType::DISCRETE,
99  true,
100  false,
101  max_dico_entries,
102  alloc),
103  _variable_(var) {
104  // check that the variable has not too many entries
105  if (var.domainSize() > max_dico_entries) {
106  GUM_ERROR(SizeError, "the dictionary induced by the variable is too large")
107  }
108 
109  // add the content of the variable into the back dictionary
110  std::size_t size = 0;
111  for (const auto& label: var.labels()) {
112  this->back_dico_.insert(size, label);
113  ++size;
114  }
115 
116  // for debugging purposes
117  GUM_CONSTRUCTOR(DBTranslator4IntegerVariable);
118  }
119 
120 
121  /// copy constructor with a given allocator
122  template < template < typename > class ALLOC >
123  DBTranslator4IntegerVariable< ALLOC >::DBTranslator4IntegerVariable(
124  const DBTranslator4IntegerVariable< ALLOC >& from,
125  const typename DBTranslator4IntegerVariable< ALLOC >::allocator_type& alloc) :
126  DBTranslator< ALLOC >(from, alloc),
127  _variable_(from._variable_) {
128  // for debugging purposes
129  GUM_CONS_CPY(DBTranslator4IntegerVariable);
130  }
131 
132 
133  /// copy constructor
134  template < template < typename > class ALLOC >
135  DBTranslator4IntegerVariable< ALLOC >::DBTranslator4IntegerVariable(
136  const DBTranslator4IntegerVariable< ALLOC >& from) :
137  DBTranslator4IntegerVariable< ALLOC >(from, from.getAllocator()) {}
138 
139 
140  /// move constructor with a given allocator
141  template < template < typename > class ALLOC >
142  DBTranslator4IntegerVariable< ALLOC >::DBTranslator4IntegerVariable(
143  DBTranslator4IntegerVariable< ALLOC >&& from,
144  const typename DBTranslator4IntegerVariable< ALLOC >::allocator_type& alloc) :
145  DBTranslator< ALLOC >(std::move(from), alloc),
146  _variable_(std::move(from._variable_)) {
147  // for debugging purposes
148  GUM_CONS_MOV(DBTranslator4IntegerVariable);
149  }
150 
151 
152  /// move constructor
153  template < template < typename > class ALLOC >
154  DBTranslator4IntegerVariable< ALLOC >::DBTranslator4IntegerVariable(
155  DBTranslator4IntegerVariable< ALLOC >&& from) :
156  DBTranslator4IntegerVariable< ALLOC >(std::move(from), from.getAllocator()) {}
157 
158 
159  /// virtual copy constructor with a given allocator
160  template < template < typename > class ALLOC >
161  DBTranslator4IntegerVariable< ALLOC >* DBTranslator4IntegerVariable< ALLOC >::clone(
162  const typename DBTranslator4IntegerVariable< ALLOC >::allocator_type& alloc) const {
163  ALLOC< DBTranslator4IntegerVariable< ALLOC > > allocator(alloc);
164  DBTranslator4IntegerVariable< ALLOC >* translator = allocator.allocate(1);
165  try {
166  allocator.construct(translator, *this, alloc);
167  } catch (...) {
168  allocator.deallocate(translator, 1);
169  throw;
170  }
171  return translator;
172  }
173 
174 
175  /// virtual copy constructor
176  template < template < typename > class ALLOC >
177  INLINE DBTranslator4IntegerVariable< ALLOC >*
178  DBTranslator4IntegerVariable< ALLOC >::clone() const {
179  return clone(this->getAllocator());
180  }
181 
182 
183  /// destructor
184  template < template < typename > class ALLOC >
185  INLINE DBTranslator4IntegerVariable< ALLOC >::~DBTranslator4IntegerVariable() {
186  // for debugging purposes
187  GUM_DESTRUCTOR(DBTranslator4IntegerVariable);
188  }
189 
190 
191  /// copy operator
192  template < template < typename > class ALLOC >
193  DBTranslator4IntegerVariable< ALLOC >& DBTranslator4IntegerVariable< ALLOC >::operator=(
194  const DBTranslator4IntegerVariable< ALLOC >& from) {
195  if (this != &from) {
196  DBTranslator< ALLOC >::operator=(from);
197  _variable_ = from._variable_;
198  }
199 
200  return *this;
201  }
202 
203 
204  /// move operator
205  template < template < typename > class ALLOC >
206  DBTranslator4IntegerVariable< ALLOC >& DBTranslator4IntegerVariable< ALLOC >::operator=(
207  DBTranslator4IntegerVariable< ALLOC >&& from) {
208  if (this != &from) {
209  DBTranslator< ALLOC >::operator=(std::move(from));
210  _variable_ = std::move(from._variable_);
211  }
212 
213  return *this;
214  }
215 
216 
217  /// returns the translation of a string, as found in the current dictionary
218  template < template < typename > class ALLOC >
219  INLINE DBTranslatedValue
220  DBTranslator4IntegerVariable< ALLOC >::translate(const std::string& str) {
221  // try to get the index of str within the integer variable.
222  try {
223  return DBTranslatedValue{std::size_t(_variable_[str])};
224  } catch (gum::Exception&) {
225  // check for a missing symbol
226  if (this->isMissingSymbol(str))
227  return DBTranslatedValue{std::numeric_limits< std::size_t >::max()};
228 
229  // check if the back_dictionary does not contain str. This enables
230  // to execute translate ( translateBack ( translate ( str ) ) )
231  // without raising an exception
232  try {
233  return DBTranslatedValue{this->back_dico_.first(str)};
234  } catch (gum::Exception&) {
235  if (!DBCell::isInteger(str)) {
236  GUM_ERROR(TypeError,
237  "String \"" << str << "\" cannot be translated because it is not a number");
238  } else {
239  GUM_ERROR(UnknownLabelInDatabase,
240  "The translation of \"" << str << "\" could not be found")
241  }
242  }
243  }
244  }
245 
246 
247  /// returns the original value for a given translation
248  template < template < typename > class ALLOC >
249  INLINE std::string DBTranslator4IntegerVariable< ALLOC >::translateBack(
250  const DBTranslatedValue translated_val) const {
251  try {
252  return this->back_dico_.second(translated_val.discr_val);
253  } catch (Exception&) {
254  // check if this is a missing value
255  if ((translated_val.discr_val == std::numeric_limits< std::size_t >::max())
256  && !this->missing_symbols_.empty())
257  return *(this->missing_symbols_.begin());
258  else
259  GUM_ERROR(UnknownLabelInDatabase,
260  "The back translation of \"" << translated_val.discr_val
261  << "\" could not be found");
262  }
263  }
264 
265 
266  /// indicates whether the translator has an editable dictionary or not
267  template < template < typename > class ALLOC >
268  INLINE bool DBTranslator4IntegerVariable< ALLOC >::hasEditableDictionary() const {
269  return false;
270  }
271 
272 
273  /// sets/unset the editable dictionary mode
274  template < template < typename > class ALLOC >
275  INLINE void DBTranslator4IntegerVariable< ALLOC >::setEditableDictionaryMode(bool) {}
276 
277 
278  /// indicates whether the translations should be reordered
279  template < template < typename > class ALLOC >
280  bool DBTranslator4IntegerVariable< ALLOC >::needsReordering() const {
281  return false;
282  }
283 
284 
285  /// returns a mapping to reorder the current dictionary and updates it
286  template < template < typename > class ALLOC >
287  INLINE HashTable< std::size_t, std::size_t, ALLOC< std::pair< std::size_t, std::size_t > > >
288  DBTranslator4IntegerVariable< ALLOC >::reorder() {
289  return HashTable< std::size_t,
290  std::size_t,
291  ALLOC< std::pair< std::size_t, std::size_t > > >();
292  }
293 
294 
295  /// returns the domain size of a variable corresponding to the translations
296  template < template < typename > class ALLOC >
297  INLINE std::size_t DBTranslator4IntegerVariable< ALLOC >::domainSize() const {
298  return _variable_.domainSize();
299  }
300 
301 
302  /// returns the variable stored into the translator
303  template < template < typename > class ALLOC >
304  INLINE const IntegerVariable* DBTranslator4IntegerVariable< ALLOC >::variable() const {
305  return &_variable_;
306  }
307 
308 
309  /// returns the translation of a missing value
310  template < template < typename > class ALLOC >
311  INLINE DBTranslatedValue DBTranslator4IntegerVariable< ALLOC >::missingValue() const {
312  return DBTranslatedValue{std::numeric_limits< std::size_t >::max()};
313  }
314 
315 
316  } /* namespace learning */
317 
318 } /* namespace gum */
319 
320 
321 #endif /* DOXYGEN_SHOULD_SKIP_THIS */