Main MRPT website > C++ reference
MRPT logo

BandMatrix.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 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_BANDMATRIX_H
00026 #define EIGEN_BANDMATRIX_H
00027 
00028 namespace internal {
00029 
00030 /**
00031   * \class BandMatrix
00032   * \ingroup Core_Module
00033   *
00034   * \brief Represents a rectangular matrix with a banded storage
00035   *
00036   * \param _Scalar Numeric type, i.e. float, double, int
00037   * \param Rows Number of rows, or \b Dynamic
00038   * \param Cols Number of columns, or \b Dynamic
00039   * \param Supers Number of super diagonal
00040   * \param Subs Number of sub diagonal
00041   * \param _Options A combination of either \b RowMajor or \b ColMajor, and of \b SelfAdjoint
00042   *                 The former controls storage order, and defaults to column-major. The latter controls
00043   *                 whether the matrix represent a selfadjoint matrix in which case either Supers of Subs
00044   *                 have to be null.
00045   *
00046   * \sa class TridiagonalMatrix
00047   */
00048 
00049 template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
00050 struct traits<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
00051 {
00052   typedef _Scalar Scalar;
00053   typedef Dense StorageKind;
00054   typedef DenseIndex Index;
00055   enum {
00056     CoeffReadCost = NumTraits<Scalar>::ReadCost,
00057     RowsAtCompileTime = Rows,
00058     ColsAtCompileTime = Cols,
00059     MaxRowsAtCompileTime = Rows,
00060     MaxColsAtCompileTime = Cols,
00061     Flags = LvalueBit
00062   };
00063 };
00064 
00065 template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
00066 class BandMatrix : public EigenBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
00067 {
00068   public:
00069 
00070     enum {
00071       Flags = internal::traits<BandMatrix>::Flags,
00072       CoeffReadCost = internal::traits<BandMatrix>::CoeffReadCost,
00073       RowsAtCompileTime = internal::traits<BandMatrix>::RowsAtCompileTime,
00074       ColsAtCompileTime = internal::traits<BandMatrix>::ColsAtCompileTime,
00075       MaxRowsAtCompileTime = internal::traits<BandMatrix>::MaxRowsAtCompileTime,
00076       MaxColsAtCompileTime = internal::traits<BandMatrix>::MaxColsAtCompileTime
00077     };
00078     typedef typename internal::traits<BandMatrix>::Scalar Scalar;
00079     typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
00080     typedef typename DenseMatrixType::Index Index;
00081 
00082   protected:
00083     enum {
00084       DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
00085                             ? 1 + Supers + Subs
00086                             : Dynamic,
00087       SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(Rows,Cols)
00088     };
00089     typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> DataType;
00090 
00091   public:
00092 
00093     inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
00094       : m_data(1+supers+subs,cols),
00095         m_rows(rows), m_supers(supers), m_subs(subs)
00096     {
00097         //m_data.setConstant(666);
00098     }
00099 
00100     /** \returns the number of columns */
00101     inline Index rows() const { return m_rows.value(); }
00102 
00103     /** \returns the number of rows */
00104     inline Index cols() const { return m_data.cols(); }
00105 
00106     /** \returns the number of super diagonals */
00107     inline Index supers() const { return m_supers.value(); }
00108 
00109     /** \returns the number of sub diagonals */
00110     inline Index subs() const { return m_subs.value(); }
00111 
00112     /** \returns a vector expression of the \a i -th column,
00113       * only the meaningful part is returned.
00114       * \warning the internal storage must be column major. */
00115     inline Block<DataType,Dynamic,1> col(Index i)
00116     {
00117       EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
00118       Index start = 0;
00119       Index len = m_data.rows();
00120       if (i<=supers())
00121       {
00122         start = supers()-i;
00123         len = std::min(rows(),std::max<Index>(0,m_data.rows() - (supers()-i)));
00124       }
00125       else if (i>=rows()-subs())
00126         len = std::max<Index>(0,m_data.rows() - (i + 1 - rows() + subs()));
00127       return Block<DataType,Dynamic,1>(m_data, start, i, len, 1);
00128     }
00129 
00130     /** \returns a vector expression of the main diagonal */
00131     inline Block<DataType,1,SizeAtCompileTime> diagonal()
00132     { return Block<DataType,1,SizeAtCompileTime>(m_data,supers(),0,1,std::min(rows(),cols())); }
00133 
00134     /** \returns a vector expression of the main diagonal (const version) */
00135     inline const Block<const DataType,1,SizeAtCompileTime> diagonal() const
00136     { return Block<const DataType,1,SizeAtCompileTime>(m_data,supers(),0,1,std::min(rows(),cols())); }
00137 
00138     template<int Index> struct DiagonalIntReturnType {
00139       enum {
00140         ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
00141         Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
00142         ActualIndex = ReturnOpposite ? -Index : Index,
00143         DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
00144                      ? Dynamic
00145                      : (ActualIndex<0
00146                      ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
00147                      : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
00148       };
00149       typedef Block<DataType,1, DiagonalSize> BuildType;
00150       typedef typename internal::conditional<Conjugate,
00151                  CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >,
00152                  BuildType>::type Type;
00153     };
00154 
00155     /** \returns a vector expression of the \a N -th sub or super diagonal */
00156     template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
00157     {
00158       return typename DiagonalIntReturnType<N>::BuildType(m_data, supers()-N, std::max(0,N), 1, diagonalLength(N));
00159     }
00160 
00161     /** \returns a vector expression of the \a N -th sub or super diagonal */
00162     template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
00163     {
00164       return typename DiagonalIntReturnType<N>::BuildType(m_data, supers()-N, std::max(0,N), 1, diagonalLength(N));
00165     }
00166 
00167     /** \returns a vector expression of the \a i -th sub or super diagonal */
00168     inline Block<DataType,1,Dynamic> diagonal(Index i)
00169     {
00170       eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
00171       return Block<DataType,1,Dynamic>(m_data, supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
00172     }
00173 
00174     /** \returns a vector expression of the \a i -th sub or super diagonal */
00175     inline const Block<const DataType,1,Dynamic> diagonal(Index i) const
00176     {
00177       eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
00178       return Block<const DataType,1,Dynamic>(m_data, supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
00179     }
00180 
00181     template<typename Dest> inline void evalTo(Dest& dst) const
00182     {
00183       dst.resize(rows(),cols());
00184       dst.setZero();
00185       dst.diagonal() = diagonal();
00186       for (Index i=1; i<=supers();++i)
00187         dst.diagonal(i) = diagonal(i);
00188       for (Index i=1; i<=subs();++i)
00189         dst.diagonal(-i) = diagonal(-i);
00190     }
00191 
00192     DenseMatrixType toDenseMatrix() const
00193     {
00194       DenseMatrixType res(rows(),cols());
00195       evalTo(res);
00196       return res;
00197     }
00198 
00199   protected:
00200 
00201     inline Index diagonalLength(Index i) const
00202     { return i<0 ? std::min(cols(),rows()+i) : std::min(rows(),cols()-i); }
00203 
00204     DataType m_data;
00205     internal::variable_if_dynamic<Index, Rows>   m_rows;
00206     internal::variable_if_dynamic<Index, Supers> m_supers;
00207     internal::variable_if_dynamic<Index, Subs>   m_subs;
00208 };
00209 
00210 /**
00211   * \class TridiagonalMatrix
00212   * \ingroup Core_Module
00213   *
00214   * \brief Represents a tridiagonal matrix with a compact banded storage
00215   *
00216   * \param _Scalar Numeric type, i.e. float, double, int
00217   * \param Size Number of rows and cols, or \b Dynamic
00218   * \param _Options Can be 0 or \b SelfAdjoint
00219   *
00220   * \sa class BandMatrix
00221   */
00222 template<typename Scalar, int Size, int Options>
00223 class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
00224 {
00225     typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
00226     typedef typename Base::Index Index;
00227   public:
00228     TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
00229 
00230     inline typename Base::template DiagonalIntReturnType<1>::Type super()
00231     { return Base::template diagonal<1>(); }
00232     inline const typename Base::template DiagonalIntReturnType<1>::Type super() const
00233     { return Base::template diagonal<1>(); }
00234     inline typename Base::template DiagonalIntReturnType<-1>::Type sub()
00235     { return Base::template diagonal<-1>(); }
00236     inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const
00237     { return Base::template diagonal<-1>(); }
00238   protected:
00239 };
00240 
00241 } // end namespace internal
00242 
00243 #endif // EIGEN_BANDMATRIX_H



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