00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // Eigen is free software; you can redistribute it and/or 00007 // modify it under the terms of the GNU Lesser General Public 00008 // License as published by the Free Software Foundation; either 00009 // version 3 of the License, or (at your option) any later version. 00010 // 00011 // Alternatively, you can redistribute it and/or 00012 // modify it under the terms of the GNU General Public License as 00013 // published by the Free Software Foundation; either version 2 of 00014 // the License, or (at your option) any later version. 00015 // 00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY 00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the 00019 // GNU General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License and a copy of the GNU General Public License along with 00023 // Eigen. If not, see <http://www.gnu.org/licenses/>. 00024 00025 #ifndef EIGEN_SPARSE_DOT_H 00026 #define EIGEN_SPARSE_DOT_H 00027 00028 template<typename Derived> 00029 template<typename OtherDerived> 00030 typename internal::traits<Derived>::Scalar 00031 SparseMatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const 00032 { 00033 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 00034 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) 00035 EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) 00036 EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), 00037 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) 00038 00039 eigen_assert(size() == other.size()); 00040 eigen_assert(other.size()>0 && "you are using a non initialized vector"); 00041 00042 typename Derived::InnerIterator i(derived(),0); 00043 Scalar res = 0; 00044 while (i) 00045 { 00046 res += internal::conj(i.value()) * other.coeff(i.index()); 00047 ++i; 00048 } 00049 return res; 00050 } 00051 00052 template<typename Derived> 00053 template<typename OtherDerived> 00054 typename internal::traits<Derived>::Scalar 00055 SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) const 00056 { 00057 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 00058 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) 00059 EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) 00060 EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), 00061 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) 00062 00063 eigen_assert(size() == other.size()); 00064 00065 typename Derived::InnerIterator i(derived(),0); 00066 typename OtherDerived::InnerIterator j(other.derived(),0); 00067 Scalar res = 0; 00068 while (i && j) 00069 { 00070 if (i.index()==j.index()) 00071 { 00072 res += internal::conj(i.value()) * j.value(); 00073 ++i; ++j; 00074 } 00075 else if (i.index()<j.index()) 00076 ++i; 00077 else 00078 ++j; 00079 } 00080 return res; 00081 } 00082 00083 template<typename Derived> 00084 inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real 00085 SparseMatrixBase<Derived>::squaredNorm() const 00086 { 00087 return internal::real((*this).cwiseAbs2().sum()); 00088 } 00089 00090 template<typename Derived> 00091 inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real 00092 SparseMatrixBase<Derived>::norm() const 00093 { 00094 return internal::sqrt(squaredNorm()); 00095 } 00096 00097 #endif // EIGEN_SPARSE_DOT_H