clean the ambiguity with insertBack and add a insertBackByOuterInner function

This commit is contained in:
Gael Guennebaud
2010-06-02 13:32:13 +02:00
parent 143e6ab9d0
commit 8710bd23e7
10 changed files with 205 additions and 146 deletions

View File

@@ -128,6 +128,7 @@ class SparseLLT<MatrixType,Cholmod> : public SparseLLT<MatrixType>
typedef typename Base::Scalar Scalar;
typedef typename Base::RealScalar RealScalar;
typedef typename Base::CholMatrixType CholMatrixType;
typedef typename MatrixType::Index Index;
using Base::MatrixLIsDirty;
using Base::SupernodalFactorIsDirty;
using Base::m_flags;

View File

@@ -127,13 +127,7 @@ class DynamicSparseMatrix
return res;
}
/** \deprecated
* Set the matrix to zero and reserve the memory for \a reserveSize nonzero coefficients. */
EIGEN_DEPRECATED void startFill(Index reserveSize = 1000)
{
setZero();
reserve(reserveSize);
}
void reserve(Index reserveSize = 1000)
{
@@ -147,9 +141,21 @@ class DynamicSparseMatrix
}
}
/** Does nothing: provided for compatibility with SparseMatrix */
inline void startVec(Index /*outer*/) {}
inline Scalar& insertBack(Index outer, Index inner)
/** \returns a reference to the non zero coefficient at position \a row, \a col assuming that:
* - the nonzero does not already exist
* - the new coefficient is the last one of the given inner vector.
*
* \sa insert, insertBackByInnerOuter */
inline Scalar& insertBack(Index row, Index col)
{
return insertBackByInnerOuter(IsRowMajor?row:col, IsRowMajor?col:row);
}
/** \sa insertBack */
inline Scalar& insertBackByOuterInner(Index outer, Index inner)
{
ei_assert(outer<Index(m_data.size()) && inner<m_innerSize && "out of range");
ei_assert(((m_data[outer].size()==0) || (m_data[outer].index(m_data[outer].size()-1)<inner))
@@ -158,32 +164,6 @@ class DynamicSparseMatrix
return m_data[outer].value(m_data[outer].size()-1);
}
/** \deprecated use insert()
* inserts a nonzero coefficient at given coordinates \a row, \a col and returns its reference assuming that:
* 1 - the coefficient does not exist yet
* 2 - this the coefficient with greater inner coordinate for the given outer coordinate.
* In other words, assuming \c *this is column-major, then there must not exists any nonzero coefficient of coordinates
* \c i \c x \a col such that \c i >= \a row. Otherwise the matrix is invalid.
*
* \see fillrand(), coeffRef()
*/
EIGEN_DEPRECATED Scalar& fill(Index row, Index col)
{
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
return insertBack(outer,inner);
}
/** \deprecated use insert()
* Like fill() but with random inner coordinates.
* Compared to the generic coeffRef(), the unique limitation is that we assume
* the coefficient does not exist yet.
*/
EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col)
{
return insert(row,col);
}
inline Scalar& insert(Index row, Index col)
{
const Index outer = IsRowMajor ? row : col;
@@ -204,12 +184,10 @@ class DynamicSparseMatrix
return m_data[outer].value(id+1);
}
/** \deprecated use finalize()
* Does nothing. Provided for compatibility with SparseMatrix. */
EIGEN_DEPRECATED void endFill() {}
/** Does nothing: provided for compatibility with SparseMatrix */
inline void finalize() {}
/** Suppress all nonzeros which are smaller than \a reference under the tolerence \a epsilon */
void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
{
for (Index j=0; j<outerSize(); ++j)
@@ -301,6 +279,46 @@ class DynamicSparseMatrix
/** Destructor */
inline ~DynamicSparseMatrix() {}
public:
/** \deprecated
* Set the matrix to zero and reserve the memory for \a reserveSize nonzero coefficients. */
EIGEN_DEPRECATED void startFill(Index reserveSize = 1000)
{
setZero();
reserve(reserveSize);
}
/** \deprecated use insert()
* inserts a nonzero coefficient at given coordinates \a row, \a col and returns its reference assuming that:
* 1 - the coefficient does not exist yet
* 2 - this the coefficient with greater inner coordinate for the given outer coordinate.
* In other words, assuming \c *this is column-major, then there must not exists any nonzero coefficient of coordinates
* \c i \c x \a col such that \c i >= \a row. Otherwise the matrix is invalid.
*
* \see fillrand(), coeffRef()
*/
EIGEN_DEPRECATED Scalar& fill(Index row, Index col)
{
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
return insertBack(outer,inner);
}
/** \deprecated use insert()
* Like fill() but with random inner coordinates.
* Compared to the generic coeffRef(), the unique limitation is that we assume
* the coefficient does not exist yet.
*/
EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col)
{
return insert(row,col);
}
/** \deprecated use finalize()
* Does nothing. Provided for compatibility with SparseMatrix. */
EIGEN_DEPRECATED void endFill() {}
};
template<typename Scalar, int _Flags>

