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