aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/SparseCore/CompressedStorage.h4
-rw-r--r--Eigen/src/SparseCore/SparseMatrix.h39
-rw-r--r--test/sparse_basic.cpp6
3 files changed, 42 insertions, 7 deletions
diff --git a/Eigen/src/SparseCore/CompressedStorage.h b/Eigen/src/SparseCore/CompressedStorage.h
index e09ad97f0..2741f8292 100644
--- a/Eigen/src/SparseCore/CompressedStorage.h
+++ b/Eigen/src/SparseCore/CompressedStorage.h
@@ -143,10 +143,10 @@ class CompressedStorage
}
/** Like at(), but the search is performed in the range [start,end) */
- inline Scalar atInRange(size_t start, size_t end, Index key, const Scalar& defaultValue = Scalar(0)) const
+ inline const Scalar& atInRange(size_t start, size_t end, Index key, const Scalar& defaultValue = Scalar(0)) const
{
if (start>=end)
- return Scalar(0);
+ return defaultValue;
else if (end>start && key==m_indices[end-1])
return m_values[end-1];
// ^^ optimization: let's first check if it is the last coefficient
diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h
index 32262d00a..b0bd8638e 100644
--- a/Eigen/src/SparseCore/SparseMatrix.h
+++ b/Eigen/src/SparseCore/SparseMatrix.h
@@ -57,7 +57,7 @@ struct traits<SparseMatrix<_Scalar, _Options, _Index> >
};
template<typename _Scalar, int _Options, typename _Index, int DiagIndex>
-struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
+struct traits<Diagonal<SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
{
typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType;
typedef typename nested<MatrixType>::type MatrixTypeNested;
@@ -73,6 +73,15 @@ struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex>
ColsAtCompileTime = 1,
MaxRowsAtCompileTime = Dynamic,
MaxColsAtCompileTime = 1,
+ Flags = LvalueBit
+ };
+};
+
+template<typename _Scalar, int _Options, typename _Index, int DiagIndex>
+struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
+ : public traits<Diagonal<SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
+{
+ enum {
Flags = 0
};
};
@@ -89,7 +98,9 @@ class SparseMatrix
EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=)
typedef MappedSparseMatrix<Scalar,Flags> Map;
- typedef Diagonal<const SparseMatrix> DiagonalReturnType;
+ typedef Diagonal<SparseMatrix> DiagonalReturnType;
+ typedef Diagonal<const SparseMatrix> ConstDiagonalReturnType;
+
using Base::IsRowMajor;
typedef internal::CompressedStorage<Scalar,Index> Storage;
@@ -168,7 +179,7 @@ class SparseMatrix
/** \returns the value of the matrix at position \a i, \a j
* This function returns Scalar(0) if the element is an explicit \em zero */
- inline Scalar coeff(Index row, Index col) const
+ inline const Scalar& coeff(Index row, Index col) const
{
eigen_assert(row>=0 && row<rows() && col>=0 && col<cols());
@@ -623,7 +634,8 @@ class SparseMatrix
}
/** \returns a const expression of the diagonal coefficients */
- const DiagonalReturnType diagonal() const { return DiagonalReturnType(*this); }
+ const ConstDiagonalReturnType diagonal() const { return ConstDiagonalReturnType(*this); }
+ DiagonalReturnType diagonal() { return DiagonalReturnType(*this); }
/** Default constructor yielding an empty \c 0 \c x \c 0 matrix */
inline SparseMatrix()
@@ -1279,7 +1291,24 @@ struct evaluator<SparseMatrix<_Scalar,_Options,_Index> >
operator SparseMatrixType&() { return m_matrix->const_cast_derived(); }
operator const SparseMatrixType&() const { return *m_matrix; }
- Scalar coeff(Index row, Index col) const { return m_matrix->coeff(row,col); }
+ typedef typename DenseCoeffsBase<SparseMatrixType,ReadOnlyAccessors>::CoeffReturnType CoeffReturnType;
+ CoeffReturnType coeff(Index row, Index col) const
+ { return m_matrix->coeff(row,col); }
+
+ Scalar& coeffRef(Index row, Index col)
+ {
+ eigen_internal_assert(row>=0 && row<m_matrix->rows() && col>=0 && col<m_matrix->cols());
+
+ const Index outer = SparseMatrixType::IsRowMajor ? row : col;
+ const Index inner = SparseMatrixType::IsRowMajor ? col : row;
+
+ Index start = m_matrix->outerIndexPtr()[outer];
+ Index end = m_matrix->isCompressed() ? m_matrix->outerIndexPtr()[outer+1] : m_matrix->outerIndexPtr()[outer] + m_matrix->innerNonZeroPtr()[outer];
+ eigen_assert(end>start && "you are using a non finalized sparse matrix or written coefficient does not exist");
+ const Index p = m_matrix->data().searchLowerIndex(start,end-1,inner);
+ eigen_assert((p<end) && (m_matrix->data().index(p)==inner) && "written coefficient does not exist");
+ return m_matrix->const_cast_derived().data().value(p);
+ }
const SparseMatrixType *m_matrix;
};
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index 2380dfa34..097959c84 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -472,6 +472,12 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
SparseMatrixType m2(rows, cols);
initSparse<Scalar>(density, refMat2, m2);
VERIFY_IS_APPROX(m2.diagonal(), refMat2.diagonal().eval());
+ VERIFY_IS_APPROX(const_cast<const SparseMatrixType&>(m2).diagonal(), refMat2.diagonal().eval());
+
+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag);
+ m2.diagonal() += refMat2.diagonal();
+ refMat2.diagonal() += refMat2.diagonal();
+ VERIFY_IS_APPROX(m2, refMat2);
}
// test conservative resize