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