View File

@@ -243,7 +243,7 @@ class RandomSetter
mp_target->startVec(j);
prevOuter = outer;
}
mp_target->insertBack(outer, inner) = it->second.value;
mp_target->insertBackByOuterInner(outer, inner) = it->second.value;
}
}
mp_target->finalize();

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -135,67 +135,41 @@ class SparseMatrix
/** \returns the number of non zero coefficients */
inline Index nonZeros() const { return static_cast<Index>(m_data.size()); }
/** \deprecated use setZero() and reserve()
* Initializes the filling process of \c *this.
* \param reserveSize approximate number of nonzeros
* Note that the matrix \c *this is zero-ed.
*/
EIGEN_DEPRECATED void startFill(Index reserveSize = 1000)
{
setZero();
m_data.reserve(reserveSize);
}
/** Preallocates \a reserveSize non zeros */
inline void reserve(Index reserveSize)
{
m_data.reserve(reserveSize);
}
/** \deprecated use insert()
*/
EIGEN_DEPRECATED Scalar& fill(Index row, Index col)
{
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
if (m_outerIndex[outer+1]==0)
{
// we start a new inner vector
Index i = outer;
while (i>=0 && m_outerIndex[i]==0)
{
m_outerIndex[i] = m_data.size();
--i;
}
m_outerIndex[outer+1] = m_outerIndex[outer];
}
else
{
ei_assert(m_data.index(m_data.size()-1)<inner && "wrong sorted insertion");
}
// std::cerr << size_t(m_outerIndex[outer+1]) << " == " << m_data.size() << "\n";
assert(size_t(m_outerIndex[outer+1]) == m_data.size());
Index id = m_outerIndex[outer+1];
++m_outerIndex[outer+1];
m_data.append(0, inner);
return m_data.value(id);
}
//--- low level purely coherent filling ---
inline Scalar& insertBack(Index outer, Index inner)
/** \returns a reference to the non zero coefficient at position \a row, \a col assuming that:
* - the nonzero does not already exist
* - the new coefficient is the last one according to the storage order
*
* Before filling a given inner vector you must call the statVec(Index) function.
*
* After an insertion session, you should call the finalize() function.
*
* \sa insert, insertBackByInnerOuter, startVec */
inline Scalar& insertBack(Index row, Index col)
{
ei_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "wrong sorted insertion");
ei_assert( (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)<inner) && "wrong sorted insertion");
return insertBackByInnerOuter(IsRowMajor?row:col, IsRowMajor?col:row);
}
/** \sa insertBack, startVec */
inline Scalar& insertBackByOuterInner(Index outer, Index inner)
{
ei_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "Invalid ordered insertion (invalid outer index)");
ei_assert( (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)<inner) && "Invalid ordered insertion (invalid inner index)");
Index id = m_outerIndex[outer+1];
++m_outerIndex[outer+1];
m_data.append(0, inner);
return m_data.value(id);
}
inline Scalar& insertBackNoCheck(Index outer, Index inner)
/** \warning use it only if you know what you are doing */
inline Scalar& insertBackByInnerOuterUnordered(Index outer, Index inner)
{
Index id = m_outerIndex[outer+1];
++m_outerIndex[outer+1];
@@ -203,23 +177,16 @@ class SparseMatrix
return m_data.value(id);
}
/** \sa insertBack, insertBackByInnerOuter */
inline void startVec(Index outer)
{
ei_assert(m_outerIndex[outer]==int(m_data.size()) && "you must call startVec on each inner vec");
ei_assert(m_outerIndex[outer+1]==0 && "you must call startVec on each inner vec");
ei_assert(m_outerIndex[outer]==int(m_data.size()) && "You must call startVec for each inner vector sequentially");
ei_assert(m_outerIndex[outer+1]==0 && "You must call startVec for each inner vector sequentially");
m_outerIndex[outer+1] = m_outerIndex[outer];
}
//---
/** \deprecated use insert()
* Like fill() but with random inner coordinates.
*/
EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col)
{
return insert(row,col);
}
/** \returns a reference to a novel non zero coefficient with coordinates \a row x \a col.
* The non zero coefficient must \b not already exist.
*
@@ -332,7 +299,8 @@ class SparseMatrix
return (m_data.value(id) = 0);
}
EIGEN_DEPRECATED void endFill() { finalize(); }
/** Must be called after inserting a set of non zero entries.
*/
@@ -351,6 +319,7 @@ class SparseMatrix
}
}
/** Suppress all nonzeros which are smaller than \a reference under the tolerence \a epsilon */
void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
{
Index k = 0;
@@ -389,23 +358,29 @@ class SparseMatrix
}
memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index));
}
/** Low level API
* Resize the nonzero vector to \a size */
void resizeNonZeros(Index size)
{
m_data.resize(size);
}
/** Default constructor yielding an empty \c 0 \c x \c 0 matrix */
inline SparseMatrix()
: m_outerSize(-1), m_innerSize(0), m_outerIndex(0)
{
resize(0, 0);
}
/** Constructs a \a rows \c x \a cols empty matrix */
inline SparseMatrix(Index rows, Index cols)
: m_outerSize(0), m_innerSize(0), m_outerIndex(0)
{
resize(rows, cols);
}
/** Constructs a sparse matrix from the sparse expression \a other */
template<typename OtherDerived>
inline SparseMatrix(const SparseMatrixBase<OtherDerived>& other)
: m_outerSize(0), m_innerSize(0), m_outerIndex(0)
@@ -413,12 +388,14 @@ class SparseMatrix
*this = other.derived();
}
/** Copy constructor */
inline SparseMatrix(const SparseMatrix& other)
: Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0)
{
*this = other.derived();
}
/** Swap the content of two sparse matrices of same type (optimization) */
inline void swap(SparseMatrix& other)
{
//EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n");
@@ -444,11 +421,13 @@ class SparseMatrix
return *this;
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename Lhs, typename Rhs>
inline SparseMatrix& operator=(const SparseProduct<Lhs,Rhs>& product)
{
return Base::operator=(product);
}
#endif
template<typename OtherDerived>
EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other)
@@ -534,6 +513,61 @@ class SparseMatrix
/** Overloaded for performance */
Scalar sum() const;
public:
/** \deprecated use setZero() and reserve()
* Initializes the filling process of \c *this.
* \param reserveSize approximate number of nonzeros
* Note that the matrix \c *this is zero-ed.
*/
EIGEN_DEPRECATED void startFill(Index reserveSize = 1000)
{
setZero();
m_data.reserve(reserveSize);
}
/** \deprecated use insert()
* Like fill() but with random inner coordinates.
*/
EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col)
{
return insert(row,col);
}
/** \deprecated use insert()
*/
EIGEN_DEPRECATED Scalar& fill(Index row, Index col)
{
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
if (m_outerIndex[outer+1]==0)
{
// we start a new inner vector
Index i = outer;
while (i>=0 && m_outerIndex[i]==0)
{
m_outerIndex[i] = m_data.size();
--i;
}
m_outerIndex[outer+1] = m_outerIndex[outer];
}
else
{
ei_assert(m_data.index(m_data.size()-1)<inner && "wrong sorted insertion");
}
// std::cerr << size_t(m_outerIndex[outer+1]) << " == " << m_data.size() << "\n";
assert(size_t(m_outerIndex[outer+1]) == m_data.size());
Index id = m_outerIndex[outer+1];
++m_outerIndex[outer+1];
m_data.append(0, inner);
return m_data.value(id);
}
/** \deprecated use finalize */
EIGEN_DEPRECATED void endFill() { finalize(); }
};
template<typename Scalar, int _Options>

