soc-2008-mxcurioni: merged changes to revision 23516
[blender.git] / extern / Eigen2 / Eigen / src / Sparse / SparseDot.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_SPARSE_DOT_H
26 #define EIGEN_SPARSE_DOT_H
27
28 template<typename Derived>
29 template<typename OtherDerived>
30 typename ei_traits<Derived>::Scalar
31 SparseMatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
32 {
33   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
34   EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
35   EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
36   EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
37     YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
38
39   ei_assert(size() == other.size());
40   ei_assert(other.size()>0 && "you are using a non initialized vector");
41   
42   typename Derived::InnerIterator i(derived(),0);
43   Scalar res = 0;
44   while (i)
45   {
46     res += i.value() * ei_conj(other.coeff(i.index()));
47     ++i;
48   }
49   return res;
50 }
51
52 template<typename Derived>
53 template<typename OtherDerived>
54 typename ei_traits<Derived>::Scalar
55 SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) const
56 {
57   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
58   EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
59   EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
60   EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
61     YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
62   
63   ei_assert(size() == other.size());
64   
65   typename Derived::InnerIterator i(derived(),0);
66   typename OtherDerived::InnerIterator j(other.derived(),0);
67   Scalar res = 0;
68   while (i && j)
69   {
70     if (i.index()==j.index())
71     {
72       res += i.value() * ei_conj(j.value());
73       ++i; ++j;
74     }
75     else if (i.index()<j.index())
76       ++i;
77     else
78       ++j;
79   }
80   return res;
81 }
82
83 template<typename Derived>
84 inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real
85 SparseMatrixBase<Derived>::squaredNorm() const
86 {
87   return ei_real((*this).cwise().abs2().sum());
88 }
89
90 template<typename Derived>
91 inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real
92 SparseMatrixBase<Derived>::norm() const
93 {
94   return ei_sqrt(squaredNorm());
95 }
96
97 #endif // EIGEN_SPARSE_DOT_H