Home | History | Annotate | Download | only in SparseCore
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #ifndef EIGEN_SPARSE_DOT_H
     11 #define EIGEN_SPARSE_DOT_H
     12 
     13 namespace Eigen {
     14 
     15 template<typename Derived>
     16 template<typename OtherDerived>
     17 typename internal::traits<Derived>::Scalar
     18 SparseMatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
     19 {
     20   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
     21   EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
     22   EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
     23   EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
     24     YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
     25 
     26   eigen_assert(size() == other.size());
     27   eigen_assert(other.size()>0 && "you are using a non initialized vector");
     28 
     29   typename Derived::InnerIterator i(derived(),0);
     30   Scalar res(0);
     31   while (i)
     32   {
     33     res += internal::conj(i.value()) * other.coeff(i.index());
     34     ++i;
     35   }
     36   return res;
     37 }
     38 
     39 template<typename Derived>
     40 template<typename OtherDerived>
     41 typename internal::traits<Derived>::Scalar
     42 SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) const
     43 {
     44   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
     45   EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
     46   EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
     47   EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
     48     YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
     49 
     50   eigen_assert(size() == other.size());
     51 
     52   typedef typename Derived::Nested  Nested;
     53   typedef typename OtherDerived::Nested  OtherNested;
     54   typedef typename internal::remove_all<Nested>::type  NestedCleaned;
     55   typedef typename internal::remove_all<OtherNested>::type  OtherNestedCleaned;
     56 
     57   const Nested nthis(derived());
     58   const OtherNested nother(other.derived());
     59 
     60   typename NestedCleaned::InnerIterator i(nthis,0);
     61   typename OtherNestedCleaned::InnerIterator j(nother,0);
     62   Scalar res(0);
     63   while (i && j)
     64   {
     65     if (i.index()==j.index())
     66     {
     67       res += internal::conj(i.value()) * j.value();
     68       ++i; ++j;
     69     }
     70     else if (i.index()<j.index())
     71       ++i;
     72     else
     73       ++j;
     74   }
     75   return res;
     76 }
     77 
     78 template<typename Derived>
     79 inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
     80 SparseMatrixBase<Derived>::squaredNorm() const
     81 {
     82   return internal::real((*this).cwiseAbs2().sum());
     83 }
     84 
     85 template<typename Derived>
     86 inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
     87 SparseMatrixBase<Derived>::norm() const
     88 {
     89   return internal::sqrt(squaredNorm());
     90 }
     91 
     92 } // end namespace Eigen
     93 
     94 #endif // EIGEN_SPARSE_DOT_H
     95