From 910b387438bc71ab418b4fbb0a3561133a85a131 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Thu, 5 Feb 2009 18:37:21 +0000 Subject: [PATCH] Add sub/super-diagonal expression (read/write) as a trivial extension of DiagonalCoeffs. The current API is simply: m.diagonal<1>() => 1st super diagonal m.diagonal<-2>() => the 2nd sub diagonal I'll add a code snippet once we agree on this API. --- Eigen/src/Core/DiagonalCoeffs.h | 51 ++++++++++++++++++----- Eigen/src/Core/MatrixBase.h | 3 ++ Eigen/src/Core/util/ForwardDeclarations.h | 2 +- Eigen/src/Core/util/Macros.h | 2 +- test/submatrices.cpp | 14 +++++++ 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/Eigen/src/Core/DiagonalCoeffs.h b/Eigen/src/Core/DiagonalCoeffs.h index 767fe5fb7..be7df806c 100644 --- a/Eigen/src/Core/DiagonalCoeffs.h +++ b/Eigen/src/Core/DiagonalCoeffs.h @@ -39,16 +39,17 @@ * * \sa MatrixBase::diagonal() */ -template -struct ei_traits > +template +struct ei_traits > { typedef typename MatrixType::Scalar Scalar; typedef typename ei_nested::type MatrixTypeNested; typedef typename ei_unref::type _MatrixTypeNested; enum { + AbsDiagId = DiagId<0 ? -DiagId : DiagId, RowsAtCompileTime = int(MatrixType::SizeAtCompileTime) == Dynamic ? Dynamic : EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime, - MatrixType::ColsAtCompileTime), + MatrixType::ColsAtCompileTime) - AbsDiagId, ColsAtCompileTime = 1, MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic : EIGEN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime, @@ -59,9 +60,14 @@ struct ei_traits > }; }; -template class DiagonalCoeffs - : public MatrixBase > +template class DiagonalCoeffs + : public MatrixBase > { + enum { + AbsDiagId = DiagId<0 ? -DiagId : DiagId, + OffsetRow = DiagId<0 ? -DiagId : 0, + OffsetCol = DiagId<0 ? 0 : DiagId + }; public: EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalCoeffs) @@ -70,27 +76,27 @@ template class DiagonalCoeffs EIGEN_INHERIT_ASSIGNMENT_OPERATORS(DiagonalCoeffs) - inline int rows() const { return std::min(m_matrix.rows(), m_matrix.cols()); } + inline int rows() const { return std::min(m_matrix.rows(), m_matrix.cols()) - AbsDiagId; } inline int cols() const { return 1; } inline Scalar& coeffRef(int row, int) { - return m_matrix.const_cast_derived().coeffRef(row, row); + return m_matrix.const_cast_derived().coeffRef(row+OffsetRow, row+OffsetCol); } inline const Scalar coeff(int row, int) const { - return m_matrix.coeff(row, row); + return m_matrix.coeff(row+OffsetRow, row+OffsetCol); } inline Scalar& coeffRef(int index) { - return m_matrix.const_cast_derived().coeffRef(index, index); + return m_matrix.const_cast_derived().coeffRef(index+OffsetRow, index+OffsetCol); } inline const Scalar coeff(int index) const { - return m_matrix.coeff(index, index); + return m_matrix.coeff(index+OffsetRow, index+OffsetCol); } protected: @@ -121,4 +127,29 @@ MatrixBase::diagonal() const return DiagonalCoeffs(derived()); } +/** \returns an expression of the \a Id-th sub or super diagonal of the matrix \c *this + * + * \c *this is not required to be square. + * + * The template parameter \a Id represent a super diagonal if \a Id > 0 + * and a sub diagonal otherwise. \a Id == 0 is equivalent to the main diagonal. + * + * \sa class DiagonalCoeffs */ +template +template +inline DiagonalCoeffs +MatrixBase::diagonal() +{ + return DiagonalCoeffs(derived()); +} + +/** This is the const version of diagonal(). */ +template +template +inline const DiagonalCoeffs +MatrixBase::diagonal() const +{ + return DiagonalCoeffs(derived()); +} + #endif // EIGEN_DIAGONALCOEFFS_H diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 6b7b002f0..5abf35f5f 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -408,6 +408,9 @@ template class MatrixBase DiagonalCoeffs diagonal(); const DiagonalCoeffs diagonal() const; + template DiagonalCoeffs diagonal(); + template const DiagonalCoeffs diagonal() const; + template Part part(); template const Part part() const; diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 83c42442b..90e2af68d 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -48,7 +48,7 @@ template class Product; template class DiagonalMatrixBase; template class DiagonalMatrixWrapper; template class DiagonalMatrix; -template class DiagonalCoeffs; +template class DiagonalCoeffs; template class Map; template class Part; template class Extract; diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index 795efb90c..fb0994c76 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -41,7 +41,7 @@ // because extra memory must be allocated for bookkeeping). // if the compiler is not GNUC, just cross fingers that the architecture isn't too exotic, because we don't want // to keep track of all the different preprocessor symbols for all compilers. -#if !defined(__GNUC__) || defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ia64__) +#if (!defined(__GNUC__)) || defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ia64__) #define EIGEN_ARCH_WANTS_ALIGNMENT 1 #else #ifdef EIGEN_VECTORIZE diff --git a/test/submatrices.cpp b/test/submatrices.cpp index 63c61baca..e34650842 100644 --- a/test/submatrices.cpp +++ b/test/submatrices.cpp @@ -138,6 +138,20 @@ template void submatrices(const MatrixType& m) VERIFY_IS_APPROX(v1.template end<2>(), v1.template segment<2>(i)); i = ei_random(0,rows-2); VERIFY_IS_APPROX(v1.segment(i,2), v1.template segment<2>(i)); + + enum { + N1 = MatrixType::RowsAtCompileTime>1 ? 1 : 0, + N2 = MatrixType::RowsAtCompileTime>2 ? -2 : 0 + }; + + // check sub/super diagonal + m2.template diagonal() = 2 * m1.template diagonal(); + m2.template diagonal()[0] *= 3; + VERIFY_IS_APPROX(m2.template diagonal()[0], static_cast(6) * m1.template diagonal()[0]); + + m2.template diagonal() = 2 * m1.template diagonal(); + m2.template diagonal()[0] *= 3; + VERIFY_IS_APPROX(m2.template diagonal()[0], static_cast(6) * m1.template diagonal()[0]); } // stress some basic stuffs with block matrices