mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-02-23 18:20:47 +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()
|
||||
*/
|
||||
template<typename MatrixType>
|
||||
struct ei_traits<DiagonalCoeffs<MatrixType> >
|
||||
template<typename MatrixType, int DiagId>
|
||||
struct ei_traits<DiagonalCoeffs<MatrixType,DiagId> >
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename ei_unref<MatrixTypeNested>::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<DiagonalCoeffs<MatrixType> >
|
||||
};
|
||||
};
|
||||
|
||||
template<typename MatrixType> class DiagonalCoeffs
|
||||
: public MatrixBase<DiagonalCoeffs<MatrixType> >
|
||||
template<typename MatrixType, int DiagId> class DiagonalCoeffs
|
||||
: public MatrixBase<DiagonalCoeffs<MatrixType, DiagId> >
|
||||
{
|
||||
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<typename MatrixType> 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<Derived>::diagonal() const
|
||||
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
|
||||
|
@ -408,6 +408,9 @@ template<typename Derived> class MatrixBase
|
||||
DiagonalCoeffs<Derived> diagonal();
|
||||
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> 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> class DiagonalMatrixWrapper;
|
||||
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, unsigned int Mode> class Part;
|
||||
template<typename MatrixType, unsigned int Mode> class Extract;
|
||||
|
@ -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
|
||||
|
@ -138,6 +138,20 @@ template<typename MatrixType> 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<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
|
||||
|
Loading…
Reference in New Issue
Block a user