add support for read/write sub sets of inner vectors (sparse module)

This commit is contained in:
Gael Guennebaud
2009-01-27 22:48:17 +00:00
parent d384671793
commit 8ce4503494
8 changed files with 238 additions and 54 deletions

View File

@@ -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;
inline SparseInnerVector(const MatrixType& matrix, int outer)
: m_matrix(matrix), m_outer(outer)
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)
// {
// 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 SparseInnerVector<Derived> SparseMatrixBase<Derived>::innerVector(int outer) const
{ return SparseInnerVector<Derived>(derived(), outer); }
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 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>