ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/detail/numeric.hpp
Go to the documentation of this file.
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