aGrUM  0.13.2
linearApproximationPolicy_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  ***************************************************************************/
28 // Help IDE parsers
30 
31 namespace gum {
32 
33  // Class constructor
34  template < typename GUM_SCALAR >
36  GUM_SCALAR low, GUM_SCALAR high, GUM_SCALAR eps) :
37  ApproximationPolicy< GUM_SCALAR >(),
38  _lowLimit(low), _highLimit(high), _epsilon(eps) {
39  if (eps <= 0) { GUM_ERROR(OutOfBounds, "Epsilon must be >0"); }
40 
42  }
43 
44  // Copy constructor.
45  template < typename GUM_SCALAR >
48  ApproximationPolicy< GUM_SCALAR >(md),
50 
51 
52  // @brief Convert value to his approximation.
53  template < typename GUM_SCALAR >
55  const GUM_SCALAR& value) const {
56  return __decode(GUM_SCALAR(encode(value)));
57  }
58 
59  // @brief Combine using addition with the given gum::ApproximationPolicy.
60  template < typename GUM_SCALAR >
63  try {
65  dynamic_cast< const LinearApproximationPolicy< GUM_SCALAR >* >(ap);
66 
67  GUM_SCALAR newHighLimit = _lowLimit + lap->lowLimit();
68  GUM_SCALAR newLowLimit = _lowLimit + lap->lowLimit();
69 
70  GUM_SCALAR newVal = _lowLimit + lap->highLimit();
71 
72  if (newHighLimit < newVal) newHighLimit = newVal;
73 
74  if (newLowLimit > newVal) newLowLimit = newVal;
75 
76  newVal = _highLimit + lap->lowLimit();
77 
78  if (newHighLimit < newVal) newHighLimit = newVal;
79 
80  if (newLowLimit > newVal) newLowLimit = newVal;
81 
82  newVal = _highLimit + lap->highLimit();
83 
84  if (newHighLimit < newVal) newHighLimit = newVal;
85 
86  if (newLowLimit > newVal) newLowLimit = newVal;
87  } catch (const std::bad_cast&) {}
88  }
89 
90  template < typename GUM_SCALAR >
93  try {
95  dynamic_cast< const LinearApproximationPolicy< GUM_SCALAR >* >(ap);
96 
97  GUM_SCALAR newHighLimit = _lowLimit - lap->lowLimit();
98  GUM_SCALAR newLowLimit = _lowLimit - lap->lowLimit();
99 
100  GUM_SCALAR newVal = _lowLimit - lap->highLimit();
101 
102  if (newHighLimit < newVal) newHighLimit = newVal;
103 
104  if (newLowLimit > newVal) newLowLimit = newVal;
105 
106  newVal = _highLimit - lap->lowLimit();
107 
108  if (newHighLimit < newVal) newHighLimit = newVal;
109 
110  if (newLowLimit > newVal) newLowLimit = newVal;
111 
112  newVal = _highLimit - lap->highLimit();
113 
114  if (newHighLimit < newVal) newHighLimit = newVal;
115 
116  if (newLowLimit > newVal) newLowLimit = newVal;
117  } catch (const std::bad_cast&) {}
118  }
119 
120  template < typename GUM_SCALAR >
123  try {
125  dynamic_cast< const LinearApproximationPolicy< GUM_SCALAR >* >(ap);
126 
127  GUM_SCALAR newHighLimit = _lowLimit * lap->lowLimit();
128  GUM_SCALAR newLowLimit = _lowLimit * lap->lowLimit();
129 
130  GUM_SCALAR newVal = _lowLimit * lap->highLimit();
131 
132  if (newHighLimit < newVal) newHighLimit = newVal;
133 
134  if (newLowLimit > newVal) newLowLimit = newVal;
135 
136  newVal = _highLimit * lap->lowLimit();
137 
138  if (newHighLimit < newVal) newHighLimit = newVal;
139 
140  if (newLowLimit > newVal) newLowLimit = newVal;
141 
142  newVal = _highLimit * lap->highLimit();
143 
144  if (newHighLimit < newVal) newHighLimit = newVal;
145 
146  if (newLowLimit > newVal) newLowLimit = newVal;
147  } catch (const std::bad_cast&) {}
148  }
149 
150  template < typename GUM_SCALAR >
153  try {
155  dynamic_cast< const LinearApproximationPolicy< GUM_SCALAR >* >(ap);
156 
157  GUM_SCALAR newHighLimit = _lowLimit / lap->lowLimit();
158  GUM_SCALAR newLowLimit = _lowLimit / lap->lowLimit();
159 
160  GUM_SCALAR newVal = _lowLimit / lap->highLimit();
161 
162  if (newHighLimit < newVal) newHighLimit = newVal;
163 
164  if (newLowLimit > newVal) newLowLimit = newVal;
165 
166  newVal = _highLimit / lap->lowLimit();
167 
168  if (newHighLimit < newVal) newHighLimit = newVal;
169 
170  if (newLowLimit > newVal) newLowLimit = newVal;
171 
172  newVal = _highLimit / lap->highLimit();
173 
174  if (newHighLimit < newVal) newHighLimit = newVal;
175 
176  if (newLowLimit > newVal) newLowLimit = newVal;
177  } catch (const std::bad_cast&) {}
178  }
179 
180  template < typename GUM_SCALAR >
183  try {
185  dynamic_cast< const LinearApproximationPolicy< GUM_SCALAR >* >(ap);
186 
187  GUM_SCALAR newHighLimit =
188  _lowLimit > lap->lowLimit() ? _lowLimit : lap->lowLimit();
189  GUM_SCALAR newLowLimit =
190  _lowLimit > lap->lowLimit() ? _lowLimit : lap->lowLimit();
191 
192  GUM_SCALAR newVal =
193  _lowLimit > lap->highLimit() ? _lowLimit : lap->highLimit();
194 
195  if (newHighLimit < newVal) newHighLimit = newVal;
196 
197  if (newLowLimit > newVal) newLowLimit = newVal;
198 
199  newVal = _highLimit > lap->lowLimit() ? _highLimit : lap->lowLimit();
200 
201  if (newHighLimit < newVal) newHighLimit = newVal;
202 
203  if (newLowLimit > newVal) newLowLimit = newVal;
204 
205  newVal = _highLimit > lap->highLimit() ? _highLimit : lap->highLimit();
206 
207  if (newHighLimit < newVal) newHighLimit = newVal;
208 
209  if (newLowLimit > newVal) newLowLimit = newVal;
210  } catch (const std::bad_cast&) {}
211  }
212 
213  template < typename GUM_SCALAR >
216  try {
218  dynamic_cast< const LinearApproximationPolicy< GUM_SCALAR >* >(ap);
219 
220  GUM_SCALAR newHighLimit =
221  _lowLimit < lap->lowLimit() ? _lowLimit : lap->lowLimit();
222  GUM_SCALAR newLowLimit =
223  _lowLimit < lap->lowLimit() ? _lowLimit : lap->lowLimit();
224 
225  GUM_SCALAR newVal =
226  _lowLimit < lap->highLimit() ? _lowLimit : lap->highLimit();
227 
228  if (newHighLimit < newVal) newHighLimit = newVal;
229 
230  if (newLowLimit > newVal) newLowLimit = newVal;
231 
232  newVal = _highLimit < lap->lowLimit() ? _highLimit : lap->lowLimit();
233 
234  if (newHighLimit < newVal) newHighLimit = newVal;
235 
236  if (newLowLimit > newVal) newLowLimit = newVal;
237 
238  newVal = _highLimit < lap->highLimit() ? _highLimit : lap->highLimit();
239 
240  if (newHighLimit < newVal) newHighLimit = newVal;
241 
242  if (newLowLimit > newVal) newLowLimit = newVal;
243  } catch (const std::bad_cast&) {}
244  }
245 
246  // Convert value to his approximation. This method is slower than @ref
247  // fromExact since it verifies the bounds
248  template < typename GUM_SCALAR >
250  const GUM_SCALAR& value) {
251  if (value > this->_highLimit) {
252  GUM_ERROR(OutOfUpperBound, "Value asked is higher than high limit");
253  }
254 
255  if (value < this->_lowLimit) {
256  GUM_ERROR(OutOfLowerBound, "Value asked is lower than low limit");
257  }
258 
259  return fromExact(value);
260  }
261 
262  // Convert value to approximation representation
263  template < typename GUM_SCALAR >
265  const GUM_SCALAR& value) const {
266 // we keep the bounds checked in debug mode
267 #ifndef NDEBUG
268  if (value > this->_highLimit) {
269  GUM_TRACE(value << " not in (" << this->_lowLimit << "-" << this->_highLimit
270  << ")");
271  GUM_ERROR(OutOfUpperBound, "Value asked is higher than High limit");
272  }
273 
274  if (value < this->_lowLimit) {
275  GUM_TRACE(value << " not in (" << this->_lowLimit << "-" << this->_highLimit
276  << ")");
277  GUM_ERROR(OutOfLowerBound, "Value asked is lower than low limit");
278  }
279 
280 #endif // NDEBUG
281  return __encode(value);
282  }
283 
284  // Convert approximation representation to value
285  template < typename GUM_SCALAR >
286  INLINE GUM_SCALAR
288  if (representation > _nbInterval) {
290  "Interval Number asked is higher than total number of interval");
291  }
292 
293  return __decode(GUM_SCALAR(representation));
294  }
295 
296  // Sets approximation factor
297  template < typename GUM_SCALAR >
298  INLINE void
300  _epsilon = e;
302  }
303 
304  // set bounds in a whole
305  template < typename GUM_SCALAR >
307  const GUM_SCALAR& newLowLimit, const GUM_SCALAR& newHighLimit) {
308  if (newLowLimit > newHighLimit) {
309  GUM_ERROR(OutOfBounds, "Asked low value is higher than asked high value");
310  }
311 
312  _lowLimit = newLowLimit;
313  _highLimit = newHighLimit;
315  }
316 
317  // Sets lowest possible value
318  template < typename GUM_SCALAR >
320  const GUM_SCALAR& newLowLimit) {
321  if (newLowLimit > this->_highLimit) {
322  GUM_ERROR(OutOfUpperBound, "Value asked is higher than High limit");
323  }
324 
325  _lowLimit = newLowLimit;
326 
328  }
329 
330  // Gets lowest possible value
331  template < typename GUM_SCALAR >
332  INLINE const GUM_SCALAR&
334  return _lowLimit;
335  }
336 
337  // Sets Highest possible value
338  template < typename GUM_SCALAR >
340  const GUM_SCALAR& newHighLimit) {
341  if (newHighLimit < this->_lowLimit) {
342  GUM_ERROR(OutOfLowerBound, "Value asked is lower than low limit");
343  }
344 
345  _highLimit = newHighLimit;
346 
348  }
349 
350  // Gets Highest possible value
351  template < typename GUM_SCALAR >
352  INLINE const GUM_SCALAR&
354  return _highLimit;
355  }
356 
357  // Concretely computes the approximate representation
358  template < typename GUM_SCALAR >
360  const GUM_SCALAR& value) const {
361  if (value <= this->_lowLimit) return 0;
362 
363  if (value >= this->_highLimit) return _nbInterval;
364 
365  return 1 + Idx(((value - this->_lowLimit) / this->_epsilon));
366  }
367 
368  // Concretely computes the approximate value from representation
369  template < typename GUM_SCALAR >
371  const GUM_SCALAR& representation) const {
372  if (representation == 0) return this->_lowLimit;
373 
374  if (representation == _nbInterval) return this->_highLimit;
375 
376  return (GUM_SCALAR)(((representation * this->_epsilon) - (this->_epsilon / 2))
377  + this->_lowLimit);
378  }
379 
380  // get the number of interval
381  template < typename GUM_SCALAR >
383  _nbInterval = 1 + Idx((this->_highLimit - this->_lowLimit) / this->_epsilon);
384  }
385 } // namespace gum
void combineSub(const ApproximationPolicy< GUM_SCALAR > *ap)
Combine using substraction with the given gum::ApproximationPolicy.
virtual void setEpsilon(const GUM_SCALAR &e)
Sets approximation factor.
const GUM_SCALAR & highLimit() const
Gets Highest possible value.
GUM_SCALAR _lowLimit
Lowest value possible.
void combineDiv(const ApproximationPolicy< GUM_SCALAR > *ap)
Combine using division with the given gum::ApproximationPolicy.
GUM_SCALAR _epsilon
Approximation factor.
Idx __encode(const GUM_SCALAR &value) const
Concretely computes the approximate representation.
void combineMin(const ApproximationPolicy< GUM_SCALAR > *ap)
Combine using min with the given gum::ApproximationPolicy.
GUM_SCALAR decode(Idx representation) const
Convert approximation representation to value.
virtual void setLimits(const GUM_SCALAR &newLowLimit, const GUM_SCALAR &newHighLimit)
Set bounds in a whole.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
GUM_SCALAR __decode(const GUM_SCALAR &representation) const
Concretely computes the approximate value from representation.
Classes used to practice approximation on value.
GUM_SCALAR fromExact(const GUM_SCALAR &value) const
Convert value to his approximation.
GUM_SCALAR _highLimit
Highest value possible.
Idx _nbInterval
The number of interval.
virtual void setHighLimit(const GUM_SCALAR &newHighLimit)
Sets Highest possible value.
LinearApproximationPolicy(GUM_SCALAR low=(GUM_SCALAR) 0.0, GUM_SCALAR high=(GUM_SCALAR) 1.0, GUM_SCALAR eps=(GUM_SCALAR) 0.1)
Default constructor.
void combineMult(const ApproximationPolicy< GUM_SCALAR > *ap)
Combine using multiplication with the given gum::ApproximationPolicy.
Idx encode(const GUM_SCALAR &value) const
Encode a given value into its approximation representation.
const GUM_SCALAR & lowLimit() const
Gets lowest possible value.
Class implementing linear approximation policy (meaning possible value are split out in interval)...
unsigned long Idx
Type for indexes.
Definition: types.h:43
GUM_SCALAR safeFromExact(const GUM_SCALAR &value)
Convert value to his approximation.
void combineMax(const ApproximationPolicy< GUM_SCALAR > *ap)
Combine using max with the given gum::ApproximationPolicy.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:66
Mother class for all approximation policy classes.
virtual void setLowLimit(const GUM_SCALAR &newLowLimit)
Sets lowest possible value.
void combineAdd(const ApproximationPolicy< GUM_SCALAR > *ap)
Combine using addition with the given gum::ApproximationPolicy.
void _computeNbInterval()
Get the number of interval.