mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-16 14:49:39 +08:00
bug #1359: fix compilation of col_major_sparse.row() *= scalar
(used to work in 3.2.9 though the expression is not really writable)
This commit is contained in:
parent
98d7458275
commit
e67397bfa7
@ -531,22 +531,24 @@ class unary_evaluator<Block<ArgType,BlockRows,BlockCols,InnerPanel>, IteratorBas
|
||||
enum { IsRowMajor = unary_evaluator::IsRowMajor };
|
||||
const unary_evaluator& m_eval;
|
||||
Index m_outerPos;
|
||||
Index m_innerIndex;
|
||||
Scalar m_value;
|
||||
const Index m_innerIndex;
|
||||
Index m_end;
|
||||
EvalIterator m_it;
|
||||
public:
|
||||
|
||||
EIGEN_STRONG_INLINE OuterVectorInnerIterator(const unary_evaluator& aEval, Index outer)
|
||||
: m_eval(aEval),
|
||||
m_outerPos( (IsRowMajor ? aEval.m_block.startCol() : aEval.m_block.startRow()) - 1), // -1 so that operator++ finds the first non-zero entry
|
||||
m_outerPos( (IsRowMajor ? aEval.m_block.startCol() : aEval.m_block.startRow()) ),
|
||||
m_innerIndex(IsRowMajor ? aEval.m_block.startRow() : aEval.m_block.startCol()),
|
||||
m_value(0),
|
||||
m_end(IsRowMajor ? aEval.m_block.startCol()+aEval.m_block.blockCols() : aEval.m_block.startRow()+aEval.m_block.blockRows())
|
||||
m_end(IsRowMajor ? aEval.m_block.startCol()+aEval.m_block.blockCols() : aEval.m_block.startRow()+aEval.m_block.blockRows()),
|
||||
m_it(m_eval.m_argImpl, m_outerPos)
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(outer);
|
||||
eigen_assert(outer==0);
|
||||
|
||||
++(*this);
|
||||
while(m_it && m_it.index() < m_innerIndex) ++m_it;
|
||||
if((!m_it) || (m_it.index()!=m_innerIndex))
|
||||
++(*this);
|
||||
}
|
||||
|
||||
inline StorageIndex index() const { return convert_index<StorageIndex>(m_outerPos - (IsRowMajor ? m_eval.m_block.startCol() : m_eval.m_block.startRow())); }
|
||||
@ -554,21 +556,20 @@ public:
|
||||
inline Index row() const { return IsRowMajor ? 0 : index(); }
|
||||
inline Index col() const { return IsRowMajor ? index() : 0; }
|
||||
|
||||
inline Scalar value() const { return m_value; }
|
||||
inline Scalar value() const { return m_it.value(); }
|
||||
inline Scalar& valueRef() { return m_it.valueRef(); }
|
||||
|
||||
inline OuterVectorInnerIterator& operator++()
|
||||
{
|
||||
// search next non-zero entry
|
||||
while(++m_outerPos<m_end)
|
||||
{
|
||||
EvalIterator it(m_eval.m_argImpl, m_outerPos);
|
||||
// Restart iterator at the next inner-vector:
|
||||
m_it.~EvalIterator();
|
||||
::new (&m_it) EvalIterator(m_eval.m_argImpl, m_outerPos);
|
||||
// search for the key m_innerIndex in the current outer-vector
|
||||
while(it && it.index() < m_innerIndex) ++it;
|
||||
if(it && it.index()==m_innerIndex)
|
||||
{
|
||||
m_value = it.value();
|
||||
break;
|
||||
}
|
||||
while(m_it && m_it.index() < m_innerIndex) ++m_it;
|
||||
if(m_it && m_it.index()==m_innerIndex) break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -9,6 +9,20 @@
|
||||
|
||||
#include "sparse.h"
|
||||
|
||||
template<typename T>
|
||||
typename Eigen::internal::enable_if<(T::Flags&RowMajorBit)==RowMajorBit, typename T::RowXpr>::type
|
||||
innervec(T& A, Index i)
|
||||
{
|
||||
return A.row(i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename Eigen::internal::enable_if<(T::Flags&RowMajorBit)==0, typename T::ColXpr>::type
|
||||
innervec(T& A, Index i)
|
||||
{
|
||||
return A.col(i);
|
||||
}
|
||||
|
||||
template<typename SparseMatrixType> void sparse_block(const SparseMatrixType& ref)
|
||||
{
|
||||
const Index rows = ref.rows();
|
||||
@ -20,9 +34,10 @@ template<typename SparseMatrixType> void sparse_block(const SparseMatrixType& re
|
||||
typedef typename SparseMatrixType::StorageIndex StorageIndex;
|
||||
|
||||
double density = (std::max)(8./(rows*cols), 0.01);
|
||||
typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
|
||||
typedef Matrix<Scalar,Dynamic,Dynamic,SparseMatrixType::IsRowMajor?RowMajor:ColMajor> DenseMatrix;
|
||||
typedef Matrix<Scalar,Dynamic,1> DenseVector;
|
||||
typedef Matrix<Scalar,1,Dynamic> RowDenseVector;
|
||||
typedef SparseVector<Scalar> SparseVectorType;
|
||||
|
||||
Scalar s1 = internal::random<Scalar>();
|
||||
{
|
||||
@ -110,15 +125,35 @@ template<typename SparseMatrixType> void sparse_block(const SparseMatrixType& re
|
||||
initSparse<Scalar>(density, refMat2, m2);
|
||||
Index j0 = internal::random<Index>(0,outer-1);
|
||||
Index j1 = internal::random<Index>(0,outer-1);
|
||||
if(SparseMatrixType::IsRowMajor)
|
||||
VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.row(j0));
|
||||
else
|
||||
VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));
|
||||
Index r0 = internal::random<Index>(0,rows-1);
|
||||
Index c0 = internal::random<Index>(0,cols-1);
|
||||
|
||||
if(SparseMatrixType::IsRowMajor)
|
||||
VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.row(j0)+refMat2.row(j1));
|
||||
else
|
||||
VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));
|
||||
VERIFY_IS_APPROX(m2.innerVector(j0), innervec(refMat2,j0));
|
||||
VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), innervec(refMat2,j0)+innervec(refMat2,j1));
|
||||
|
||||
m2.innerVector(j0) *= Scalar(2);
|
||||
innervec(refMat2,j0) *= Scalar(2);
|
||||
VERIFY_IS_APPROX(m2, refMat2);
|
||||
|
||||
m2.row(r0) *= Scalar(3);
|
||||
refMat2.row(r0) *= Scalar(3);
|
||||
VERIFY_IS_APPROX(m2, refMat2);
|
||||
|
||||
m2.col(c0) *= Scalar(4);
|
||||
refMat2.col(c0) *= Scalar(4);
|
||||
VERIFY_IS_APPROX(m2, refMat2);
|
||||
|
||||
m2.row(r0) /= Scalar(3);
|
||||
refMat2.row(r0) /= Scalar(3);
|
||||
VERIFY_IS_APPROX(m2, refMat2);
|
||||
|
||||
m2.col(c0) /= Scalar(4);
|
||||
refMat2.col(c0) /= Scalar(4);
|
||||
VERIFY_IS_APPROX(m2, refMat2);
|
||||
|
||||
SparseVectorType v1;
|
||||
VERIFY_IS_APPROX(v1 = m2.col(c0) * 4, refMat2.col(c0)*4);
|
||||
VERIFY_IS_APPROX(v1 = m2.row(r0) * 4, refMat2.row(r0).transpose()*4);
|
||||
|
||||
SparseMatrixType m3(rows,cols);
|
||||
m3.reserve(VectorXi::Constant(outer,int(inner/2)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user