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