diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h index e9aaa01b9..3f2608c13 100644 --- a/Eigen/src/Core/BandMatrix.h +++ b/Eigen/src/Core/BandMatrix.h @@ -27,113 +27,80 @@ namespace internal { -/** - * \class BandMatrix - * \ingroup Core_Module - * - * \brief Represents a rectangular matrix with a banded storage - * - * \param _Scalar Numeric type, i.e. float, double, int - * \param Rows Number of rows, or \b Dynamic - * \param Cols Number of columns, or \b Dynamic - * \param Supers Number of super diagonal - * \param Subs Number of sub diagonal - * \param _Options A combination of either \b RowMajor or \b ColMajor, and of \b SelfAdjoint - * The former controls storage order, and defaults to column-major. The latter controls - * whether the matrix represent a selfadjoint matrix in which case either Supers of Subs - * have to be null. - * - * \sa class TridiagonalMatrix - */ -template -struct traits > -{ - typedef _Scalar Scalar; - typedef Dense StorageKind; - typedef DenseIndex Index; - enum { - CoeffReadCost = NumTraits::ReadCost, - RowsAtCompileTime = Rows, - ColsAtCompileTime = Cols, - MaxRowsAtCompileTime = Rows, - MaxColsAtCompileTime = Cols, - Flags = LvalueBit - }; -}; - -template -class BandMatrix : public EigenBase > +template +class BandMatrixBase : public EigenBase { public: enum { - Flags = internal::traits::Flags, - CoeffReadCost = internal::traits::CoeffReadCost, - RowsAtCompileTime = internal::traits::RowsAtCompileTime, - ColsAtCompileTime = internal::traits::ColsAtCompileTime, - MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, - MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime + Flags = internal::traits::Flags, + CoeffReadCost = internal::traits::CoeffReadCost, + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + ColsAtCompileTime = internal::traits::ColsAtCompileTime, + MaxRowsAtCompileTime = internal::traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = internal::traits::MaxColsAtCompileTime, + Supers = internal::traits::Supers, + Subs = internal::traits::Subs, + Options = internal::traits::Options }; - typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::Scalar Scalar; typedef Matrix DenseMatrixType; typedef typename DenseMatrixType::Index Index; + typedef typename internal::traits::CoefficientsType CoefficientsType; + typedef EigenBase Base; protected: enum { DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic, - SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(Rows,Cols) + SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime) }; - typedef Matrix DataType; public: - - inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs) - : m_data(1+supers+subs,cols), - m_rows(rows), m_supers(supers), m_subs(subs) - { - //m_data.setConstant(666); - } - - /** \returns the number of columns */ - inline Index rows() const { return m_rows.value(); } - - /** \returns the number of rows */ - inline Index cols() const { return m_data.cols(); } + + using Base::derived; + using Base::rows; + using Base::cols; /** \returns the number of super diagonals */ - inline Index supers() const { return m_supers.value(); } + inline Index supers() const { return derived().supers(); } /** \returns the number of sub diagonals */ - inline Index subs() const { return m_subs.value(); } + inline Index subs() const { return derived().subs(); } + + /** \returns an expression of the underlying coefficient matrix */ + inline const CoefficientsType& coeffs() const { return derived().coeffs(); } + + /** \returns an expression of the underlying coefficient matrix */ + inline CoefficientsType& coeffs() { return derived().coeffs(); } /** \returns a vector expression of the \a i -th column, * only the meaningful part is returned. * \warning the internal storage must be column major. */ - inline Block col(Index i) + inline Block col(Index i) { EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); Index start = 0; - Index len = m_data.rows(); + Index len = coeffs().rows(); if (i<=supers()) { start = supers()-i; - len = std::min(rows(),std::max(0,m_data.rows() - (supers()-i))); + len = std::min(rows(),std::max(0,coeffs().rows() - (supers()-i))); } else if (i>=rows()-subs()) - len = std::max(0,m_data.rows() - (i + 1 - rows() + subs())); - return Block(m_data, start, i, len, 1); + len = std::max(0,coeffs().rows() - (i + 1 - rows() + subs())); + return Block(coeffs(), start, i, len, 1); } /** \returns a vector expression of the main diagonal */ - inline Block diagonal() - { return Block(m_data,supers(),0,1,std::min(rows(),cols())); } + inline Block diagonal() + { return Block(coeffs(),supers(),0,1,std::min(rows(),cols())); } /** \returns a vector expression of the main diagonal (const version) */ - inline const Block diagonal() const - { return Block(m_data,supers(),0,1,std::min(rows(),cols())); } + inline const Block diagonal() const + { return Block(coeffs(),supers(),0,1,std::min(rows(),cols())); } template struct DiagonalIntReturnType { enum { @@ -146,7 +113,7 @@ class BandMatrix : public EigenBase BuildType; + typedef Block BuildType; typedef typename internal::conditional,BuildType >, BuildType>::type Type; @@ -155,29 +122,29 @@ class BandMatrix : public EigenBase inline typename DiagonalIntReturnType::Type diagonal() { - return typename DiagonalIntReturnType::BuildType(m_data, supers()-N, std::max(0,N), 1, diagonalLength(N)); + return typename DiagonalIntReturnType::BuildType(coeffs(), supers()-N, std::max(0,N), 1, diagonalLength(N)); } /** \returns a vector expression of the \a N -th sub or super diagonal */ template inline const typename DiagonalIntReturnType::Type diagonal() const { - return typename DiagonalIntReturnType::BuildType(m_data, supers()-N, std::max(0,N), 1, diagonalLength(N)); + return typename DiagonalIntReturnType::BuildType(coeffs(), supers()-N, std::max(0,N), 1, diagonalLength(N)); } /** \returns a vector expression of the \a i -th sub or super diagonal */ - inline Block diagonal(Index i) + inline Block diagonal(Index i) { eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers())); - return Block(m_data, supers()-i, std::max(0,i), 1, diagonalLength(i)); + return Block(coeffs(), supers()-i, std::max(0,i), 1, diagonalLength(i)); } /** \returns a vector expression of the \a i -th sub or super diagonal */ - inline const Block diagonal(Index i) const + inline const Block diagonal(Index i) const { eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers())); - return Block(m_data, supers()-i, std::max(0,i), 1, diagonalLength(i)); + return Block(coeffs(), supers()-i, std::max(0,i), 1, diagonalLength(i)); } - + template inline void evalTo(Dest& dst) const { dst.resize(rows(),cols()); @@ -200,13 +167,148 @@ class BandMatrix : public EigenBase +struct traits > +{ + typedef _Scalar Scalar; + typedef Dense StorageKind; + typedef DenseIndex Index; + enum { + CoeffReadCost = NumTraits::ReadCost, + RowsAtCompileTime = _Rows, + ColsAtCompileTime = _Cols, + MaxRowsAtCompileTime = _Rows, + MaxColsAtCompileTime = _Cols, + Flags = LvalueBit, + Supers = _Supers, + Subs = _Subs, + Options = _Options, + DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic + }; + typedef Matrix CoefficientsType; +}; + +template +class BandMatrix : public BandMatrixBase > +{ + public: + + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::CoefficientsType CoefficientsType; + + inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs) + : m_coeffs(1+supers+subs,cols), + m_rows(rows), m_supers(supers), m_subs(subs) + { + } + + /** \returns the number of columns */ + inline Index rows() const { return m_rows.value(); } + + /** \returns the number of rows */ + inline Index cols() const { return m_coeffs.cols(); } + + /** \returns the number of super diagonals */ + inline Index supers() const { return m_supers.value(); } + + /** \returns the number of sub diagonals */ + inline Index subs() const { return m_subs.value(); } + + inline const CoefficientsType& coeffs() const { return m_coeffs; } + inline CoefficientsType& coeffs() { return m_coeffs; } + + protected: + + CoefficientsType m_coeffs; internal::variable_if_dynamic m_rows; internal::variable_if_dynamic m_supers; internal::variable_if_dynamic m_subs; }; +template +class BandMatrixWrapper; + +template +struct traits > +{ + typedef typename _CoefficientsType::Scalar Scalar; + typedef typename _CoefficientsType::StorageKind StorageKind; + typedef typename _CoefficientsType::Index Index; + enum { + CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost, + RowsAtCompileTime = _Rows, + ColsAtCompileTime = _Cols, + MaxRowsAtCompileTime = _Rows, + MaxColsAtCompileTime = _Cols, + Flags = LvalueBit, + Supers = _Supers, + Subs = _Subs, + Options = _Options, + DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic + }; + typedef _CoefficientsType CoefficientsType; +}; + +template +class BandMatrixWrapper : public BandMatrixBase > +{ + public: + + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::traits::CoefficientsType CoefficientsType; + typedef typename internal::traits::Index Index; + + inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs) + : m_coeffs(coeffs), + m_rows(rows), m_supers(supers), m_subs(subs) + { + //internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows()); + } + + /** \returns the number of columns */ + inline Index rows() const { return m_rows.value(); } + + /** \returns the number of rows */ + inline Index cols() const { return m_coeffs.cols(); } + + /** \returns the number of super diagonals */ + inline Index supers() const { return m_supers.value(); } + + /** \returns the number of sub diagonals */ + inline Index subs() const { return m_subs.value(); } + + inline const CoefficientsType& coeffs() const { return m_coeffs; } + + protected: + + const CoefficientsType& m_coeffs; + internal::variable_if_dynamic m_rows; + internal::variable_if_dynamic m_supers; + internal::variable_if_dynamic m_subs; +}; + /** * \class TridiagonalMatrix * \ingroup Core_Module