mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-09-15 02:43:14 +08:00
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.
This commit is contained in:
parent
9637af5ecf
commit
910b387438
@ -39,16 +39,17 @@
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::diagonal()
|
* \sa MatrixBase::diagonal()
|
||||||
*/
|
*/
|
||||||
template<typename MatrixType>
|
template<typename MatrixType, int DiagId>
|
||||||
struct ei_traits<DiagonalCoeffs<MatrixType> >
|
struct ei_traits<DiagonalCoeffs<MatrixType,DiagId> >
|
||||||
{
|
{
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
|
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
|
||||||
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
|
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
|
||||||
enum {
|
enum {
|
||||||
|
AbsDiagId = DiagId<0 ? -DiagId : DiagId,
|
||||||
RowsAtCompileTime = int(MatrixType::SizeAtCompileTime) == Dynamic ? Dynamic
|
RowsAtCompileTime = int(MatrixType::SizeAtCompileTime) == Dynamic ? Dynamic
|
||||||
: EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime,
|
: EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime,
|
||||||
MatrixType::ColsAtCompileTime),
|
MatrixType::ColsAtCompileTime) - AbsDiagId,
|
||||||
ColsAtCompileTime = 1,
|
ColsAtCompileTime = 1,
|
||||||
MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
|
MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
|
||||||
: EIGEN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime,
|
: EIGEN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime,
|
||||||
@ -59,9 +60,14 @@ struct ei_traits<DiagonalCoeffs<MatrixType> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename MatrixType> class DiagonalCoeffs
|
template<typename MatrixType, int DiagId> class DiagonalCoeffs
|
||||||
: public MatrixBase<DiagonalCoeffs<MatrixType> >
|
: public MatrixBase<DiagonalCoeffs<MatrixType, DiagId> >
|
||||||
{
|
{
|
||||||
|
enum {
|
||||||
|
AbsDiagId = DiagId<0 ? -DiagId : DiagId,
|
||||||
|
OffsetRow = DiagId<0 ? -DiagId : 0,
|
||||||
|
OffsetCol = DiagId<0 ? 0 : DiagId
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalCoeffs)
|
EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalCoeffs)
|
||||||
@ -70,27 +76,27 @@ template<typename MatrixType> class DiagonalCoeffs
|
|||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(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 int cols() const { return 1; }
|
||||||
|
|
||||||
inline Scalar& coeffRef(int row, int)
|
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
|
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)
|
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
|
inline const Scalar coeff(int index) const
|
||||||
{
|
{
|
||||||
return m_matrix.coeff(index, index);
|
return m_matrix.coeff(index+OffsetRow, index+OffsetCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -121,4 +127,29 @@ MatrixBase<Derived>::diagonal() const
|
|||||||
return DiagonalCoeffs<Derived>(derived());
|
return DiagonalCoeffs<Derived>(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<typename Derived>
|
||||||
|
template<int Id>
|
||||||
|
inline DiagonalCoeffs<Derived,Id>
|
||||||
|
MatrixBase<Derived>::diagonal()
|
||||||
|
{
|
||||||
|
return DiagonalCoeffs<Derived,Id>(derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This is the const version of diagonal<int>(). */
|
||||||
|
template<typename Derived>
|
||||||
|
template<int Id>
|
||||||
|
inline const DiagonalCoeffs<Derived,Id>
|
||||||
|
MatrixBase<Derived>::diagonal() const
|
||||||
|
{
|
||||||
|
return DiagonalCoeffs<Derived,Id>(derived());
|
||||||
|
}
|
||||||
|
|
||||||
#endif // EIGEN_DIAGONALCOEFFS_H
|
#endif // EIGEN_DIAGONALCOEFFS_H
|
||||||
|
@ -408,6 +408,9 @@ template<typename Derived> class MatrixBase
|
|||||||
DiagonalCoeffs<Derived> diagonal();
|
DiagonalCoeffs<Derived> diagonal();
|
||||||
const DiagonalCoeffs<Derived> diagonal() const;
|
const DiagonalCoeffs<Derived> diagonal() const;
|
||||||
|
|
||||||
|
template<int Id> DiagonalCoeffs<Derived,Id> diagonal();
|
||||||
|
template<int Id> const DiagonalCoeffs<Derived,Id> diagonal() const;
|
||||||
|
|
||||||
template<unsigned int Mode> Part<Derived, Mode> part();
|
template<unsigned int Mode> Part<Derived, Mode> part();
|
||||||
template<unsigned int Mode> const Part<Derived, Mode> part() const;
|
template<unsigned int Mode> const Part<Derived, Mode> part() const;
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ template<typename Lhs, typename Rhs, int ProductMode> class Product;
|
|||||||
template<typename CoeffsVectorType, typename Derived> class DiagonalMatrixBase;
|
template<typename CoeffsVectorType, typename Derived> class DiagonalMatrixBase;
|
||||||
template<typename CoeffsVectorType> class DiagonalMatrixWrapper;
|
template<typename CoeffsVectorType> class DiagonalMatrixWrapper;
|
||||||
template<typename _Scalar, int _Size> class DiagonalMatrix;
|
template<typename _Scalar, int _Size> class DiagonalMatrix;
|
||||||
template<typename MatrixType> class DiagonalCoeffs;
|
template<typename MatrixType, int DiagId=0> class DiagonalCoeffs;
|
||||||
template<typename MatrixType, int PacketAccess = AsRequested> class Map;
|
template<typename MatrixType, int PacketAccess = AsRequested> class Map;
|
||||||
template<typename MatrixType, unsigned int Mode> class Part;
|
template<typename MatrixType, unsigned int Mode> class Part;
|
||||||
template<typename MatrixType, unsigned int Mode> class Extract;
|
template<typename MatrixType, unsigned int Mode> class Extract;
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
// because extra memory must be allocated for bookkeeping).
|
// 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
|
// 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.
|
// 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
|
#define EIGEN_ARCH_WANTS_ALIGNMENT 1
|
||||||
#else
|
#else
|
||||||
#ifdef EIGEN_VECTORIZE
|
#ifdef EIGEN_VECTORIZE
|
||||||
|
@ -138,6 +138,20 @@ template<typename MatrixType> void submatrices(const MatrixType& m)
|
|||||||
VERIFY_IS_APPROX(v1.template end<2>(), v1.template segment<2>(i));
|
VERIFY_IS_APPROX(v1.template end<2>(), v1.template segment<2>(i));
|
||||||
i = ei_random(0,rows-2);
|
i = ei_random(0,rows-2);
|
||||||
VERIFY_IS_APPROX(v1.segment(i,2), v1.template segment<2>(i));
|
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<N1>() = 2 * m1.template diagonal<N1>();
|
||||||
|
m2.template diagonal<N1>()[0] *= 3;
|
||||||
|
VERIFY_IS_APPROX(m2.template diagonal<N1>()[0], static_cast<Scalar>(6) * m1.template diagonal<N1>()[0]);
|
||||||
|
|
||||||
|
m2.template diagonal<N2>() = 2 * m1.template diagonal<N2>();
|
||||||
|
m2.template diagonal<N2>()[0] *= 3;
|
||||||
|
VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stress some basic stuffs with block matrices
|
// stress some basic stuffs with block matrices
|
||||||
|
Loading…
x
Reference in New Issue
Block a user