Main MRPT website > C++ reference
MRPT logo

DiagonalMatrix.h

Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
00006 //
00007 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
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 DiagonalMatrix<Scalar,DiagonalVectorType::SizeAtCompileTime,DiagonalVectorType::MaxSizeAtCompileTime> PlainObject;
00050 
00051     inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00052     inline Derived& derived() { return *static_cast<Derived*>(this); }
00053 
00054     DenseMatrixType toDenseMatrix() const { return derived(); }
00055     template<typename DenseDerived>
00056     void evalTo(MatrixBase<DenseDerived> &other) const;
00057     template<typename DenseDerived>
00058     void addTo(MatrixBase<DenseDerived> &other) const
00059     { other.diagonal() += diagonal(); }
00060     template<typename DenseDerived>
00061     void subTo(MatrixBase<DenseDerived> &other) const
00062     { other.diagonal() -= diagonal(); }
00063 
00064     inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
00065     inline DiagonalVectorType& diagonal() { return derived().diagonal(); }
00066 
00067     inline Index rows() const { return diagonal().size(); }
00068     inline Index cols() const { return diagonal().size(); }
00069 
00070     template<typename MatrixDerived>
00071     const DiagonalProduct<MatrixDerived, Derived, OnTheLeft>
00072     operator*(const MatrixBase<MatrixDerived> &matrix) const;
00073 
00074     inline const DiagonalWrapper<CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, DiagonalVectorType> >
00075     inverse() const
00076     {
00077       return diagonal().cwiseInverse();
00078     }
00079 };
00080 
00081 template<typename Derived>
00082 template<typename DenseDerived>
00083 void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
00084 {
00085   other.setZero();
00086   other.diagonal() = diagonal();
00087 }
00088 #endif
00089 
00090 /** \class DiagonalMatrix
00091   * \ingroup Core_Module
00092   *
00093   * \brief Represents a diagonal matrix with its storage
00094   *
00095   * \param _Scalar the type of coefficients
00096   * \param SizeAtCompileTime the dimension of the matrix, or Dynamic
00097   * \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults
00098   *        to SizeAtCompileTime. Most of the time, you do not need to specify it.
00099   *
00100   * \sa class DiagonalWrapper
00101   */
00102 
00103 namespace internal {
00104 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
00105 struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
00106  : traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
00107 {
00108   typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType;
00109   typedef Dense StorageKind;
00110   typedef DenseIndex Index;
00111   enum {
00112     Flags = LvalueBit
00113   };
00114 };
00115 }
00116 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
00117 class DiagonalMatrix
00118   : public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
00119 {
00120   public:
00121     #ifndef EIGEN_PARSED_BY_DOXYGEN
00122     typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
00123     typedef const DiagonalMatrix& Nested;
00124     typedef _Scalar Scalar;
00125     typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind;
00126     typedef typename internal::traits<DiagonalMatrix>::Index Index;
00127     #endif
00128 
00129   protected:
00130 
00131     DiagonalVectorType m_diagonal;
00132 
00133   public:
00134 
00135     /** const version of diagonal(). */
00136     inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
00137     /** \returns a reference to the stored vector of diagonal coefficients. */
00138     inline DiagonalVectorType& diagonal() { return m_diagonal; }
00139 
00140     /** Default constructor without initialization */
00141     inline DiagonalMatrix() {}
00142 
00143     /** Constructs a diagonal matrix with given dimension  */
00144     inline DiagonalMatrix(Index dim) : m_diagonal(dim) {}
00145 
00146     /** 2D constructor. */
00147     inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
00148 
00149     /** 3D constructor. */
00150     inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
00151 
00152     /** Copy constructor. */
00153     template<typename OtherDerived>
00154     inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {}
00155 
00156     #ifndef EIGEN_PARSED_BY_DOXYGEN
00157     /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
00158     inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {}
00159     #endif
00160 
00161     /** generic constructor from expression of the diagonal coefficients */
00162     template<typename OtherDerived>
00163     explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
00164     {}
00165 
00166     /** Copy operator. */
00167     template<typename OtherDerived>
00168     DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other)
00169     {
00170       m_diagonal = other.diagonal();
00171       return *this;
00172     }
00173 
00174     #ifndef EIGEN_PARSED_BY_DOXYGEN
00175     /** This is a special case of the templated operator=. Its purpose is to
00176       * prevent a default operator= from hiding the templated operator=.
00177       */
00178     DiagonalMatrix& operator=(const DiagonalMatrix& other)
00179     {
00180       m_diagonal = other.diagonal();
00181       return *this;
00182     }
00183     #endif
00184 
00185     /** Resizes to given size. */
00186     inline void resize(Index size) { m_diagonal.resize(size); }
00187     /** Sets all coefficients to zero. */
00188     inline void setZero() { m_diagonal.setZero(); }
00189     /** Resizes and sets all coefficients to zero. */
00190     inline void setZero(Index size) { m_diagonal.setZero(size); }
00191     /** Sets this matrix to be the identity matrix of the current size. */
00192     inline void setIdentity() { m_diagonal.setOnes(); }
00193     /** Sets this matrix to be the identity matrix of the given size. */
00194     inline void setIdentity(Index size) { m_diagonal.setOnes(size); }
00195 };
00196 
00197 /** \class DiagonalWrapper
00198   * \ingroup Core_Module
00199   *
00200   * \brief Expression of a diagonal matrix
00201   *
00202   * \param _DiagonalVectorType the type of the vector of diagonal coefficients
00203   *
00204   * This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients,
00205   * instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal()
00206   * and most of the time this is the only way that it is used.
00207   *
00208   * \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal()
00209   */
00210 
00211 namespace internal {
00212 template<typename _DiagonalVectorType>
00213 struct traits<DiagonalWrapper<_DiagonalVectorType> >
00214 {
00215   typedef _DiagonalVectorType DiagonalVectorType;
00216   typedef typename DiagonalVectorType::Scalar Scalar;
00217   typedef typename DiagonalVectorType::Index Index;
00218   typedef typename DiagonalVectorType::StorageKind StorageKind;
00219   enum {
00220     RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00221     ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00222     MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00223     MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
00224     Flags =  traits<DiagonalVectorType>::Flags & LvalueBit
00225   };
00226 };
00227 }
00228 
00229 template<typename _DiagonalVectorType>
00230 class DiagonalWrapper
00231   : public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, internal::no_assignment_operator
00232 {
00233   public:
00234     #ifndef EIGEN_PARSED_BY_DOXYGEN
00235     typedef _DiagonalVectorType DiagonalVectorType;
00236     typedef DiagonalWrapper Nested;
00237     #endif
00238 
00239     /** Constructor from expression of diagonal coefficients to wrap. */
00240     inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {}
00241 
00242     /** \returns a const reference to the wrapped expression of diagonal coefficients. */
00243     const DiagonalVectorType& diagonal() const { return m_diagonal; }
00244 
00245   protected:
00246     const typename DiagonalVectorType::Nested m_diagonal;
00247 };
00248 
00249 /** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
00250   *
00251   * \only_for_vectors
00252   *
00253   * Example: \include MatrixBase_asDiagonal.cpp
00254   * Output: \verbinclude MatrixBase_asDiagonal.out
00255   *
00256   * \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal()
00257   **/
00258 template<typename Derived>
00259 inline const DiagonalWrapper<Derived>
00260 MatrixBase<Derived>::asDiagonal() const
00261 {
00262   return derived();
00263 }
00264 
00265 /** \returns true if *this is approximately equal to a diagonal matrix,
00266   *          within the precision given by \a prec.
00267   *
00268   * Example: \include MatrixBase_isDiagonal.cpp
00269   * Output: \verbinclude MatrixBase_isDiagonal.out
00270   *
00271   * \sa asDiagonal()
00272   */
00273 template<typename Derived>
00274 bool MatrixBase<Derived>::isDiagonal(RealScalar prec) const
00275 {
00276   if(cols() != rows()) return false;
00277   RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
00278   for(Index j = 0; j < cols(); ++j)
00279   {
00280     RealScalar absOnDiagonal = internal::abs(coeff(j,j));
00281     if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
00282   }
00283   for(Index j = 0; j < cols(); ++j)
00284     for(Index i = 0; i < j; ++i)
00285     {
00286       if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
00287       if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
00288     }
00289   return true;
00290 }
00291 
00292 #endif // EIGEN_DIAGONALMATRIX_H



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:16:28 UTC 2011