ViennaCL - The Vienna Computing Library  1.5.1
viennacl/linalg/norm_2.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_NORM_2_HPP_
00002 #define VIENNACL_LINALG_NORM_2_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2014, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008    Portions of this software are copyright by UChicago Argonne, LLC.
00009 
00010                             -----------------
00011                   ViennaCL - The Vienna Computing Library
00012                             -----------------
00013 
00014    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00015 
00016    (A list of authors and contributors can be found in the PDF manual)
00017 
00018    License:         MIT (X11), see file LICENSE in the base directory
00019 ============================================================================= */
00020 
00025 #include <cmath>
00026 #include "viennacl/forwards.h"
00027 #include "viennacl/tools/tools.hpp"
00028 #include "viennacl/meta/enable_if.hpp"
00029 #include "viennacl/meta/tag_of.hpp"
00030 
00031 namespace viennacl
00032 {
00033   //
00034   // generic norm_2 function
00035   //   uses tag dispatch to identify which algorithm
00036   //   should be called
00037   //
00038   namespace linalg
00039   {
00040     #ifdef VIENNACL_WITH_MTL4
00041     // ----------------------------------------------------
00042     // MTL4
00043     //
00044     template< typename VectorT >
00045     typename viennacl::enable_if< viennacl::is_mtl4< typename viennacl::traits::tag_of< VectorT >::type >::value,
00046                                   typename VectorT::value_type>::type
00047     norm_2(VectorT const & v)
00048     {
00049       return mtl::two_norm(v);
00050     }
00051     #endif
00052 
00053 
00054     #ifdef VIENNACL_WITH_EIGEN
00055     // ----------------------------------------------------
00056     // EIGEN
00057     //
00058     template< typename VectorT >
00059     typename viennacl::enable_if< viennacl::is_eigen< typename viennacl::traits::tag_of< VectorT >::type >::value,
00060                                   typename VectorT::RealScalar>::type
00061     norm_2(VectorT const & v)
00062     {
00063       return v.norm();
00064     }
00065     #endif
00066 
00067 
00068     #ifdef VIENNACL_WITH_UBLAS
00069     // ----------------------------------------------------
00070     // UBLAS
00071     //
00072     template< typename VectorT >
00073     typename viennacl::enable_if< viennacl::is_ublas< typename viennacl::traits::tag_of< VectorT >::type >::value,
00074                                   typename VectorT::value_type>::type
00075     norm_2(VectorT const & v)
00076     {
00077       return boost::numeric::ublas::norm_2(v);
00078     }
00079     #endif
00080 
00081 
00082     // ----------------------------------------------------
00083     // STL
00084     //
00085     template< typename T, typename A >
00086     T norm_2(std::vector<T, A> const & v1)
00087     {
00088       T result = 0;
00089       for (typename std::vector<T, A>::size_type i=0; i<v1.size(); ++i)
00090         result += v1[i] * v1[i];
00091 
00092       return std::sqrt(result);
00093     }
00094 
00095     // ----------------------------------------------------
00096     // VIENNACL
00097     //
00098     template< typename ScalarType>
00099     viennacl::scalar_expression< const viennacl::vector_base<ScalarType>,
00100                                  const viennacl::vector_base<ScalarType>,
00101                                  viennacl::op_norm_2 >
00102     norm_2(viennacl::vector_base<ScalarType> const & v)
00103     {
00104        //std::cout << "viennacl .. " << std::endl;
00105       return viennacl::scalar_expression< const viennacl::vector_base<ScalarType>,
00106                                           const viennacl::vector_base<ScalarType>,
00107                                           viennacl::op_norm_2 >(v, v);
00108     }
00109 
00110     // with vector expression:
00111     template <typename LHS, typename RHS, typename OP>
00112     viennacl::scalar_expression<const viennacl::vector_expression<const LHS, const RHS, OP>,
00113                                 const viennacl::vector_expression<const LHS, const RHS, OP>,
00114                                 viennacl::op_norm_2>
00115     norm_2(viennacl::vector_expression<const LHS, const RHS, OP> const & vector)
00116     {
00117       return viennacl::scalar_expression< const viennacl::vector_expression<const LHS, const RHS, OP>,
00118                                           const viennacl::vector_expression<const LHS, const RHS, OP>,
00119                                           viennacl::op_norm_2>(vector, vector);
00120     }
00121 
00122 
00123   } // end namespace linalg
00124 } // end namespace viennacl
00125 #endif
00126 
00127 
00128 
00129 
00130