31 template<
class T,
typename A>
42 template<
class T,
int n>
67 template<
class T, CmpStyle style = defaultCmpStyle>
71 static bool eq(
const T &first,
76 return abs(first - second) <= epsilon*
std::max(abs(first), abs(second));
81 static bool eq(
const T &first,
86 return abs(first - second) <= epsilon*
std::min(abs(first), abs(second));
91 static bool eq(
const T &first,
96 return abs(first-second) <= epsilon;
99 template<
class T, CmpStyle cstyle>
100 struct eq_t_std_vec {
102 static bool eq(
const V &first,
105 auto size = first.size();
106 if(size != second.size())
return false;
107 for(
unsigned int i = 0; i <
size; ++i)
108 if(!eq_t<T, cstyle>::eq(first[i], second[i], epsilon))
114 struct eq_t<
std::vector<T>,
relativeWeak> : eq_t_std_vec<T, relativeWeak> {};
116 struct eq_t<
std::vector<T>,
relativeStrong> : eq_t_std_vec<T, relativeStrong> {};
118 struct eq_t<
std::vector<T>,
absolute> : eq_t_std_vec<T, absolute> {};
120 template<
class T,
int n, CmpStyle cstyle>
123 static bool eq(
const V &first,
126 for(
int i = 0; i < n; ++i)
127 if(!eq_t<T, cstyle>::eq(first[i], second[i], epsilon))
132 template<
class T,
int n >
133 struct eq_t<
Dune::FieldVector<T, n>,
relativeWeak> : eq_t_fvec<T, n, relativeWeak> {};
134 template<
class T,
int n >
135 struct eq_t<
Dune::FieldVector<T, n>,
relativeStrong> : eq_t_fvec<T, n, relativeStrong> {};
136 template<
class T,
int n >
137 struct eq_t<
Dune::FieldVector<T, n>,
absolute> : eq_t_fvec<T, n, absolute> {};
141 template <
class T, CmpStyle style>
142 bool eq(
const T &first,
146 return Impl::eq_t<T, style>::eq(first, second, epsilon);
148 template <
class T, CmpStyle style>
149 bool ne(
const T &first,
153 return !eq<T, style>(first, second, epsilon);
155 template <
class T, CmpStyle style>
156 bool gt(
const T &first,
160 return first > second && ne<T, style>(first, second, epsilon);
162 template <
class T, CmpStyle style>
163 bool lt(
const T &first,
167 return first < second && ne<T, style>(first, second, epsilon);
169 template <
class T, CmpStyle style>
170 bool ge(
const T &first,
174 return first > second || eq<T, style>(first, second, epsilon);
176 template <
class T, CmpStyle style>
177 bool le(
const T &first,
181 return first < second || eq<T, style>(first, second, epsilon);
186 bool eq(
const T &first,
190 return eq<T, defaultCmpStyle>(first, second, epsilon);
193 bool ne(
const T &first,
197 return ne<T, defaultCmpStyle>(first, second, epsilon);
200 bool gt(
const T &first,
204 return gt<T, defaultCmpStyle>(first, second, epsilon);
207 bool lt(
const T &first,
211 return lt<T, defaultCmpStyle>(first, second, epsilon);
214 bool ge(
const T &first,
218 return ge<T, defaultCmpStyle>(first, second, epsilon);
221 bool le(
const T &first,
225 return le<T, defaultCmpStyle>(first, second, epsilon);
230 template<
class I,
class T, CmpStyle cstyle = defaultCmpStyle, RoundingStyle rstyle = defaultRoundingStyle>
232 template<
class I,
class T, CmpStyle cstyle>
233 struct round_t<I, T, cstyle,
downward> {
240 if(eq<T, cstyle>(T(lower), val, epsilon))
return lower;
241 if(T(lower) > val) { upper = lower; lower--; }
242 else upper = lower+1;
243 if(le<T, cstyle>(val - T(lower), T(upper) - val, epsilon))
248 template<
class I,
class T, CmpStyle cstyle>
249 struct round_t<I, T, cstyle,
upward> {
256 if(eq<T, cstyle>(T(lower), val, epsilon))
return lower;
257 if(T(lower) > val) { upper = lower; lower--; }
258 else upper = lower+1;
259 if(lt<T, cstyle>(val - T(lower), T(upper) - val, epsilon))
264 template<
class I,
class T, CmpStyle cstyle>
270 return round_t<I, T, cstyle, downward>::round(val, epsilon);
271 else return round_t<I, T, cstyle, upward>::round(val, epsilon);
274 template<
class I,
class T, CmpStyle cstyle>
275 struct round_t<I, T, cstyle,
towardInf> {
280 return round_t<I, T, cstyle, upward>::round(val, epsilon);
281 else return round_t<I, T, cstyle, downward>::round(val, epsilon);
284 template<
class I,
class T, CmpStyle cstyle, RoundingStyle rstyle>
289 unsigned int size = val.size();
291 for(
unsigned int i = 0; i <
size; ++i)
292 res[i] = round_t<I, T, cstyle, rstyle>::round(val[i], epsilon);
296 template<
class I,
class T,
int n, CmpStyle cstyle, RoundingStyle rstyle>
302 for(
int i = 0; i < n; ++i)
303 res[i] = round_t<I, T, cstyle, rstyle>::round(val[i], epsilon);
308 template<
class I,
class T, CmpStyle cstyle, RoundingStyle rstyle>
311 return Impl::round_t<I, T, cstyle, rstyle>::round(val, epsilon);
313 template<
class I,
class T, CmpStyle cstyle>
316 return round<I, T, cstyle, defaultRoundingStyle>(val, epsilon);
318 template<
class I,
class T, RoundingStyle rstyle>
321 return round<I, T, defaultCmpStyle, rstyle>(val, epsilon);
323 template<
class I,
class T>
326 return round<I, T, defaultCmpStyle>(val, epsilon);
331 template<
class I,
class T, CmpStyle cstyle = defaultCmpStyle, RoundingStyle rstyle = defaultRoundingStyle>
333 template<
class I,
class T, CmpStyle cstyle>
334 struct trunc_t<I, T, cstyle,
downward> {
341 if(eq<T, cstyle>(val, T(0), epsilon))
return I(0);
345 if(T(lower) > val) lower--;
347 if(eq<T, cstyle>(T(lower+1), val, epsilon))
352 template<
class I,
class T, CmpStyle cstyle>
353 struct trunc_t<I, T, cstyle,
upward> {
357 I upper = trunc_t<I, T, cstyle, downward>::trunc(val, epsilon);
358 if(ne<T, cstyle>(T(upper), val, epsilon)) ++upper;
362 template<
class I,
class T, CmpStyle cstyle>
367 if(val > T(0))
return trunc_t<I, T, cstyle, downward>::trunc(val, epsilon);
368 else return trunc_t<I, T, cstyle, upward>::trunc(val, epsilon);
371 template<
class I,
class T, CmpStyle cstyle>
372 struct trunc_t<I, T, cstyle,
towardInf> {
376 if(val > T(0))
return trunc_t<I, T, cstyle, upward>::trunc(val, epsilon);
377 else return trunc_t<I, T, cstyle, downward>::trunc(val, epsilon);
380 template<
class I,
class T, CmpStyle cstyle, RoundingStyle rstyle>
387 for(
unsigned int i = 0; i <
size; ++i)
388 res[i] = trunc_t<I, T, cstyle, rstyle>::trunc(val[i], epsilon);
392 template<
class I,
class T,
int n, CmpStyle cstyle, RoundingStyle rstyle>
398 for(
int i = 0; i < n; ++i)
399 res[i] = trunc_t<I, T, cstyle, rstyle>::trunc(val[i], epsilon);
404 template<
class I,
class T, CmpStyle cstyle, RoundingStyle rstyle>
407 return Impl::trunc_t<I, T, cstyle, rstyle>::trunc(val, epsilon);
409 template<
class I,
class T, CmpStyle cstyle>
412 return trunc<I, T, cstyle, defaultRoundingStyle>(val, epsilon);
414 template<
class I,
class T, RoundingStyle rstyle>
417 return trunc<I, T, defaultCmpStyle, rstyle>(val, epsilon);
419 template<
class I,
class T>
422 return trunc<I, T, defaultCmpStyle>(val, epsilon);
427 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
432 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
439 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
443 epsilon_ = epsilon__;
447 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
451 return Dune::FloatCmp::eq<ValueType, cstyle>(first, second, epsilon_);
454 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
458 return Dune::FloatCmp::ne<ValueType, cstyle>(first, second, epsilon_);
461 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
465 return Dune::FloatCmp::gt<ValueType, cstyle>(first, second, epsilon_);
468 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
472 return Dune::FloatCmp::lt<ValueType, cstyle>(first, second, epsilon_);
475 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
479 return Dune::FloatCmp::ge<ValueType, cstyle>(first, second, epsilon_);
482 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
486 return Dune::FloatCmp::le<ValueType, cstyle>(first, second, epsilon_);
490 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
495 return Dune::FloatCmp::round<I, ValueType, cstyle, rstyle_>(val, epsilon_);
498 template<
class T, FloatCmp::CmpStyle cstyle_, FloatCmp::RoundingStyle rstyle_>
503 return Dune::FloatCmp::trunc<I, ValueType, cstyle, rstyle_>(val, epsilon_);
Various ways to compare floating-point numbers.
Implements a vector constructed from a given type representing a field and a compile-time given size.
bool ne(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test for inequality using epsilon
Definition float_cmp.cc:149
bool eq(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test for equality using epsilon
Definition float_cmp.cc:142
I round(const T &val, typename EpsilonType< T >::Type epsilon)
round using epsilon
Definition float_cmp.cc:309
I trunc(const T &val, typename EpsilonType< T >::Type epsilon)
truncate using epsilon
Definition float_cmp.cc:405
bool lt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first lesser than second
Definition float_cmp.cc:163
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition float_cmp.cc:156
bool ge(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater or equal second
Definition float_cmp.cc:170
bool le(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first lesser or equal second
Definition float_cmp.cc:177
@ relativeStrong
|a-b|/|a| <= epsilon && |a-b|/|b| <= epsilon
Definition float_cmp.hh:106
@ relativeWeak
|a-b|/|a| <= epsilon || |a-b|/|b| <= epsilon
Definition float_cmp.hh:104
@ absolute
|a-b| <= epsilon
Definition float_cmp.hh:108
@ towardZero
always round toward 0
Definition float_cmp.hh:116
@ towardInf
always round away from 0
Definition float_cmp.hh:118
@ upward
round toward
Definition float_cmp.hh:122
@ downward
round toward
Definition float_cmp.hh:120
Dune namespace.
Definition alignedallocator.hh:11
vector space out of a tensor product of fields.
Definition fvector.hh:95
Mapping of value type to epsilon type.
Definition float_cmp.cc:21
T Type
The epsilon type corresponding to value type T.
Definition float_cmp.cc:23
EpsilonType< T >::Type Type
The epsilon type corresponding to value type std::vector<T, A>
Definition float_cmp.cc:34
EpsilonType< T >::Type Type
The epsilon type corresponding to value type Dune::FieldVector<T, n>
Definition float_cmp.cc:45
static EpsilonType< T >::Type value()
Definition float_cmp.cc:51
static EpsilonType< T >::Type value()
Definition float_cmp.cc:56
static EpsilonType< T >::Type value()
Definition float_cmp.cc:61
mapping from a value type and a compare style to a default epsilon
Definition float_cmp.hh:136
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:484
FloatCmpOps(EpsilonType epsilon=DefaultEpsilon::value())
construct an operations object
Definition float_cmp.cc:429
bool eq(const ValueType &first, const ValueType &second) const
test for equality using epsilon
Definition float_cmp.cc:449
bool lt(const ValueType &first, const ValueType &second) const
test if first lesser than second
Definition float_cmp.cc:470
bool ge(const ValueType &first, const ValueType &second) const
test if first greater or equal second
Definition float_cmp.cc:477
FloatCmp::EpsilonType< T >::Type EpsilonType
Type of the epsilon.
Definition float_cmp.hh:302
bool ne(const ValueType &first, const ValueType &second) const
test for inequality using epsilon
Definition float_cmp.cc:456
T ValueType
Type of the values to compare.
Definition float_cmp.hh:297
EpsilonType epsilon() const
return the current epsilon
Definition float_cmp.cc:434
I round(const ValueType &val) const
round using epsilon
Definition float_cmp.cc:493
I trunc(const ValueType &val) const
truncate using epsilon
Definition float_cmp.cc:501
bool gt(const ValueType &first, const ValueType &second) const
test if first greater than second
Definition float_cmp.cc:463