DiagonalMatrix.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25 
26 #ifndef EIGEN_DIAGONALMATRIX_H
27 #define EIGEN_DIAGONALMATRIX_H
28 
29 namespace Eigen {
30 
31 #ifndef EIGEN_PARSED_BY_DOXYGEN
32 template<typename Derived>
33 class DiagonalBase : public EigenBase<Derived>
34 {
35  public:
36  typedef typename internal::traits<Derived>::DiagonalVectorType DiagonalVectorType;
37  typedef typename DiagonalVectorType::Scalar Scalar;
38  typedef typename internal::traits<Derived>::StorageKind StorageKind;
39  typedef typename internal::traits<Derived>::Index Index;
40 
41  enum {
42  RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
43  ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
44  MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
45  MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
46  IsVectorAtCompileTime = 0,
47  Flags = 0
48  };
49 
50  typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
51  typedef DenseMatrixType DenseType;
52  typedef DiagonalMatrix<Scalar,DiagonalVectorType::SizeAtCompileTime,DiagonalVectorType::MaxSizeAtCompileTime> PlainObject;
53 
54  inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
55  inline Derived& derived() { return *static_cast<Derived*>(this); }
56 
57  DenseMatrixType toDenseMatrix() const { return derived(); }
58  template<typename DenseDerived>
59  void evalTo(MatrixBase<DenseDerived> &other) const;
60  template<typename DenseDerived>
61  void addTo(MatrixBase<DenseDerived> &other) const
62  { other.diagonal() += diagonal(); }
63  template<typename DenseDerived>
64  void subTo(MatrixBase<DenseDerived> &other) const
65  { other.diagonal() -= diagonal(); }
66 
67  inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
68  inline DiagonalVectorType& diagonal() { return derived().diagonal(); }
69 
70  inline Index rows() const { return diagonal().size(); }
71  inline Index cols() const { return diagonal().size(); }
72 
73  template<typename MatrixDerived>
74  const DiagonalProduct<MatrixDerived, Derived, OnTheLeft>
75  operator*(const MatrixBase<MatrixDerived> &matrix) const;
76 
77  inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> >
78  inverse() const
79  {
80  return diagonal().cwiseInverse();
81  }
82 
83  #ifdef EIGEN2_SUPPORT
84  template<typename OtherDerived>
85  bool isApprox(const DiagonalBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
86  {
87  return diagonal().isApprox(other.diagonal(), precision);
88  }
89  template<typename OtherDerived>
90  bool isApprox(const MatrixBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
91  {
92  return toDenseMatrix().isApprox(other, precision);
93  }
94  #endif
95 };
96 
97 template<typename Derived>
98 template<typename DenseDerived>
99 void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
100 {
101  other.setZero();
102  other.diagonal() = diagonal();
103 }
104 #endif
105 
119 namespace internal {
120 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
121 struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
122  : traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
123 {
124  typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType;
125  typedef Dense StorageKind;
126  typedef DenseIndex Index;
127  enum {
128  Flags = LvalueBit
129  };
130 };
131 }
132 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
134  : public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
135 {
136  public:
137  #ifndef EIGEN_PARSED_BY_DOXYGEN
138  typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
139  typedef const DiagonalMatrix& Nested;
140  typedef _Scalar Scalar;
141  typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind;
142  typedef typename internal::traits<DiagonalMatrix>::Index Index;
143  #endif
144 
145  protected:
146 
147  DiagonalVectorType m_diagonal;
148 
149  public:
150 
152  inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
154  inline DiagonalVectorType& diagonal() { return m_diagonal; }
155 
157  inline DiagonalMatrix() {}
158 
160  inline DiagonalMatrix(Index dim) : m_diagonal(dim) {}
161 
163  inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
164 
166  inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
167 
169  template<typename OtherDerived>
171 
172  #ifndef EIGEN_PARSED_BY_DOXYGEN
173 
174  inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {}
175  #endif
176 
178  template<typename OtherDerived>
179  explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
180  {}
181 
183  template<typename OtherDerived>
185  {
186  m_diagonal = other.diagonal();
187  return *this;
188  }
189 
190  #ifndef EIGEN_PARSED_BY_DOXYGEN
191 
195  {
196  m_diagonal = other.diagonal();
197  return *this;
198  }
199  #endif
200 
202  inline void resize(Index size) { m_diagonal.resize(size); }
204  inline void setZero() { m_diagonal.setZero(); }
206  inline void setZero(Index size) { m_diagonal.setZero(size); }
208  inline void setIdentity() { m_diagonal.setOnes(); }
210  inline void setIdentity(Index size) { m_diagonal.setOnes(size); }
211 };
212 
227 namespace internal {
228 template<typename _DiagonalVectorType>
229 struct traits<DiagonalWrapper<_DiagonalVectorType> >
230 {
231  typedef _DiagonalVectorType DiagonalVectorType;
232  typedef typename DiagonalVectorType::Scalar Scalar;
233  typedef typename DiagonalVectorType::Index Index;
234  typedef typename DiagonalVectorType::StorageKind StorageKind;
235  enum {
236  RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
237  ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
238  MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
239  MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
241  };
242 };
243 }
244 
245 template<typename _DiagonalVectorType>
247  : public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, internal::no_assignment_operator
248 {
249  public:
250  #ifndef EIGEN_PARSED_BY_DOXYGEN
251  typedef _DiagonalVectorType DiagonalVectorType;
252  typedef DiagonalWrapper Nested;
253  #endif
254 
256  inline DiagonalWrapper(DiagonalVectorType& diagonal) : m_diagonal(diagonal) {}
257 
259  const DiagonalVectorType& diagonal() const { return m_diagonal; }
260 
261  protected:
262  typename DiagonalVectorType::Nested m_diagonal;
263 };
264 
274 template<typename Derived>
277 {
278  return derived();
279 }
280 
289 template<typename Derived>
291 {
292  if(cols() != rows()) return false;
293  RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
294  for(Index j = 0; j < cols(); ++j)
295  {
296  RealScalar absOnDiagonal = internal::abs(coeff(j,j));
297  if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
298  }
299  for(Index j = 0; j < cols(); ++j)
300  for(Index i = 0; i < j; ++i)
301  {
302  if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
303  if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
304  }
305  return true;
306 }
307 
308 } // end namespace Eigen
309 
310 #endif // EIGEN_DIAGONALMATRIX_H