1 #ifndef VIENNACL_LINALG_NORM_2_HPP_ 2 #define VIENNACL_LINALG_NORM_2_HPP_ 3 4 /* ========================================================================= 5 Copyright (c) 2010-2016, Institute for Microelectronics, 6 Institute for Analysis and Scientific Computing, 7 TU Wien. 8 Portions of this software are copyright by UChicago Argonne, LLC. 9 10 ----------------- 11 ViennaCL - The Vienna Computing Library 12 ----------------- 13 14 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 15 16 (A list of authors and contributors can be found in the manual) 17 18 License: MIT (X11), see file LICENSE in the base directory 19 ============================================================================= */ 20 21 /** @file norm_2.hpp 22 @brief Generic interface for the l^2-norm. See viennacl/linalg/vector_operations.hpp for implementations. 23 */ 24 25 #include <cmath> 26 #include "viennacl/forwards.h" 27 #include "viennacl/tools/tools.hpp" 28 #include "viennacl/meta/enable_if.hpp" 29 #include "viennacl/meta/tag_of.hpp" 30 31 namespace viennacl 32 { 33 // 34 // generic norm_2 function 35 // uses tag dispatch to identify which algorithm 36 // should be called 37 // 38 namespace linalg 39 { 40 #ifdef VIENNACL_WITH_MTL4 41 // ---------------------------------------------------- 42 // MTL4 43 // 44 template< typename VectorT > 45 typename viennacl::enable_if< viennacl::is_mtl4< typename viennacl::traits::tag_of< VectorT >::type >::value, 46 typename VectorT::value_type>::type norm_2(VectorT const & v)47 norm_2(VectorT const & v) 48 { 49 return mtl::two_norm(v); 50 } 51 #endif 52 53 #ifdef VIENNACL_WITH_ARMADILLO 54 // ---------------------------------------------------- 55 // Armadillo 56 // 57 template<typename NumericT> norm_2(arma::Col<NumericT> const & v)58 NumericT norm_2(arma::Col<NumericT> const& v) 59 { 60 return norm(v); 61 } 62 #endif 63 64 #ifdef VIENNACL_WITH_EIGEN 65 // ---------------------------------------------------- 66 // EIGEN 67 // 68 template< typename VectorT > 69 typename viennacl::enable_if< viennacl::is_eigen< typename viennacl::traits::tag_of< VectorT >::type >::value, 70 typename VectorT::RealScalar>::type norm_2(VectorT const & v)71 norm_2(VectorT const & v) 72 { 73 return v.norm(); 74 } 75 #endif 76 77 78 #ifdef VIENNACL_WITH_UBLAS 79 // ---------------------------------------------------- 80 // UBLAS 81 // 82 template< typename VectorT > 83 typename viennacl::enable_if< viennacl::is_ublas< typename viennacl::traits::tag_of< VectorT >::type >::value, 84 typename VectorT::value_type>::type norm_2(VectorT const & v)85 norm_2(VectorT const & v) 86 { 87 return boost::numeric::ublas::norm_2(v); 88 } 89 #endif 90 91 92 // ---------------------------------------------------- 93 // STL 94 // 95 template< typename T, typename A > 96 T norm_2(std::vector<T, A> const & v1) 97 { 98 T result = 0; 99 for (typename std::vector<T, A>::size_type i=0; i<v1.size(); ++i) 100 result += v1[i] * v1[i]; 101 102 return std::sqrt(result); 103 } 104 105 // ---------------------------------------------------- 106 // VIENNACL 107 // 108 template< typename ScalarType> 109 viennacl::scalar_expression< const viennacl::vector_base<ScalarType>, 110 const viennacl::vector_base<ScalarType>, 111 viennacl::op_norm_2 > norm_2(viennacl::vector_base<ScalarType> const & v)112 norm_2(viennacl::vector_base<ScalarType> const & v) 113 { 114 //std::cout << "viennacl .. " << std::endl; 115 return viennacl::scalar_expression< const viennacl::vector_base<ScalarType>, 116 const viennacl::vector_base<ScalarType>, 117 viennacl::op_norm_2 >(v, v); 118 } 119 120 // with vector expression: 121 template<typename LHS, typename RHS, typename OP> 122 viennacl::scalar_expression<const viennacl::vector_expression<const LHS, const RHS, OP>, 123 const viennacl::vector_expression<const LHS, const RHS, OP>, 124 viennacl::op_norm_2> norm_2(viennacl::vector_expression<const LHS,const RHS,OP> const & vector)125 norm_2(viennacl::vector_expression<const LHS, const RHS, OP> const & vector) 126 { 127 return viennacl::scalar_expression< const viennacl::vector_expression<const LHS, const RHS, OP>, 128 const viennacl::vector_expression<const LHS, const RHS, OP>, 129 viennacl::op_norm_2>(vector, vector); 130 } 131 132 133 } // end namespace linalg 134 } // end namespace viennacl 135 #endif 136 137 138 139 140 141