aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Core/util/StaticAssert.h3
-rw-r--r--Eigen/src/Sparse/DynamicSparseMatrix.h3
-rw-r--r--Eigen/src/Sparse/SparseBlock.h215
-rw-r--r--Eigen/src/Sparse/SparseCwiseBinaryOp.h2
-rw-r--r--Eigen/src/Sparse/SparseMatrixBase.h27
-rw-r--r--Eigen/src/Sparse/SparseUtil.h2
-rw-r--r--Eigen/src/Sparse/SparseVector.h20
-rw-r--r--test/sparse_basic.cpp18
8 files changed, 237 insertions, 53 deletions
diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h
index 60055683e..7ceeabb5f 100644
--- a/Eigen/src/Core/util/StaticAssert.h
+++ b/Eigen/src/Core/util/StaticAssert.h
@@ -73,7 +73,8 @@
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY,
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES,
THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES,
- INVALID_MATRIX_TEMPLATE_PARAMETERS
+ INVALID_MATRIX_TEMPLATE_PARAMETERS,
+ BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER
};
};
diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h
index d59b81458..74916e0ab 100644
--- a/Eigen/src/Sparse/DynamicSparseMatrix.h
+++ b/Eigen/src/Sparse/DynamicSparseMatrix.h
@@ -83,6 +83,9 @@ class DynamicSparseMatrix
inline int innerSize() const { return m_innerSize; }
inline int outerSize() const { return m_data.size(); }
inline int innerNonZeros(int j) const { return m_data[j].size(); }
+
+ std::vector<CompressedStorage<Scalar> >& _data() { return m_data; }
+ const std::vector<CompressedStorage<Scalar> >& _data() const { return m_data; }
/** \returns the coefficient value at given position \a row, \a col
* This operation involes a log(rho*outer_size) binary search.
diff --git a/Eigen/src/Sparse/SparseBlock.h b/Eigen/src/Sparse/SparseBlock.h
index cbec36e61..a90ccd812 100644
--- a/Eigen/src/Sparse/SparseBlock.h
+++ b/Eigen/src/Sparse/SparseBlock.h
@@ -26,61 +26,154 @@
#ifndef EIGEN_SPARSE_BLOCK_H
#define EIGEN_SPARSE_BLOCK_H
-template<typename MatrixType>
-struct ei_traits<SparseInnerVector<MatrixType> >
+template<typename MatrixType, int Size>
+struct ei_traits<SparseInnerVectorSet<MatrixType, Size> >
{
typedef typename ei_traits<MatrixType>::Scalar Scalar;
enum {
IsRowMajor = (int(MatrixType::Flags)&RowMajorBit)==RowMajorBit,
Flags = MatrixType::Flags,
- RowsAtCompileTime = IsRowMajor ? 1 : MatrixType::RowsAtCompileTime,
- ColsAtCompileTime = IsRowMajor ? MatrixType::ColsAtCompileTime : 1,
+ RowsAtCompileTime = IsRowMajor ? Size : MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = IsRowMajor ? MatrixType::ColsAtCompileTime : Size,
CoeffReadCost = MatrixType::CoeffReadCost
};
};
-template<typename MatrixType>
-class SparseInnerVector : ei_no_assignment_operator,
- public SparseMatrixBase<SparseInnerVector<MatrixType> >
+template<typename MatrixType, int Size>
+class SparseInnerVectorSet : ei_no_assignment_operator,
+ public SparseMatrixBase<SparseInnerVectorSet<MatrixType, Size> >
{
- enum {
- IsRowMajor = ei_traits<SparseInnerVector>::IsRowMajor
- };
-public:
+ enum { IsRowMajor = ei_traits<SparseInnerVectorSet>::IsRowMajor };
+ public:
- EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseInnerVector)
- class InnerIterator;
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseInnerVectorSet)
+ class InnerIterator: public MatrixType::InnerIterator
+ {
+ public:
+ inline InnerIterator(const SparseInnerVectorSet& xpr, int outer)
+ : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer)
+ {}
+ };
- inline SparseInnerVector(const MatrixType& matrix, int outer)
- : m_matrix(matrix), m_outer(outer)
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize)
+ : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
{
+ ei_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
+ }
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outer)
+ : m_matrix(matrix), m_outerStart(outer)
+ {
+ ei_assert(Size==1);
ei_assert( (outer>=0) && (outer<matrix.outerSize()) );
}
+
+// template<typename OtherDerived>
+// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+// {
+// return *this;
+// }
+
+// template<typename Sparse>
+// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+// {
+// return *this;
+// }
- EIGEN_STRONG_INLINE int rows() const { return IsRowMajor ? 1 : m_matrix.rows(); }
- EIGEN_STRONG_INLINE int cols() const { return IsRowMajor ? m_matrix.cols() : 1; }
+ EIGEN_STRONG_INLINE int rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
protected:
const typename MatrixType::Nested m_matrix;
- int m_outer;
+ int m_outerStart;
+ const ei_int_if_dynamic<Size> m_outerSize;
};
-template<typename MatrixType>
-class SparseInnerVector<MatrixType>::InnerIterator : public MatrixType::InnerIterator
+//----------
+// specialisation for DynamicSparseMatrix
+//----------
+
+template<typename _Scalar, int _Options, int Size>
+class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size>
+ : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size> >
{
-public:
- inline InnerIterator(const SparseInnerVector& xpr, int outer=0)
- : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outer)
- {
- ei_assert(outer==0);
- }
+ typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType;
+ enum { IsRowMajor = ei_traits<SparseInnerVectorSet>::IsRowMajor };
+ public:
+
+ EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseInnerVectorSet)
+ class InnerIterator: public MatrixType::InnerIterator
+ {
+ public:
+ inline InnerIterator(const SparseInnerVectorSet& xpr, int outer)
+ : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer)
+ {}
+ };
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize)
+ : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
+ {
+ ei_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
+ }
+
+ inline SparseInnerVectorSet(const MatrixType& matrix, int outer)
+ : m_matrix(matrix), m_outerStart(outer)
+ {
+ ei_assert(Size==1);
+ ei_assert( (outer>=0) && (outer<matrix.outerSize()) );
+ }
+
+ template<typename OtherDerived>
+ inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+ {
+ if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit))
+ {
+ // need to transpose => perform a block evaluation followed by a big swap
+ DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other);
+ *this = aux.markAsRValue();
+ }
+ else
+ {
+ // evaluate/copy vector per vector
+ for (int j=0; j<m_outerSize.value(); ++j)
+ {
+ SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j));
+ m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data());
+ }
+ }
+ return *this;
+ }
+
+ inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
+ {
+ return operator=<SparseInnerVectorSet>(other);
+ }
+
+// template<typename Sparse>
+// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+// {
+// return *this;
+// }
+
+ EIGEN_STRONG_INLINE int rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
+ EIGEN_STRONG_INLINE int cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
+
+ protected:
+
+ const typename MatrixType::Nested m_matrix;
+ int m_outerStart;
+ const ei_int_if_dynamic<Size> m_outerSize;
+
};
+
+//----------
+
/** \returns the i-th row of the matrix \c *this. For row-major matrix only. */
template<typename Derived>
-SparseInnerVector<Derived> SparseMatrixBase<Derived>::row(int i)
+SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::row(int i)
{
EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
return innerVector(i);
@@ -89,7 +182,7 @@ SparseInnerVector<Derived> SparseMatrixBase<Derived>::row(int i)
/** \returns the i-th row of the matrix \c *this. For row-major matrix only.
* (read-only version) */
template<typename Derived>
-const SparseInnerVector<Derived> SparseMatrixBase<Derived>::row(int i) const
+const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::row(int i) const
{
EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
return innerVector(i);
@@ -97,18 +190,18 @@ const SparseInnerVector<Derived> SparseMatrixBase<Derived>::row(int i) const
/** \returns the i-th column of the matrix \c *this. For column-major matrix only. */
template<typename Derived>
-SparseInnerVector<Derived> SparseMatrixBase<Derived>::col(int i)
+SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::col(int i)
{
- EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
+ EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COL_MAJOR_MATRICES);
return innerVector(i);
}
/** \returns the i-th column of the matrix \c *this. For column-major matrix only.
* (read-only version) */
template<typename Derived>
-const SparseInnerVector<Derived> SparseMatrixBase<Derived>::col(int i) const
+const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::col(int i) const
{
- EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
+ EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COL_MAJOR_MATRICES);
return innerVector(i);
}
@@ -116,15 +209,65 @@ const SparseInnerVector<Derived> SparseMatrixBase<Derived>::col(int i) const
* is col-major (resp. row-major).
*/
template<typename Derived>
-SparseInnerVector<Derived> SparseMatrixBase<Derived>::innerVector(int outer)
-{ return SparseInnerVector<Derived>(derived(), outer); }
+SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(int outer)
+{ return SparseInnerVectorSet<Derived,1>(derived(), outer); }
+
+/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
+ * is col-major (resp. row-major). Read-only.
+ */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(int outer) const
+{ return SparseInnerVectorSet<Derived,1>(derived(), outer); }
+
+//----------
+
+/** \returns the i-th row of the matrix \c *this. For row-major matrix only. */
+template<typename Derived>
+SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(int start, int size)
+{
+ EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
+ return innerVectors(start, size);
+}
+
+/** \returns the i-th row of the matrix \c *this. For row-major matrix only.
+ * (read-only version) */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(int start, int size) const
+{
+ EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
+ return innerVectors(start, size);
+}
+
+/** \returns the i-th column of the matrix \c *this. For column-major matrix only. */
+template<typename Derived>
+SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(int start, int size)
+{
+ EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COL_MAJOR_MATRICES);
+ return innerVectors(start, size);
+}
+
+/** \returns the i-th column of the matrix \c *this. For column-major matrix only.
+ * (read-only version) */
+template<typename Derived>
+const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(int start, int size) const
+{
+ EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COL_MAJOR_MATRICES);
+ return innerVectors(start, size);
+}
+
+/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
+ * is col-major (resp. row-major).
+ */
+template<typename Derived>
+SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(int outerStart, int outerSize)
+{ return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
* is col-major (resp. row-major). Read-only.
*/
template<typename Derived>
-const SparseInnerVector<Derived> SparseMatrixBase<Derived>::innerVector(int outer) const
-{ return SparseInnerVector<Derived>(derived(), outer); }
+const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(int outerStart, int outerSize) const
+{ return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
# if 0
template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess>
diff --git a/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/Eigen/src/Sparse/SparseCwiseBinaryOp.h
index 87fd429be..a061368ab 100644
--- a/Eigen/src/Sparse/SparseCwiseBinaryOp.h
+++ b/Eigen/src/Sparse/SparseCwiseBinaryOp.h
@@ -86,6 +86,8 @@ class SparseCwiseBinaryOp : ei_no_assignment_operator,
EIGEN_STRONG_INLINE SparseCwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
: m_lhs(lhs), m_rhs(rhs), m_functor(func)
{
+ EIGEN_STATIC_ASSERT((_LhsNested::Flags&RowMajorBit)==(_RhsNested::Flags&RowMajorBit),
+ BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER)
EIGEN_STATIC_ASSERT((ei_functor_allows_mixing_real_and_complex<BinaryOp>::ret
? int(ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret)
: int(ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)),
diff --git a/Eigen/src/Sparse/SparseMatrixBase.h b/Eigen/src/Sparse/SparseMatrixBase.h
index 46c0c546a..468bc9e22 100644
--- a/Eigen/src/Sparse/SparseMatrixBase.h
+++ b/Eigen/src/Sparse/SparseMatrixBase.h
@@ -327,18 +327,21 @@ template<typename Derived> class SparseMatrixBase
// void transposeInPlace();
const AdjointReturnType adjoint() const { return conjugate()/*.nestByValue()*/; }
- SparseInnerVector<Derived> row(int i);
- const SparseInnerVector<Derived> row(int i) const;
- SparseInnerVector<Derived> col(int j);
- const SparseInnerVector<Derived> col(int j) const;
- SparseInnerVector<Derived> innerVector(int outer);
- const SparseInnerVector<Derived> innerVector(int outer) const;
-
-// RowXpr row(int i);
-// const RowXpr row(int i) const;
-
-// ColXpr col(int i);
-// const ColXpr col(int i) const;
+ // sub-vector
+ SparseInnerVectorSet<Derived,1> row(int i);
+ const SparseInnerVectorSet<Derived,1> row(int i) const;
+ SparseInnerVectorSet<Derived,1> col(int j);
+ const SparseInnerVectorSet<Derived,1> col(int j) const;
+ SparseInnerVectorSet<Derived,1> innerVector(int outer);
+ const SparseInnerVectorSet<Derived,1> innerVector(int outer) const;
+
+ // set of sub-vectors
+ SparseInnerVectorSet<Derived,Dynamic> subrows(int start, int size);
+ const SparseInnerVectorSet<Derived,Dynamic> subrows(int start, int size) const;
+ SparseInnerVectorSet<Derived,Dynamic> subcols(int start, int size);
+ const SparseInnerVectorSet<Derived,Dynamic> subcols(int start, int size) const;
+ SparseInnerVectorSet<Derived,Dynamic> innerVectors(int outerStart, int outerSize);
+ const SparseInnerVectorSet<Derived,Dynamic> innerVectors(int outerStart, int outerSize) const;
// typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols);
// const typename BlockReturnType<Derived>::Type
diff --git a/Eigen/src/Sparse/SparseUtil.h b/Eigen/src/Sparse/SparseUtil.h
index 18d0ee238..0ab7dda41 100644
--- a/Eigen/src/Sparse/SparseUtil.h
+++ b/Eigen/src/Sparse/SparseUtil.h
@@ -107,7 +107,7 @@ template<typename _Scalar, int _Flags = 0> class SparseVector;
template<typename _Scalar, int _Flags = 0> class MappedSparseMatrix;
template<typename MatrixType> class SparseTranspose;
-template<typename MatrixType> class SparseInnerVector;
+template<typename MatrixType, int Size> class SparseInnerVectorSet;
template<typename Derived> class SparseCwise;
template<typename UnaryOp, typename MatrixType> class SparseCwiseUnaryOp;
template<typename BinaryOp, typename Lhs, typename Rhs> class SparseCwiseBinaryOp;
diff --git a/Eigen/src/Sparse/SparseVector.h b/Eigen/src/Sparse/SparseVector.h
index 457984cad..a5100150b 100644
--- a/Eigen/src/Sparse/SparseVector.h
+++ b/Eigen/src/Sparse/SparseVector.h
@@ -59,6 +59,7 @@ class SparseVector
EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseVector)
EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
+// EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, =)
protected:
public:
@@ -68,6 +69,9 @@ class SparseVector
CompressedStorage<Scalar> m_data;
int m_size;
+
+ CompressedStorage<Scalar>& _data() { return m_data; }
+ CompressedStorage<Scalar>& _data() const { return m_data; }
public:
@@ -198,6 +202,13 @@ class SparseVector
{
*this = other.derived();
}
+
+ template<typename OtherDerived>
+ inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
+ : m_size(0)
+ {
+ *this = other.derived();
+ }
inline SparseVector(const SparseVector& other)
: m_size(0)
@@ -225,9 +236,12 @@ class SparseVector
return *this;
}
-// template<typename OtherDerived>
-// inline SparseVector& operator=(const MatrixBase<OtherDerived>& other)
-// {
+ template<typename OtherDerived>
+ inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
+ {
+ return Base::operator=(other);
+ }
+
// const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
// if (needToTranspose)
// {
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index 439458128..08f19d7e4 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -254,6 +254,24 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
int j1 = ei_random(0,rows-1);
VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));
VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));
+ //m2.innerVector(j0) = 2*m2.innerVector(j1);
+ //refMat2.col(j0) = 2*refMat2.col(j1);
+ //VERIFY_IS_APPROX(m2, refMat2);
+ }
+
+ // test innerVectors()
+ {
+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
+ SparseMatrixType m2(rows, rows);
+ initSparse<Scalar>(density, refMat2, m2);
+ int j0 = ei_random(0,rows-2);
+ int j1 = ei_random(0,rows-2);
+ int n0 = ei_random<int>(1,rows-std::max(j0,j1));
+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));
+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
+ refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
+ //m2.innerVectors(j0,n0) = m2.innerVectors(j0,n0) + m2.innerVectors(j1,n0);
+ //refMat2.block(0,j0,rows,n0) = refMat2.block(0,j0,rows,n0) + refMat2.block(0,j1,rows,n0);
}
// test transpose