mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-14 04:35:57 +08:00
bug #980: fix taking a row (resp. column) of a column-major (resp. row-major) sparse matrix and add missing coeff/coeffRef members.
This commit is contained in:
parent
c5fc8e6bdc
commit
b09316fbea
@ -66,8 +66,9 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprTyp
|
||||
: ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
|
||||
: int(traits<XprType>::MaxColsAtCompileTime),
|
||||
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
|
||||
IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
||||
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||
IsDense = is_same<StorageKind,Dense>::value,
|
||||
IsRowMajor = (IsDense&&MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
||||
: (IsDense&&MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||
: XprTypeIsRowMajor,
|
||||
HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
|
||||
InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
||||
|
@ -57,6 +57,16 @@ public:
|
||||
inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols)
|
||||
: m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols)
|
||||
{}
|
||||
|
||||
inline const Scalar coeff(int row, int col) const
|
||||
{
|
||||
return m_matrix.coeff(row + IsRowMajor ? m_outerStart : 0, col +IsRowMajor ? 0 : m_outerStart);
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int index) const
|
||||
{
|
||||
return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
|
||||
EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
|
||||
@ -226,6 +236,21 @@ public:
|
||||
else
|
||||
return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(int row, int col)
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int row, int col) const
|
||||
{
|
||||
return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int index) const
|
||||
{
|
||||
return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
|
||||
}
|
||||
|
||||
const Scalar& lastCoeff() const
|
||||
{
|
||||
@ -313,6 +338,16 @@ public:
|
||||
else
|
||||
return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int row, int col) const
|
||||
{
|
||||
return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int index) const
|
||||
{
|
||||
return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
|
||||
}
|
||||
|
||||
const Scalar& lastCoeff() const
|
||||
{
|
||||
@ -396,8 +431,8 @@ public:
|
||||
: m_matrix(xpr),
|
||||
m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
|
||||
m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
|
||||
m_blockRows(xpr.rows()),
|
||||
m_blockCols(xpr.cols())
|
||||
m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
|
||||
m_blockCols(BlockCols==1 ? 1 : xpr.cols())
|
||||
{}
|
||||
|
||||
/** Dynamic-size constructor
|
||||
|
@ -24,6 +24,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
|
||||
double density = (std::max)(8./(rows*cols), 0.01);
|
||||
typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
|
||||
typedef Matrix<Scalar,Dynamic,1> DenseVector;
|
||||
typedef Matrix<Scalar,1,Dynamic> RowDenseVector;
|
||||
Scalar eps = 1e-6;
|
||||
|
||||
Scalar s1 = internal::random<Scalar>();
|
||||
@ -52,7 +53,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
|
||||
refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
|
||||
|
||||
VERIFY_IS_APPROX(m, refMat);
|
||||
/*
|
||||
|
||||
// test InnerIterators and Block expressions
|
||||
for (int t=0; t<10; ++t)
|
||||
{
|
||||
@ -61,23 +62,54 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
|
||||
int w = internal::random<int>(1,cols-j-1);
|
||||
int h = internal::random<int>(1,rows-i-1);
|
||||
|
||||
// VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));
|
||||
VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));
|
||||
for(int c=0; c<w; c++)
|
||||
{
|
||||
VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));
|
||||
for(int r=0; r<h; r++)
|
||||
{
|
||||
// VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));
|
||||
VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));
|
||||
VERIFY_IS_APPROX(m.block(i,j,h,w).coeff(r,c), refMat.block(i,j,h,w).coeff(r,c));
|
||||
}
|
||||
}
|
||||
// for(int r=0; r<h; r++)
|
||||
// {
|
||||
// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));
|
||||
// for(int c=0; c<w; c++)
|
||||
// {
|
||||
// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));
|
||||
// }
|
||||
// }
|
||||
for(int r=0; r<h; r++)
|
||||
{
|
||||
VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));
|
||||
for(int c=0; c<w; c++)
|
||||
{
|
||||
VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));
|
||||
VERIFY_IS_APPROX(m.block(i,j,h,w).coeff(r,c), refMat.block(i,j,h,w).coeff(r,c));
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY_IS_APPROX(m.middleCols(j,w), refMat.middleCols(j,w));
|
||||
VERIFY_IS_APPROX(m.middleRows(i,h), refMat.middleRows(i,h));
|
||||
for(int r=0; r<h; r++)
|
||||
{
|
||||
VERIFY_IS_APPROX(m.middleCols(j,w).row(r), refMat.middleCols(j,w).row(r));
|
||||
VERIFY_IS_APPROX(m.middleRows(i,h).row(r), refMat.middleRows(i,h).row(r));
|
||||
for(int c=0; c<w; c++)
|
||||
{
|
||||
VERIFY_IS_APPROX(m.col(c).coeff(r), refMat.col(c).coeff(r));
|
||||
VERIFY_IS_APPROX(m.row(r).coeff(c), refMat.row(r).coeff(c));
|
||||
|
||||
VERIFY_IS_APPROX(m.middleCols(j,w).coeff(r,c), refMat.middleCols(j,w).coeff(r,c));
|
||||
VERIFY_IS_APPROX(m.middleRows(i,h).coeff(r,c), refMat.middleRows(i,h).coeff(r,c));
|
||||
if(m.middleCols(j,w).coeff(r,c) != Scalar(0))
|
||||
{
|
||||
VERIFY_IS_APPROX(m.middleCols(j,w).coeffRef(r,c), refMat.middleCols(j,w).coeff(r,c));
|
||||
}
|
||||
if(m.middleRows(i,h).coeff(r,c) != Scalar(0))
|
||||
{
|
||||
VERIFY_IS_APPROX(m.middleRows(i,h).coeff(r,c), refMat.middleRows(i,h).coeff(r,c));
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int c=0; c<w; c++)
|
||||
{
|
||||
VERIFY_IS_APPROX(m.middleCols(j,w).col(c), refMat.middleCols(j,w).col(c));
|
||||
VERIFY_IS_APPROX(m.middleRows(i,h).col(c), refMat.middleRows(i,h).col(c));
|
||||
}
|
||||
}
|
||||
|
||||
for(int c=0; c<cols; c++)
|
||||
@ -91,7 +123,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
|
||||
VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));
|
||||
VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// test assertion
|
||||
VERIFY_RAISES_ASSERT( m.coeffRef(-1,1) = 0 );
|
||||
@ -326,6 +358,15 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
|
||||
refMat2.col(i) = refMat2.col(i) * s1;
|
||||
VERIFY_IS_APPROX(m2,refMat2);
|
||||
}
|
||||
|
||||
VERIFY_IS_APPROX(DenseVector(m2.col(j0)), refMat2.col(j0));
|
||||
VERIFY_IS_APPROX(m2.col(j0), refMat2.col(j0));
|
||||
|
||||
VERIFY_IS_APPROX(RowDenseVector(m2.row(j0)), refMat2.row(j0));
|
||||
VERIFY_IS_APPROX(m2.row(j0), refMat2.row(j0));
|
||||
|
||||
VERIFY_IS_APPROX(m2.block(j0,j1,n0,n0), refMat2.block(j0,j1,n0,n0));
|
||||
VERIFY_IS_APPROX((2*m2).block(j0,j1,n0,n0), (2*refMat2).block(j0,j1,n0,n0));
|
||||
}
|
||||
|
||||
// test prune
|
||||
|
Loading…
x
Reference in New Issue
Block a user