ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ALGORITHM_NORM_HPP 00002 #define VIENNAGRID_ALGORITHM_NORM_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 <cmath> 00017 #include "viennagrid/forwards.hpp" 00018 #include "viennagrid/point.hpp" 00019 00024 namespace viennagrid 00025 { 00026 00027 namespace detail 00028 { 00029 00030 // ----------------------------------------------------------------------------- 00031 // 00032 // norm algorithm specialization hierarchy 00033 // 00034 template<typename Tag> 00035 struct norm_impl 00036 { 00037 template<typename PointT> 00038 typename viennagrid::result_of::coord<PointT>::type operator()(PointT const&) 00039 { 00040 std::cerr << "ViennaGrid - Norm Error - this error type is not implemented" << std::endl; 00041 return 0.0; 00042 } 00043 }; 00044 00046 template<> 00047 struct norm_impl<viennagrid::one_norm_tag> 00048 { 00049 template<typename PointT> 00050 typename viennagrid::result_of::coord<PointT>::type operator()(PointT const& p) 00051 { 00052 typename viennagrid::result_of::coord<PointT>::type result(0); 00053 for(std::size_t i = 0; i < dynamic_size(p); i++) 00054 result += std::abs(p[i]); 00055 return result; 00056 } 00057 }; 00058 00060 template<> 00061 struct norm_impl<viennagrid::two_norm_tag> 00062 { 00063 template<typename PointT> 00064 typename viennagrid::result_of::coord<PointT>::type operator()(PointT const& p) 00065 { 00066 typename viennagrid::result_of::coord<PointT>::type result(0); 00067 for(std::size_t i = 0; i < dynamic_size(p); i++) 00068 result += p[i]*p[i]; 00069 return std::sqrt(result); 00070 } 00071 }; 00072 00074 template<> 00075 struct norm_impl<viennagrid::inf_norm_tag> 00076 { 00077 template<typename PointT> 00078 typename viennagrid::result_of::coord<PointT>::type operator()(PointT const& p) 00079 { 00080 typename viennagrid::result_of::coord<PointT>::type result(0); 00081 for(std::size_t i = 0; i < dynamic_size(p); i++) 00082 { 00083 if(std::abs(p[i]) > result) 00084 result = std::abs(p[i]); 00085 } 00086 return result; 00087 } 00088 }; 00089 00090 } //namespace detail 00091 00093 template<typename NormTag, typename PointT, typename CoordinateSystemT> 00094 typename viennagrid::result_of::coord<PointT>::type 00095 norm_impl(PointT const & p, CoordinateSystemT const &) 00096 { 00097 return detail::norm_impl<NormTag>()(to_cartesian(p)); 00098 } 00099 00101 template<typename NormTag, typename PointT1, int d> 00102 typename viennagrid::result_of::coord<PointT1>::type 00103 norm_impl(PointT1 const & p, cartesian_cs<d>) 00104 { 00105 return detail::norm_impl<NormTag>()(p); 00106 } 00107 00108 00109 // ----------------------------------------------------------------------------- 00110 // 00111 // norm algorithm generic interface functions 00112 // 00117 template<typename PointT, typename Tag> 00118 typename viennagrid::result_of::coord<PointT>::type 00119 norm(PointT const & p, Tag) 00120 { 00121 return norm_impl<Tag>(p, typename result_of::coordinate_system<PointT>::type()); 00122 } 00123 00125 template<typename PointT> 00126 typename viennagrid::result_of::coord<PointT>::type 00127 norm(PointT const & p) 00128 { 00129 return norm_impl<viennagrid::two_norm_tag>(p, typename result_of::coordinate_system<PointT>::type()); 00130 } 00131 00132 00133 //convenience shortcuts: 00135 template<typename PointT> 00136 typename viennagrid::result_of::coord<PointT>::type 00137 norm_1(PointT const & p) 00138 { 00139 return norm_impl<viennagrid::one_norm_tag>(p, typename result_of::coordinate_system<PointT>::type()); 00140 } 00141 00143 template<typename PointT> 00144 typename viennagrid::result_of::coord<PointT>::type 00145 norm_2(PointT const & p) 00146 { 00147 return norm_impl<viennagrid::two_norm_tag>(p, typename result_of::coordinate_system<PointT>::type()); 00148 } 00149 00151 template<typename PointT> 00152 typename viennagrid::result_of::coord<PointT>::type 00153 norm_inf(PointT const & p) 00154 { 00155 return norm_impl<viennagrid::inf_norm_tag>(p, typename result_of::coordinate_system<PointT>::type()); 00156 } 00157 00158 } 00159 00160 #endif 00161