33 template<
class T,
typename A>
44 template<
class T,
int n>
54 {
return std::numeric_limits<typename EpsilonType<T>::Type>::epsilon()*8.; }
59 {
return std::numeric_limits<typename EpsilonType<T>::Type>::epsilon()*8.; }
69 template<
class T, CmpStyle style = defaultCmpStyle>
73 static bool eq(
const T &first,
78 return abs(first - second) <= epsilon*std::max(abs(first), abs(second));
83 static bool eq(
const T &first,
88 return abs(first - second) <= epsilon*std::min(abs(first), abs(second));
93 static bool eq(
const T &first,
98 return abs(first-second) <= epsilon;
101 template<
class T, CmpStyle cstyle>
102 struct eq_t_std_vec {
103 typedef std::vector<T> V;
104 static bool eq(
const V &first,
107 auto size = first.size();
108 if(size != second.size())
return false;
109 for(
unsigned int i = 0; i < size; ++i)
110 if(!eq_t<T, cstyle>::eq(first[i], second[i], epsilon))
116 struct eq_t<
std::vector<T>,
relativeWeak> : eq_t_std_vec<T, relativeWeak> {};
118 struct eq_t<
std::vector<T>,
relativeStrong> : eq_t_std_vec<T, relativeStrong> {};
120 struct eq_t<
std::vector<T>,
absolute> : eq_t_std_vec<T, absolute> {};
122 template<
class T,
int n, CmpStyle cstyle>
125 static bool eq(
const V &first,
128 for(
int i = 0; i < n; ++i)
129 if(!eq_t<T, cstyle>::eq(first[i], second[i], epsilon))
134 template<
class T,
int n >
135 struct eq_t<
Dune::FieldVector<T, n>,
relativeWeak> : eq_t_fvec<T, n, relativeWeak> {};
136 template<
class T,
int n >
137 struct eq_t<
Dune::FieldVector<T, n>,
relativeStrong> : eq_t_fvec<T, n, relativeStrong> {};
138 template<
class T,
int n >
139 struct eq_t<
Dune::FieldVector<T, n>,
absolute> : eq_t_fvec<T, n, absolute> {};
143 template <
class T, CmpStyle style>
144 bool eq(
const T &first,
148 return Impl::eq_t<T, style>::eq(first, second, epsilon);
150 template <
class T, CmpStyle style>
151 bool ne(
const T &first,
155 return !eq<T, style>(first, second, epsilon);
157 template <
class T, CmpStyle style>
158 bool gt(
const T &first,
162 return first > second && ne<T, style>(first, second, epsilon);
164 template <
class T, CmpStyle style>
165 bool lt(
const T &first,
169 return first < second && ne<T, style>(first, second, epsilon);
171 template <
class T, CmpStyle style>
172 bool ge(
const T &first,
176 return first > second || eq<T, style>(first, second, epsilon);
178 template <
class T, CmpStyle style>
179 bool le(
const T &first,
183 return first < second || eq<T, style>(first, second, epsilon);
188 bool eq(
const T &first,
192 return eq<T, defaultCmpStyle>(first, second, epsilon);
195 bool ne(
const T &first,
199 return ne<T, defaultCmpStyle>(first, second, epsilon);
202 bool gt(
const T &first,
206 return gt<T, defaultCmpStyle>(first, second, epsilon);
209 bool lt(
const T &first,
213 return lt<T, defaultCmpStyle>(first, second, epsilon);
216 bool ge(
const T &first,
220 return ge<T, defaultCmpStyle>(first, second, epsilon);
223 bool le(
const T &first,
227 return le<T, defaultCmpStyle>(first, second, epsilon);
232 template<
class I,
class T, CmpStyle cstyle = defaultCmpStyle, RoundingStyle rstyle = defaultRoundingStyle>
234 template<
class I,
class T, CmpStyle cstyle>
235 struct round_t<I, T, cstyle,
downward> {
242 if(eq<T, cstyle>(T(lower), val, epsilon))
return lower;
243 if(T(lower) > val) { upper = lower; lower--; }
244 else upper = lower+1;
245 if(le<T, cstyle>(val - T(lower), T(upper) - val, epsilon))
250 template<
class I,
class T, CmpStyle cstyle>
251 struct round_t<I, T, cstyle,
upward> {
258 if(eq<T, cstyle>(T(lower), val, epsilon))
return lower;
259 if(T(lower) > val) { upper = lower; lower--; }
260 else upper = lower+1;
261 if(lt<T, cstyle>(val - T(lower), T(upper) - val, epsilon))
266 template<
class I,
class T, CmpStyle cstyle>
272 return round_t<I, T, cstyle, downward>::round(val, epsilon);
273 else return round_t<I, T, cstyle, upward>::round(val, epsilon);
276 template<
class I,
class T, CmpStyle cstyle>
277 struct round_t<I, T, cstyle,
towardInf> {
282 return round_t<I, T, cstyle, upward>::round(val, epsilon);
283 else return round_t<I, T, cstyle, downward>::round(val, epsilon);
286 template<
class I,
class T, CmpStyle cstyle, RoundingStyle rstyle>
287 struct round_t<
std::vector<I>, std::vector<T>, cstyle, rstyle> {
288 static std::vector<I>
291 unsigned int size = val.size();
292 std::vector<I> res(size);
293 for(
unsigned int i = 0; i < size; ++i)
294 res[i] = round_t<I, T, cstyle, rstyle>::round(val[i], epsilon);
298 template<
class I,
class T,
int n, CmpStyle cstyle, RoundingStyle rstyle>
304 for(
int i = 0; i < n; ++i)
305 res[i] = round_t<I, T, cstyle, rstyle>::round(val[i], epsilon);
310 template<
class I,
class T, CmpStyle cstyle, RoundingStyle rstyle>
313 return Impl::round_t<I, T, cstyle, rstyle>::round(val, epsilon);
315 template<
class I,
class T, CmpStyle cstyle>
318 return round<I, T, cstyle, defaultRoundingStyle>(val, epsilon);
320 template<
class I,
class T, RoundingStyle rstyle>
323 return round<I, T, defaultCmpStyle, rstyle>(val, epsilon);
325 template<
class I,
class T>
328 return round<I, T, defaultCmpStyle>(val, epsilon);
333 template<
class I,
class T, CmpStyle cstyle = defaultCmpStyle, RoundingStyle rstyle = defaultRoundingStyle>
335 template<
class I,
class T, CmpStyle cstyle>
336 struct trunc_t<I, T, cstyle,
downward> {
341 if(!std::numeric_limits<I>::is_signed)
343 if(eq<T, cstyle>(val, T(0), epsilon))
return I(0);
347 if(T(lower) > val) lower--;
349 if(eq<T, cstyle>(T(lower+1), val, epsilon))
354 template<
class I,
class T, CmpStyle cstyle>
355 struct trunc_t<I, T, cstyle,
upward> {
359 I upper = trunc_t<I, T, cstyle, downward>::trunc(val, epsilon);
360 if(ne<T, cstyle>(T(upper), val, epsilon)) ++upper;
364 template<
class I,
class T, CmpStyle cstyle>
369 if(val > T(0))
return trunc_t<I, T, cstyle, downward>::trunc(val, epsilon);
370 else return trunc_t<I, T, cstyle, upward>::trunc(val, epsilon);
373 template<
class I,
class T, CmpStyle cstyle>
374 struct trunc_t<I, T, cstyle,
towardInf> {
378 if(val > T(0))
return trunc_t<I, T, cstyle, upward>::trunc(val, epsilon);
379 else return trunc_t<I, T, cstyle, downward>::trunc(val, epsilon);
382 template<
class I,
class T, CmpStyle cstyle, RoundingStyle rstyle>
383 struct trunc_t<
std::vector<I>, std::vector<T>, cstyle, rstyle> {
384 static std::vector<I>
385 trunc(
const std::vector<T> &val,
387 unsigned int size = val.size();
388 std::vector<I> res(size);
389 for(
unsigned int i = 0; i < size; ++i)
390 res[i] = trunc_t<I, T, cstyle, rstyle>::trunc(val[i], epsilon);
394 template<
class I,
class T,
int n, CmpStyle cstyle, RoundingStyle rstyle>
400 for(
int i = 0; i < n; ++i)
401 res[i] = trunc_t<I, T, cstyle, rstyle>::trunc(val[i], epsilon);
406 template<
class I,
class T, CmpStyle cstyle, RoundingStyle rstyle>
409 return Impl::trunc_t<I, T, cstyle, rstyle>::trunc(val, epsilon);
411 template<
class I,
class T, CmpStyle cstyle>
414 return trunc<I, T, cstyle, defaultRoundingStyle>(val, epsilon);
416 template<
class I,
class T, RoundingStyle rstyle>
419 return trunc<I, T, defaultCmpStyle, rstyle>(val, epsilon);
421 template<
class I,
class T>
424 return trunc<I, T, defaultCmpStyle>(val, epsilon);
429 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
434 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
441 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
445 epsilon_ = epsilon__;
449 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
453 return Dune::FloatCmp::eq<ValueType, cstyle>(first, second, epsilon_);
456 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
460 return Dune::FloatCmp::ne<ValueType, cstyle>(first, second, epsilon_);
463 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
467 return Dune::FloatCmp::gt<ValueType, cstyle>(first, second, epsilon_);
470 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
474 return Dune::FloatCmp::lt<ValueType, cstyle>(first, second, epsilon_);
477 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
481 return Dune::FloatCmp::ge<ValueType, cstyle>(first, second, epsilon_);
484 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
488 return Dune::FloatCmp::le<ValueType, cstyle>(first, second, epsilon_);
492 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
497 return Dune::FloatCmp::round<I, ValueType, cstyle, rstyle_>(val, epsilon_);
500 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
505 return Dune::FloatCmp::trunc<I, ValueType, cstyle, rstyle_>(val, epsilon_);
Implements a vector constructed from a given type representing a field and a compile-time given size.
Various ways to compare floating-point numbers.
bool ne(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test for inequality using epsilon
Definition float_cmp.cc:151
bool eq(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test for equality using epsilon
Definition float_cmp.cc:144
I round(const T &val, typename EpsilonType< T >::Type epsilon)
round using epsilon
Definition float_cmp.cc:311
I trunc(const T &val, typename EpsilonType< T >::Type epsilon)
truncate using epsilon
Definition float_cmp.cc:407
bool lt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first lesser than second
Definition float_cmp.cc:165
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition float_cmp.cc:158
bool ge(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater or equal second
Definition float_cmp.cc:172
bool le(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first lesser or equal second
Definition float_cmp.cc:179
@ relativeStrong
|a-b|/|a| <= epsilon && |a-b|/|b| <= epsilon
Definition float_cmp.hh:108
@ relativeWeak
|a-b|/|a| <= epsilon || |a-b|/|b| <= epsilon
Definition float_cmp.hh:106
@ absolute
|a-b| <= epsilon
Definition float_cmp.hh:110
@ towardZero
always round toward 0
Definition float_cmp.hh:118
@ towardInf
always round away from 0
Definition float_cmp.hh:120
@ upward
round toward
Definition float_cmp.hh:124
@ downward
round toward
Definition float_cmp.hh:122
Dune namespace.
Definition alignedallocator.hh:13
vector space out of a tensor product of fields.
Definition fvector.hh:95
Mapping of value type to epsilon type.
Definition float_cmp.cc:23
T Type
The epsilon type corresponding to value type T.
Definition float_cmp.cc:25
EpsilonType< T >::Type Type
The epsilon type corresponding to value type std::vector<T, A>
Definition float_cmp.cc:36
EpsilonType< T >::Type Type
The epsilon type corresponding to value type Dune::FieldVector<T, n>
Definition float_cmp.cc:47
static EpsilonType< T >::Type value()
Definition float_cmp.cc:53
static EpsilonType< T >::Type value()
Definition float_cmp.cc:58
static EpsilonType< T >::Type value()
Definition float_cmp.cc:63
mapping from a value type and a compare style to a default epsilon
Definition float_cmp.hh:138
static EpsilonType< T >::Type value()
Returns the default epsilon for the given value type and compare style.
bool le(const ValueType &first, const ValueType &second) const
test if first lesser or equal second
Definition float_cmp.cc:486
FloatCmpOps(EpsilonType epsilon=DefaultEpsilon::value())
construct an operations object
Definition float_cmp.cc:431
bool eq(const ValueType &first, const ValueType &second) const
test for equality using epsilon
Definition float_cmp.cc:451
bool lt(const ValueType &first, const ValueType &second) const
test if first lesser than second
Definition float_cmp.cc:472
bool ge(const ValueType &first, const ValueType &second) const
test if first greater or equal second
Definition float_cmp.cc:479
FloatCmp::EpsilonType< T >::Type EpsilonType
Type of the epsilon.
Definition float_cmp.hh:304
bool ne(const ValueType &first, const ValueType &second) const
test for inequality using epsilon
Definition float_cmp.cc:458
T ValueType
Type of the values to compare.
Definition float_cmp.hh:299
EpsilonType epsilon() const
return the current epsilon
Definition float_cmp.cc:436
I round(const ValueType &val) const
round using epsilon
Definition float_cmp.cc:495
I trunc(const ValueType &val) const
truncate using epsilon
Definition float_cmp.cc:503
bool gt(const ValueType &first, const ValueType &second) const
test if first greater than second
Definition float_cmp.cc:465