00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef EIGEN_DIAGONALMATRIX_H
00012 #define EIGEN_DIAGONALMATRIX_H
00013
00014 namespace Eigen {
00015
00016 #ifndef EIGEN_PARSED_BY_DOXYGEN
00017 template<typename Derived>
00018 class DiagonalBase : public EigenBase<Derived>
00019 {
00020 public:
00021 typedef typename internal::traits<Derived>::DiagonalVectorType DiagonalVectorType;
00022 typedef typename DiagonalVectorType::Scalar Scalar;
00023 typedef typename DiagonalVectorType::RealScalar RealScalar;
00024 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00025 typedef typename internal::traits<Derived>::Index Index;
00026
00027 enum {
00028 RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00029 ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00030 MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
00031 MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
00032 IsVectorAtCompileTime = 0,
00033 Flags = 0
00034 };
00035
00036 typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
00037 typedef DenseMatrixType DenseType;
00038 typedef DiagonalMatrix<Scalar,DiagonalVectorType::SizeAtCompileTime,DiagonalVectorType::MaxSizeAtCompileTime> PlainObject;
00039
00040 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00041 inline Derived& derived() { return *static_cast<Derived*>(this); }
00042
00043 DenseMatrixType toDenseMatrix() const { return derived(); }
00044 template<typename DenseDerived>
00045 void evalTo(MatrixBase<DenseDerived> &other) const;
00046 template<typename DenseDerived>
00047 void addTo(MatrixBase<DenseDerived> &other) const
00048 { other.diagonal() += diagonal(); }
00049 template<typename DenseDerived>
00050 void subTo(MatrixBase<DenseDerived> &other) const
00051 { other.diagonal() -= diagonal(); }
00052
00053 inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
00054 inline DiagonalVectorType& diagonal() { return derived().diagonal(); }
00055
00056 inline Index rows() const { return diagonal().size(); }
00057 inline Index cols() const { return diagonal().size(); }
00058
00061 template<typename MatrixDerived>
00062 const DiagonalProduct<MatrixDerived, Derived, OnTheLeft>
00063 operator*(const MatrixBase<MatrixDerived> &matrix) const
00064 {
00065 return DiagonalProduct<MatrixDerived, Derived, OnTheLeft>(matrix.derived(), derived());
00066 }
00067
00068 inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> >
00069 inverse() const
00070 {
00071 return diagonal().cwiseInverse();
00072 }
00073
00074 inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> >
00075 operator*(const Scalar& scalar) const
00076 {
00077 return diagonal() * scalar;
00078 }
00079 friend inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> >
00080 operator*(const Scalar& scalar, const DiagonalBase& other)
00081 {
00082 return other.diagonal() * scalar;
00083 }
00084
00085 #ifdef EIGEN2_SUPPORT
00086 template<typename OtherDerived>
00087 bool isApprox(const DiagonalBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
00088 {
00089 return diagonal().isApprox(other.diagonal(), precision);
00090 }
00091 template<typename OtherDerived>
00092 bool isApprox(const MatrixBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
00093 {
00094 return toDenseMatrix().isApprox(other, precision);
00095 }
00096 #endif
00097 };
00098
00099 template<typename Derived>
00100 template<typename DenseDerived>
00101 void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
00102 {
00103 other.setZero();
00104 other.diagonal() = diagonal();
00105 }
00106 #endif
00107
00121 namespace internal {
00122 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
00123 struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
00124 : traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
00125 {
00126 typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType;
00127 typedef Dense StorageKind;
00128 typedef DenseIndex Index;
00129 enum {
00130 Flags = LvalueBit
00131 };
00132 };
00133 }
00134 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
00135 class DiagonalMatrix
00136 : public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
00137 {
00138 public:
00139 #ifndef EIGEN_PARSED_BY_DOXYGEN
00140 typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
00141 typedef const DiagonalMatrix& Nested;
00142 typedef _Scalar Scalar;
00143 typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind;
00144 typedef typename internal::traits<DiagonalMatrix>::Index Index;
00145 #endif
00146
00147 protected:
00148
00149 DiagonalVectorType m_diagonal;
00150
00151 public:
00152
00154 inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
00156 inline DiagonalVectorType& diagonal() { return m_diagonal; }
00157
00159 inline DiagonalMatrix() {}
00160
00162 inline DiagonalMatrix(Index dim) : m_diagonal(dim) {}
00163
00165 inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
00166
00168 inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
00169
00171 template<typename OtherDerived>
00172 inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {}
00173
00174 #ifndef EIGEN_PARSED_BY_DOXYGEN
00175
00176 inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {}
00177 #endif
00178
00180 template<typename OtherDerived>
00181 explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
00182 {}
00183
00185 template<typename OtherDerived>
00186 DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other)
00187 {
00188 m_diagonal = other.diagonal();
00189 return *this;
00190 }
00191
00192 #ifndef EIGEN_PARSED_BY_DOXYGEN
00193
00196 DiagonalMatrix& operator=(const DiagonalMatrix& other)
00197 {
00198 m_diagonal = other.diagonal();
00199 return *this;
00200 }
00201 #endif
00202
00204 inline void resize(Index size) { m_diagonal.resize(size); }
00206 inline void setZero() { m_diagonal.setZero(); }
00208 inline void setZero(Index size) { m_diagonal.setZero(size); }
00210 inline void setIdentity() { m_diagonal.setOnes(); }
00212 inline void setIdentity(Index size) { m_diagonal.setOnes(size); }
00213 };
00214
00229 namespace internal {
00230 template<typename _DiagonalVectorType>
00231 struct traits<DiagonalWrapper<_DiagonalVectorType> >
00232 {
00233 typedef _DiagonalVectorType DiagonalVectorType;
00234 typedef typename DiagonalVectorType::Scalar Scalar;
00235 typedef typename DiagonalVectorType::Index Index;
00236 typedef typename DiagonalVectorType::StorageKind StorageKind;
00237 enum {
00238 RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00239 ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00240 MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00241 MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00242 Flags = traits<DiagonalVectorType>::Flags & LvalueBit
00243 };
00244 };
00245 }
00246
00247 template<typename _DiagonalVectorType>
00248 class DiagonalWrapper
00249 : public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, internal::no_assignment_operator
00250 {
00251 public:
00252 #ifndef EIGEN_PARSED_BY_DOXYGEN
00253 typedef _DiagonalVectorType DiagonalVectorType;
00254 typedef DiagonalWrapper Nested;
00255 #endif
00256
00258 inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {}
00259
00261 const DiagonalVectorType& diagonal() const { return m_diagonal; }
00262
00263 protected:
00264 typename DiagonalVectorType::Nested m_diagonal;
00265 };
00266
00276 template<typename Derived>
00277 inline const DiagonalWrapper<const Derived>
00278 MatrixBase<Derived>::asDiagonal() const
00279 {
00280 return derived();
00281 }
00282
00291 template<typename Derived>
00292 bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const
00293 {
00294 using std::abs;
00295 if(cols() != rows()) return false;
00296 RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
00297 for(Index j = 0; j < cols(); ++j)
00298 {
00299 RealScalar absOnDiagonal = abs(coeff(j,j));
00300 if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
00301 }
00302 for(Index j = 0; j < cols(); ++j)
00303 for(Index i = 0; i < j; ++i)
00304 {
00305 if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
00306 if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
00307 }
00308 return true;
00309 }
00310
00311 }
00312
00313 #endif // EIGEN_DIAGONALMATRIX_H