mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-30 07:44:10 +08:00
fix realloc when initial size was 0 (bug reported by Jens Mueller)
This commit is contained in:
parent
4f0af00e51
commit
6dffdca123
@ -138,7 +138,7 @@ class SparseMatrix
|
|||||||
setZero();
|
setZero();
|
||||||
m_data.reserve(reserveSize);
|
m_data.reserve(reserveSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Preallocates \a reserveSize non zeros */
|
/** Preallocates \a reserveSize non zeros */
|
||||||
inline void reserve(int reserveSize)
|
inline void reserve(int reserveSize)
|
||||||
{
|
{
|
||||||
@ -175,9 +175,9 @@ class SparseMatrix
|
|||||||
m_data.append(0, inner);
|
m_data.append(0, inner);
|
||||||
return m_data.value(id);
|
return m_data.value(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--- low level purely coherent filling ---
|
//--- low level purely coherent filling ---
|
||||||
|
|
||||||
inline Scalar& insertBack(int outer, int inner)
|
inline Scalar& insertBack(int outer, int inner)
|
||||||
{
|
{
|
||||||
ei_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "wrong sorted insertion");
|
ei_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "wrong sorted insertion");
|
||||||
@ -187,14 +187,14 @@ class SparseMatrix
|
|||||||
m_data.append(0, inner);
|
m_data.append(0, inner);
|
||||||
return m_data.value(id);
|
return m_data.value(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void startVec(int outer)
|
inline void startVec(int outer)
|
||||||
{
|
{
|
||||||
ei_assert(m_outerIndex[outer]==int(m_data.size()) && "you must call startVec on each inner vec");
|
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+1]==0 && "you must call startVec on each inner vec");
|
||||||
m_outerIndex[outer+1] = m_outerIndex[outer];
|
m_outerIndex[outer+1] = m_outerIndex[outer];
|
||||||
}
|
}
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/** \deprecated use insert()
|
/** \deprecated use insert()
|
||||||
@ -204,20 +204,20 @@ class SparseMatrix
|
|||||||
{
|
{
|
||||||
return insert(row,col);
|
return insert(row,col);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a reference to a novel non zero coefficient with coordinates \a row x \a 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.
|
* The non zero coefficient must \b not already exist.
|
||||||
*
|
*
|
||||||
* \warning This function can be extremely slow if the non zero coefficients
|
* \warning This function can be extremely slow if the non zero coefficients
|
||||||
* are not inserted in a coherent order.
|
* are not inserted in a coherent order.
|
||||||
*
|
*
|
||||||
* After an insertion session, you should call the finalize() function.
|
* After an insertion session, you should call the finalize() function.
|
||||||
*/
|
*/
|
||||||
EIGEN_DONT_INLINE Scalar& insert(int row, int col)
|
EIGEN_DONT_INLINE Scalar& insert(int row, int col)
|
||||||
{
|
{
|
||||||
const int outer = IsRowMajor ? row : col;
|
const int outer = IsRowMajor ? row : col;
|
||||||
const int inner = IsRowMajor ? col : row;
|
const int inner = IsRowMajor ? col : row;
|
||||||
|
|
||||||
int previousOuter = outer;
|
int previousOuter = outer;
|
||||||
if (m_outerIndex[outer+1]==0)
|
if (m_outerIndex[outer+1]==0)
|
||||||
{
|
{
|
||||||
@ -229,13 +229,13 @@ class SparseMatrix
|
|||||||
}
|
}
|
||||||
m_outerIndex[outer+1] = m_outerIndex[outer];
|
m_outerIndex[outer+1] = m_outerIndex[outer];
|
||||||
}
|
}
|
||||||
|
|
||||||
// here we have to handle the tricky case where the outerIndex array
|
// here we have to handle the tricky case where the outerIndex array
|
||||||
// starts with: [ 0 0 0 0 0 1 ...] and we are inserting in, e.g.,
|
// starts with: [ 0 0 0 0 0 1 ...] and we are inserting in, e.g.,
|
||||||
// the 2nd inner vector...
|
// the 2nd inner vector...
|
||||||
bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0))
|
bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0))
|
||||||
&& (size_t(m_outerIndex[outer+1]) == m_data.size());
|
&& (size_t(m_outerIndex[outer+1]) == m_data.size());
|
||||||
|
|
||||||
size_t startId = m_outerIndex[outer];
|
size_t startId = m_outerIndex[outer];
|
||||||
// FIXME let's make sure sizeof(long int) == sizeof(size_t)
|
// FIXME let's make sure sizeof(long int) == sizeof(size_t)
|
||||||
size_t id = m_outerIndex[outer+1];
|
size_t id = m_outerIndex[outer+1];
|
||||||
@ -244,18 +244,26 @@ class SparseMatrix
|
|||||||
float reallocRatio = 1;
|
float reallocRatio = 1;
|
||||||
if (m_data.allocatedSize()<=m_data.size())
|
if (m_data.allocatedSize()<=m_data.size())
|
||||||
{
|
{
|
||||||
// we need to reallocate the data, to reduce multiple reallocations
|
// if there is no preallocated memory, let's reserve a minimum of 32 elements
|
||||||
// we use a smart resize algorithm based on the current filling ratio
|
if (m_data.size()==0)
|
||||||
// in addition, we use float to avoid integers overflows
|
{
|
||||||
float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1);
|
m_data.reserve(32);
|
||||||
reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size());
|
}
|
||||||
// furthermore we bound the realloc ratio to:
|
else
|
||||||
// 1) reduce multiple minor realloc when the matrix is almost filled
|
{
|
||||||
// 2) avoid to allocate too much memory when the matrix is almost empty
|
// we need to reallocate the data, to reduce multiple reallocations
|
||||||
reallocRatio = std::min(std::max(reallocRatio,1.5f),8.f);
|
// we use a smart resize algorithm based on the current filling ratio
|
||||||
|
// in addition, we use float to avoid integers overflows
|
||||||
|
float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1);
|
||||||
|
reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size());
|
||||||
|
// furthermore we bound the realloc ratio to:
|
||||||
|
// 1) reduce multiple minor realloc when the matrix is almost filled
|
||||||
|
// 2) avoid to allocate too much memory when the matrix is almost empty
|
||||||
|
reallocRatio = std::min(std::max(reallocRatio,1.5f),8.f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_data.resize(m_data.size()+1,reallocRatio);
|
m_data.resize(m_data.size()+1,reallocRatio);
|
||||||
|
|
||||||
if (!isLastVec)
|
if (!isLastVec)
|
||||||
{
|
{
|
||||||
if (previousOuter==-1)
|
if (previousOuter==-1)
|
||||||
@ -310,7 +318,7 @@ class SparseMatrix
|
|||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEPRECATED void endFill() { finalize(); }
|
EIGEN_DEPRECATED void endFill() { finalize(); }
|
||||||
|
|
||||||
/** Must be called after inserting a set of non zero entries.
|
/** Must be called after inserting a set of non zero entries.
|
||||||
*/
|
*/
|
||||||
inline void finalize()
|
inline void finalize()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user