aGrUM  0.14.2
discretizedVariable_tpl.h
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
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  ***************************************************************************/
20 #ifndef DOXYGEN_SHOULD_SKIP_THIS
21 # include <sstream>
22 
24 
25 namespace gum {
26  template < typename T_TICKS >
28  const DiscretizedVariable< T_TICKS >& aDRV) {
29  eraseTicks();
31 
32  for (Idx i = 0; i < aDRV.__ticks_size; ++i) {
33  addTick((T_TICKS)aDRV.__ticks[i]);
34  }
35  }
36 
37  template < typename T_TICKS >
38  Idx DiscretizedVariable< T_TICKS >::_dichotomy(const T_TICKS& target,
39  Idx min,
40  Idx max) const {
41  Idx res;
42  Idx mid = 0;
43 
44  if (max - min < 2)
45  res = min;
46  else {
47  mid = (max + min) / 2;
48  T_TICKS val = __ticks[mid];
49 
50  if (target == val)
51  res = mid;
52  else if (target < val)
53  res = _dichotomy(target, min, mid);
54  else if (target > val)
55  res = _dichotomy(target, mid, max);
56  else
57  res = mid;
58  }
59 
60  return res;
61  }
62 
63  template < typename T_TICKS >
64  INLINE Idx DiscretizedVariable< T_TICKS >::_pos(const T_TICKS& target) const {
65  if (__ticks_size < 2) { GUM_ERROR(OutOfBounds, "not enough ticks"); }
66 
67  if (target < __ticks[0]) {
68  GUM_ERROR(OutOfLowerBound, "less than first range");
69  }
70 
71  if (target > __ticks[__ticks_size - 1]) {
72  GUM_ERROR(OutOfUpperBound, "more than last range");
73  }
74 
75  if (target == __ticks[__ticks_size - 1]) // special case for upper limit
76  // (which belongs to class __ticks_size-2
77  return __ticks_size - 2;
78 
79  return _dichotomy(target, 0, __ticks_size - 1);
80  }
81 
82  template < typename T_TICKS >
84  const std::string& aName, const std::string& aDesc) :
85  IDiscretizedVariable(aName, aDesc),
86  __ticks_size((Size)0) {
87  GUM_CONSTRUCTOR(DiscretizedVariable);
88  __ticks.reserve(1);
89  }
90 
91  template < typename T_TICKS >
93  const std::string& aName,
94  const std::string& aDesc,
95  const std::vector< T_TICKS >& ticks) :
96  IDiscretizedVariable(aName, aDesc),
97  __ticks_size((Size)0) {
98  GUM_CONSTRUCTOR(DiscretizedVariable);
99  __ticks.reserve(ticks.size());
100  for (const auto t : ticks)
101  addTick(t);
102  }
103 
104  template < typename T_TICKS >
106  const DiscretizedVariable< T_TICKS >& aDRV) :
107  IDiscretizedVariable(aDRV) {
108  GUM_CONS_CPY(DiscretizedVariable);
109  __ticks.reserve(1);
110  _copy(aDRV);
111  }
112 
113  template < typename T_TICKS >
115  GUM_DESTRUCTOR(DiscretizedVariable);
116  }
117 
118  template < typename T_TICKS >
119  DiscretizedVariable< T_TICKS >* DiscretizedVariable< T_TICKS >::clone() const {
120  return new DiscretizedVariable< T_TICKS >(*this);
121  }
122 
123  template < typename T_TICKS >
124  INLINE DiscretizedVariable< T_TICKS >& DiscretizedVariable< T_TICKS >::
125  operator=(const DiscretizedVariable< T_TICKS >& aDRV) {
126  _copy(aDRV);
127  return *this;
128  }
129 
130  template < typename T_TICKS >
131  INLINE bool DiscretizedVariable< T_TICKS >::isTick(const T_TICKS& aTick) const {
132  if (__ticks_size == 0) return false;
133 
134  if (__ticks_size == 1) return (__ticks[0] == aTick);
135 
136  try {
137  Idx zeIdx = _pos(aTick);
138 
139  if (zeIdx != __ticks_size - 2)
140  return (__ticks[zeIdx] == aTick);
141  else // special case for upper limit
142  return ((__ticks[zeIdx] == aTick) || (__ticks[zeIdx + 1] == aTick));
143  } catch (OutOfBounds&) { return false; }
144  }
145 
146  template < typename T_TICKS >
147  DiscretizedVariable< T_TICKS >&
148  DiscretizedVariable< T_TICKS >::addTick(const T_TICKS& aTick) {
149  if (isTick(aTick)) {
150  GUM_ERROR(DefaultInLabel,
151  "Tick '" << aTick << "' already used for variable " << name());
152  }
153 
154  if (__ticks_size == __ticks.size()) { // streching __ticks if necessary
155  __ticks.resize(__ticks_size + 1);
156  }
157 
158  if (__ticks_size == 0) { // special case for first tick
159  __ticks[0] = aTick;
160  } else if (__ticks_size == 1) { // special case for second tick
161  if (__ticks[0] < aTick) {
162  __ticks[1] = aTick;
163  } else {
164  __ticks[1] = __ticks[0];
165  __ticks[0] = aTick;
166  }
167  } else {
168  try {
169  Idx zeIdx =
170  _pos(aTick); // aTick is in [ __ticks[zeIdx],__ticks[zeIdx+1] [
171 
172  for (Idx i = __ticks_size - 1; i > zeIdx; --i) {
173  __ticks[i + 1] = __ticks[i];
174  }
175 
176  __ticks[zeIdx + 1] = aTick;
177  } catch (OutOfUpperBound&) { // new upper bound
178  __ticks[__ticks_size] = aTick;
179  } catch (OutOfLowerBound&) { // new lower bound
180  for (Idx i = __ticks_size; i >= 1; --i) {
181  __ticks[i] = __ticks[i - 1];
182  }
183 
184  __ticks[0] = aTick;
185  }
186  }
187 
188  __ticks_size++;
189 
190  return *this;
191  }
192 
193  template < typename T_TICKS >
195  if (__ticks_size != 0) { __ticks_size = 0; }
196  }
197 
198  template < typename T_TICKS >
199  INLINE std::string DiscretizedVariable< T_TICKS >::label(Idx i) const {
200  std::stringstream ss;
201 
202  if (i >= __ticks_size - 1) {
203  GUM_ERROR(OutOfBounds, "inexisting label index");
204  }
205 
206  ss << "[" << __ticks[i] << ";" << __ticks[i + 1];
207 
208  ss << ((i == __ticks_size - 2) ? "]" : "[");
209 
210  return ss.str();
211  }
212 
214  template < typename T_TICKS >
215  INLINE double DiscretizedVariable< T_TICKS >::numerical(Idx indice) const {
216  if (indice >= __ticks_size - 1) {
217  GUM_ERROR(OutOfBounds, "inexisting label index");
218  }
219 
220  return double((__ticks[indice + 1] + __ticks[indice]) / 2);
221  }
222 
223  template < typename T_TICKS >
224  INLINE Idx
225  DiscretizedVariable< T_TICKS >::index(const std::string& label) const {
226  if (empty()) { GUM_ERROR(OutOfBounds, "empty variable : " + toString()); }
227 
228  std::istringstream i(label);
229  T_TICKS target;
230 
231  if (!(i >> target)) {
232  GUM_ERROR(NotFound, "Bad label : " << label << " for " << *this);
233  }
234 
235  return _pos(target);
236  }
237 
242  template < typename T_TICKS >
244  return (__ticks_size < 2) ? Size(0) : Size(__ticks_size - 1);
245  }
246 
247  template < typename T_TICKS >
249  return VarType::Discretized;
250  }
251 
252  template < typename T_TICKS >
253  INLINE const T_TICKS& DiscretizedVariable< T_TICKS >::tick(Idx i) const {
254  if (i >= __ticks_size) { GUM_ERROR(OutOfBounds, "There is no such tick"); }
255 
256  return __ticks[i];
257  }
258 
259  template < typename T_TICKS >
260  const std::string DiscretizedVariable< T_TICKS >::domain() const {
261  std::stringstream s;
262  s << "<";
263 
264  if (domainSize() > 0) {
265  s << label(0);
266 
267  for (Idx i = 1; i < domainSize(); ++i) {
268  s << ",";
269  s << label(i);
270  }
271  }
272 
273  s << ">";
274 
275  return s.str();
276  }
277 
278  template < typename T_TICKS >
279  INLINE const std::vector< T_TICKS >&
281  return this->__ticks;
282  }
283 
284  template < typename T_TICKS >
285  INLINE std::vector< double >
287  const std::size_t size = __ticks.size();
288  std::vector< double > ticks(size);
289  for (std::size_t i = std::size_t(0); i < size; ++i)
290  ticks[i] = (double)__ticks[i];
291  return ticks;
292  }
293 
294 } /* namespace gum */
295 
296 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
virtual std::vector< double > ticksAsDoubles() const
return the list of ticks as a vector of doubles
std::vector< T_TICKS > __ticks
void _copy(const Variable &aRV)
protected copy
virtual Idx index(const std::string &label) const
from the label to its index in var.
virtual Size domainSize() const
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
virtual ~DiscretizedVariable()
Destructor.
virtual std::string label(Idx i) const
const std::vector< T_TICKS > & ticks() const
Return the list of ticks.
bool isTick(const T_TICKS &aTick) const
DiscretizedVariable & addTick(const T_TICKS &aTick)
add a tick.
VarType
Definition: variable.h:38
virtual double numerical(Idx indice) const
get a numerical representation of he indice-the value.
DiscretizedVariable(const std::string &aName, const std::string &aDesc)
Constructor.
Idx _pos(const T_TICKS &target) const
seach the class of target (internally use _dichotomy)
DiscretizedVariable< T_TICKS > & operator=(const DiscretizedVariable< T_TICKS > &aDRV)
operator =
const T_TICKS & tick(Idx i) const
from the index to the tick.
void eraseTicks()
erase all the Ticks
IDiscretizedVariable(const std::string &aName, const std::string &aDesc)
Default constructor.
virtual DiscretizedVariable< T_TICKS > * clone() const
a virtual clone
const std::string toString() const
string version of *this
virtual const std::string domain() const
string represent the domain of the variable
virtual VarType varType() const
returns the type of variable
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
const std::string & name() const
returns the name of the variable
void _copy(const DiscretizedVariable< T_TICKS > &aDRV)
make a copy TODO since we removed T_OtherData maybe some changes are needed in this method...
Idx _dichotomy(const T_TICKS &target, Idx min, Idx max) const
perform a dichotomy on ticks
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52