View File

@@ -209,7 +209,7 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
{
Scalar v = it.value();
if (v!=Scalar(0))
temp.insertBack(Flip?it.index():j,Flip?j:it.index()) = v;
temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
}
}
temp.finalize();
@@ -239,7 +239,7 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
{
Scalar v = it.value();
if (v!=Scalar(0))
derived().insertBack(j,it.index()) = v;
derived().insertBackByOuterInner(j,it.index()) = v;
}
}
derived().finalize();

View File

@@ -265,7 +265,7 @@ static void ei_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& r
}
res.startVec(j);
for (typename AmbiVector<Scalar>::Iterator it(tempVector); it; ++it)
res.insertBack(j,it.index()) = it.value();
res.insertBackByOuterInner(j,it.index()) = it.value();
}
res.finalize();
}

View File

@@ -127,7 +127,7 @@ class SparseVector
ei_assert(outer==0);
}
inline Scalar& insertBack(Index outer, Index inner)
inline Scalar& insertBackByOuterInner(Index outer, Index inner)
{
ei_assert(outer==0);
return insertBack(inner);
@@ -138,8 +138,10 @@ class SparseVector
return m_data.value(m_data.size()-1);
}
inline Scalar& insert(Index outer, Index inner)
inline Scalar& insert(Index row, Index col)
{
Index inner = IsColVector ? row : col;
Index outer = IsColVector ? col : row;
ei_assert(outer==0);
return insert(inner);
}
@@ -165,42 +167,7 @@ class SparseVector
*/
inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); }
/** \deprecated use setZero() and reserve() */
EIGEN_DEPRECATED void startFill(Index reserve)
{
setZero();
m_data.reserve(reserve);
}
/** \deprecated use insertBack(Index,Index) */
EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
{
ei_assert(r==0 || c==0);
return fill(IsColVector ? r : c);
}
/** \deprecated use insertBack(Index) */
EIGEN_DEPRECATED Scalar& fill(Index i)
{
m_data.append(0, i);
return m_data.value(m_data.size()-1);
}
/** \deprecated use insert(Index,Index) */
EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
{
ei_assert(r==0 || c==0);
return fillrand(IsColVector ? r : c);
}
/** \deprecated use insert(Index) */
EIGEN_DEPRECATED Scalar& fillrand(Index i)
{
return insert(i);
}
/** \deprecated use finalize() */
EIGEN_DEPRECATED void endFill() {}
inline void finalize() {}
void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
@@ -362,6 +329,45 @@ class SparseVector
/** Overloaded for performance */
Scalar sum() const;
public:
/** \deprecated use setZero() and reserve() */
EIGEN_DEPRECATED void startFill(Index reserve)
{
setZero();
m_data.reserve(reserve);
}
/** \deprecated use insertBack(Index,Index) */
EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
{
ei_assert(r==0 || c==0);
return fill(IsColVector ? r : c);
}
/** \deprecated use insertBack(Index) */
EIGEN_DEPRECATED Scalar& fill(Index i)
{
m_data.append(0, i);
return m_data.value(m_data.size()-1);
}
/** \deprecated use insert(Index,Index) */
EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
{
ei_assert(r==0 || c==0);
return fillrand(IsColVector ? r : c);
}
/** \deprecated use insert(Index) */
EIGEN_DEPRECATED Scalar& fillrand(Index i)
{
return insert(i);
}
/** \deprecated use finalize() */
EIGEN_DEPRECATED void endFill() {}
};
template<typename Scalar, int _Options>