ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ALGORITHM_NUMERIC_HPP 00002 #define VIENNAGRID_ALGORITHM_NUMERIC_HPP 00003 00004 /* ======================================================================= 00005 Copyright (c) 2011-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaGrid - The Vienna Grid Library 00011 ----------------- 00012 00013 License: MIT (X11), see file LICENSE in the base directory 00014 ======================================================================= */ 00015 00016 #include <algorithm> 00017 #include <cmath> 00018 00023 namespace viennagrid 00024 { 00025 namespace detail 00026 { 00027 namespace result_of 00028 { 00029 template<typename NumericConfigT, typename OuterNumericT> 00030 struct numeric_type 00031 { 00032 typedef typename NumericConfigT::numeric_type type; 00033 }; 00034 00035 template<typename OuterNumericT> 00036 struct numeric_type<double, OuterNumericT> 00037 { 00038 typedef double type; 00039 }; 00040 } 00041 00042 template<typename OuterNumericT, typename NumericConfigT> 00043 typename result_of::numeric_type<NumericConfigT, OuterNumericT>::type absolute_tolerance( NumericConfigT config ) 00044 { 00045 typedef typename result_of::numeric_type<NumericConfigT, OuterNumericT>::type numeric_type; 00046 return static_cast<numeric_type>(config.eps); 00047 } 00048 00049 template<typename OuterNumericT, typename NumericConfigT> 00050 typename result_of::numeric_type<NumericConfigT, OuterNumericT>::type relative_tolerance( NumericConfigT config, OuterNumericT base ) 00051 { 00052 typedef typename result_of::numeric_type<NumericConfigT, OuterNumericT>::type numeric_type; 00053 return std::max( static_cast<numeric_type>(config.eps) * static_cast<numeric_type>(base), absolute_tolerance<OuterNumericT>(config) ); 00054 } 00055 00056 template<typename OuterNumericT> 00057 typename result_of::numeric_type<double, OuterNumericT>::type absolute_tolerance( double eps ) 00058 { 00059 typedef typename result_of::numeric_type<double, OuterNumericT>::type numeric_type; 00060 return std::abs(static_cast<numeric_type>(eps)); 00061 } 00062 00063 template<typename OuterNumericT> 00064 typename result_of::numeric_type<double, OuterNumericT>::type relative_tolerance( double eps, OuterNumericT base ) 00065 { 00066 typedef typename result_of::numeric_type<double, OuterNumericT>::type numeric_type; 00067 // return static_cast<numeric_type>(eps) * base; 00068 return std::max( static_cast<numeric_type>(eps) * base, absolute_tolerance<OuterNumericT>(eps) ); 00069 } 00070 00071 00072 template<typename NumericConfigT, typename NumericT> 00073 bool is_equal( NumericConfigT nc, NumericT first, NumericT second ) 00074 { 00075 return (std::abs(first-second) < relative_tolerance(nc, first)); 00076 } 00077 00078 template<typename NumericConfigT, typename NumericT> 00079 bool is_not_equal( NumericConfigT nc, NumericT first, NumericT second ) 00080 { 00081 return !is_equal(nc, first, second); 00082 } 00083 00084 } 00085 00086 } 00087 00088 #endif 00089