Cycles: svn merge -r41225:41232 ^/trunk/blender
[blender.git] / extern / Eigen2 / Eigen / src / Core / DiagonalMatrix.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) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
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_DIAGONALMATRIX_H
26 #define EIGEN_DIAGONALMATRIX_H
27
28 /** \class DiagonalMatrix
29   * \nonstableyet 
30   *
31   * \brief Expression of a diagonal matrix
32   *
33   * \param CoeffsVectorType the type of the vector of diagonal coefficients
34   *
35   * This class is an expression of a diagonal matrix with given vector of diagonal
36   * coefficients. It is the return
37   * type of MatrixBase::diagonal(const OtherDerived&) and most of the time this is
38   * the only way it is used.
39   *
40   * \sa MatrixBase::diagonal(const OtherDerived&)
41   */
42 template<typename CoeffsVectorType>
43 struct ei_traits<DiagonalMatrix<CoeffsVectorType> >
44 {
45   typedef typename CoeffsVectorType::Scalar Scalar;
46   typedef typename ei_nested<CoeffsVectorType>::type CoeffsVectorTypeNested;
47   typedef typename ei_unref<CoeffsVectorTypeNested>::type _CoeffsVectorTypeNested;
48   enum {
49     RowsAtCompileTime = CoeffsVectorType::SizeAtCompileTime,
50     ColsAtCompileTime = CoeffsVectorType::SizeAtCompileTime,
51     MaxRowsAtCompileTime = CoeffsVectorType::MaxSizeAtCompileTime,
52     MaxColsAtCompileTime = CoeffsVectorType::MaxSizeAtCompileTime,
53     Flags = (_CoeffsVectorTypeNested::Flags & HereditaryBits) | Diagonal,
54     CoeffReadCost = _CoeffsVectorTypeNested::CoeffReadCost
55   };
56 };
57
58 template<typename CoeffsVectorType>
59 class DiagonalMatrix : ei_no_assignment_operator,
60    public MatrixBase<DiagonalMatrix<CoeffsVectorType> >
61 {
62   public:
63
64     EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrix)
65     typedef CoeffsVectorType _CoeffsVectorType;
66
67     // needed to evaluate a DiagonalMatrix<Xpr> to a DiagonalMatrix<NestByValue<Vector> >
68     template<typename OtherCoeffsVectorType>
69     inline DiagonalMatrix(const DiagonalMatrix<OtherCoeffsVectorType>& other) : m_coeffs(other.diagonal())
70     {
71       EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType);
72       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherCoeffsVectorType);
73       ei_assert(m_coeffs.size() > 0);
74     }
75
76     inline DiagonalMatrix(const CoeffsVectorType& coeffs) : m_coeffs(coeffs)
77     {
78       EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType);
79       ei_assert(coeffs.size() > 0);
80     }
81
82     inline int rows() const { return m_coeffs.size(); }
83     inline int cols() const { return m_coeffs.size(); }
84
85     inline const Scalar coeff(int row, int col) const
86     {
87       return row == col ? m_coeffs.coeff(row) : static_cast<Scalar>(0);
88     }
89
90     inline const CoeffsVectorType& diagonal() const { return m_coeffs; }
91
92   protected:
93     const typename CoeffsVectorType::Nested m_coeffs;
94 };
95
96 /** \nonstableyet 
97   * \returns an expression of a diagonal matrix with *this as vector of diagonal coefficients
98   *
99   * \only_for_vectors
100   *
101   * \addexample AsDiagonalExample \label How to build a diagonal matrix from a vector
102   *
103   * Example: \include MatrixBase_asDiagonal.cpp
104   * Output: \verbinclude MatrixBase_asDiagonal.out
105   *
106   * \sa class DiagonalMatrix, isDiagonal()
107   **/
108 template<typename Derived>
109 inline const DiagonalMatrix<Derived>
110 MatrixBase<Derived>::asDiagonal() const
111 {
112   return derived();
113 }
114
115 /** \nonstableyet 
116   * \returns true if *this is approximately equal to a diagonal matrix,
117   *          within the precision given by \a prec.
118   *
119   * Example: \include MatrixBase_isDiagonal.cpp
120   * Output: \verbinclude MatrixBase_isDiagonal.out
121   *
122   * \sa asDiagonal()
123   */
124 template<typename Derived>
125 bool MatrixBase<Derived>::isDiagonal
126 (RealScalar prec) const
127 {
128   if(cols() != rows()) return false;
129   RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
130   for(int j = 0; j < cols(); ++j)
131   {
132     RealScalar absOnDiagonal = ei_abs(coeff(j,j));
133     if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
134   }
135   for(int j = 0; j < cols(); ++j)
136     for(int i = 0; i < j; ++i)
137     {
138       if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
139       if(!ei_isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
140     }
141   return true;
142 }
143
144 #endif // EIGEN_DIAGONALMATRIX_H