ViennaCL - The Vienna Computing Library  1.5.0
viennacl/linalg/inner_prod.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_INNER_PROD_HPP_
00002 #define VIENNACL_LINALG_INNER_PROD_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2013, 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 "viennacl/forwards.h"
00026 #include "viennacl/tools/tools.hpp"
00027 #include "viennacl/meta/enable_if.hpp"
00028 #include "viennacl/meta/tag_of.hpp"
00029 #include "viennacl/meta/result_of.hpp"
00030 
00031 namespace viennacl
00032 {
00033   //
00034   // generic inner_prod function
00035   //   uses tag dispatch to identify which algorithm
00036   //   should be called
00037   //
00038   namespace linalg
00039   {
00040 
00041     #ifdef VIENNACL_WITH_EIGEN
00042     // ----------------------------------------------------
00043     // EIGEN
00044     //
00045     template< typename VectorT1, typename VectorT2 >
00046     typename viennacl::enable_if< viennacl::is_eigen< typename viennacl::traits::tag_of< VectorT1 >::type >::value,
00047                                   typename VectorT1::RealScalar>::type
00048     inner_prod(VectorT1 const& v1, VectorT2 const& v2)
00049     {
00050       //std::cout << "eigen .. " << std::endl;
00051       return v1.dot(v2);
00052     }
00053     #endif
00054 
00055     #ifdef VIENNACL_WITH_MTL4
00056     // ----------------------------------------------------
00057     // MTL4
00058     //
00059     template< typename VectorT1, typename VectorT2 >
00060     typename viennacl::enable_if< viennacl::is_mtl4< typename viennacl::traits::tag_of< VectorT1 >::type >::value,
00061                                   typename VectorT1::value_type>::type
00062     inner_prod(VectorT1 const& v1, VectorT2 const& v2)
00063     {
00064       //std::cout << "mtl4 .. " << std::endl;
00065       return mtl::dot(v1, v2);
00066     }
00067     #endif
00068 
00069     #ifdef VIENNACL_WITH_UBLAS
00070     // ----------------------------------------------------
00071     // UBLAS
00072     //
00073     template< typename VectorT1, typename VectorT2 >
00074     typename viennacl::enable_if< viennacl::is_ublas< typename viennacl::traits::tag_of< VectorT1 >::type >::value,
00075                                   typename VectorT1::value_type>::type
00076     inner_prod(VectorT1 const& v1, VectorT2 const& v2)
00077     {
00078       //std::cout << "ublas .. " << std::endl;
00079       return boost::numeric::ublas::inner_prod(v1, v2);
00080     }
00081     #endif
00082 
00083     // ----------------------------------------------------
00084     // STL
00085     //
00086     template< typename VectorT1, typename VectorT2 >
00087     typename viennacl::enable_if< viennacl::is_stl< typename viennacl::traits::tag_of< VectorT1 >::type >::value,
00088                                   typename VectorT1::value_type>::type
00089     inner_prod(VectorT1 const& v1, VectorT2 const& v2)
00090     {
00091       assert(v1.size() == v2.size() && bool("Vector sizes mismatch"));
00092       //std::cout << "stl .. " << std::endl;
00093       typename VectorT1::value_type result = 0;
00094       for (typename VectorT1::size_type i=0; i<v1.size(); ++i)
00095         result += v1[i] * v2[i];
00096 
00097       return result;
00098     }
00099 
00100     // ----------------------------------------------------
00101     // VIENNACL
00102     //
00103     template< typename NumericT>
00104     viennacl::scalar_expression< const vector_base<NumericT>, const vector_base<NumericT>, viennacl::op_inner_prod >
00105     inner_prod(vector_base<NumericT> const & vector1,
00106                vector_base<NumericT> const & vector2)
00107     {
00108       //std::cout << "viennacl .. " << std::endl;
00109       return viennacl::scalar_expression< const vector_base<NumericT>,
00110                                           const vector_base<NumericT>,
00111                                           viennacl::op_inner_prod >(vector1, vector2);
00112     }
00113 
00114 
00115     // expression on lhs:
00116     template< typename LHS, typename RHS, typename OP, typename NumericT>
00117     viennacl::scalar_expression< const viennacl::vector_expression<LHS, RHS, OP>,
00118                                  const vector_base<NumericT>,
00119                                  viennacl::op_inner_prod >
00120     inner_prod(viennacl::vector_expression<LHS, RHS, OP> const & vector1,
00121                vector_base<NumericT> const & vector2)
00122     {
00123       //std::cout << "viennacl .. " << std::endl;
00124       return viennacl::scalar_expression< const viennacl::vector_expression<LHS, RHS, OP>,
00125                                           const vector_base<NumericT>,
00126                                           viennacl::op_inner_prod >(vector1, vector2);
00127     }
00128 
00129     // expression on rhs:
00130     template <typename NumericT, typename LHS, typename RHS, typename OP>
00131     viennacl::scalar_expression< const vector_base<NumericT>,
00132                                  const viennacl::vector_expression<LHS, RHS, OP>,
00133                                  viennacl::op_inner_prod >
00134     inner_prod(vector_base<NumericT> const & vector1,
00135                viennacl::vector_expression<LHS, RHS, OP> const & vector2)
00136     {
00137       //std::cout << "viennacl .. " << std::endl;
00138       return viennacl::scalar_expression< const vector_base<NumericT>,
00139                                           const viennacl::vector_expression<LHS, RHS, OP>,
00140                                           viennacl::op_inner_prod >(vector1, vector2);
00141     }
00142 
00143     // expression on lhs and rhs:
00144     template <typename LHS1, typename RHS1, typename OP1,
00145               typename LHS2, typename RHS2, typename OP2>
00146     viennacl::scalar_expression< const viennacl::vector_expression<LHS1, RHS1, OP1>,
00147                                  const viennacl::vector_expression<LHS2, RHS2, OP2>,
00148                                  viennacl::op_inner_prod >
00149     inner_prod(viennacl::vector_expression<LHS1, RHS1, OP1> const & vector1,
00150                viennacl::vector_expression<LHS2, RHS2, OP2> const & vector2)
00151     {
00152       //std::cout << "viennacl .. " << std::endl;
00153       return viennacl::scalar_expression< const viennacl::vector_expression<LHS1, RHS1, OP1>,
00154                                           const viennacl::vector_expression<LHS2, RHS2, OP2>,
00155                                           viennacl::op_inner_prod >(vector1, vector2);
00156     }
00157 
00158 
00159     // Multiple inner products:
00160     template< typename NumericT>
00161     viennacl::vector_expression< const vector_base<NumericT>, const vector_tuple<NumericT>, viennacl::op_inner_prod >
00162     inner_prod(vector_base<NumericT> const & x,
00163                vector_tuple<NumericT> const & y_tuple)
00164     {
00165       return viennacl::vector_expression< const vector_base<NumericT>,
00166                                           const vector_tuple<NumericT>,
00167                                           viennacl::op_inner_prod >(x, y_tuple);
00168     }
00169 
00170 
00171   } // end namespace linalg
00172 } // end namespace viennacl
00173 #endif
00174 
00175