aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/SparseCore/SparseMatrix.h
diff options
context:
space:
mode:
authorGravatar Benjamin Piwowarski <benjamin@bpiwowar.net>2012-07-19 00:07:06 +0200
committerGravatar Benjamin Piwowarski <benjamin@bpiwowar.net>2012-07-19 00:07:06 +0200
commit6bf49ceac212cc575f70d1d32cf3849a4177624a (patch)
tree85fe4dd6d2bc23df52835a81d606b2e7a0b76a37 /Eigen/src/SparseCore/SparseMatrix.h
parent3f08a6a126a334bb89c187bcf4ee3598972e616b (diff)
bug #449: add SparseMatrix::conservativeResize feature
Diffstat (limited to 'Eigen/src/SparseCore/SparseMatrix.h')
-rw-r--r--Eigen/src/SparseCore/SparseMatrix.h85
1 files changed, 74 insertions, 11 deletions
diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h
index 8463269c3..e94e55cfb 100644
--- a/Eigen/src/SparseCore/SparseMatrix.h
+++ b/Eigen/src/SparseCore/SparseMatrix.h
@@ -286,7 +286,8 @@ class SparseMatrix
{
std::size_t totalReserveSize = 0;
// turn the matrix into non-compressed mode
- m_innerNonZeros = new Index[m_outerSize];
+ m_innerNonZeros = static_cast<Index*>(std::malloc(m_outerSize * sizeof(Index)));
+ if (!m_innerNonZeros) internal::throw_std_bad_alloc();
// temporarily use m_innerSizes to hold the new starting points.
Index* newOuterIndex = m_innerNonZeros;
@@ -318,7 +319,9 @@ class SparseMatrix
}
else
{
- Index* newOuterIndex = new Index[m_outerSize+1];
+ Index* newOuterIndex = static_cast<Index*>(std::malloc((m_outerSize+1)*sizeof(Index)));
+ if (!newOuterIndex) internal::throw_std_bad_alloc();
+
Index count = 0;
for(Index j=0; j<m_outerSize; ++j)
{
@@ -345,7 +348,7 @@ class SparseMatrix
}
std::swap(m_outerIndex, newOuterIndex);
- delete[] newOuterIndex;
+ std::free(newOuterIndex);
}
}
@@ -460,7 +463,7 @@ class SparseMatrix
m_outerIndex[j+1] = m_outerIndex[j] + m_innerNonZeros[j];
oldStart = nextOldStart;
}
- delete[] m_innerNonZeros;
+ std::free(m_innerNonZeros);
m_innerNonZeros = 0;
m_data.resize(m_outerIndex[m_outerSize]);
m_data.squeeze();
@@ -506,6 +509,64 @@ class SparseMatrix
m_data.resize(k,0);
}
+ /** Resizes the matrix to a \a rows x \a cols matrix leaving old values untouched.
+ * \sa resizeNonZeros(Index), reserve(), setZero()
+ */
+ void conservativeResize(Index rows, Index cols)
+ {
+ // No change
+ if (this->rows() == rows && this->cols() == cols) return;
+
+ Index innerChange = IsRowMajor ? cols - this->cols() : rows - this->rows();
+ Index outerChange = IsRowMajor ? rows - this->rows() : cols - this->cols();
+ Index newInnerSize = IsRowMajor ? cols : rows;
+
+ // Deals with inner non zeros
+ if (m_innerNonZeros)
+ {
+ // Resize m_innerNonZeros
+ Index *newInnerNonZeros = static_cast<Index*>(std::realloc(m_innerNonZeros, (m_outerSize + outerChange) * sizeof(Index)));
+ if (!newInnerNonZeros) internal::throw_std_bad_alloc();
+ m_innerNonZeros = newInnerNonZeros;
+
+ for(Index i=m_outerSize; i<m_outerSize+outerChange; i++)
+ m_innerNonZeros[i] = 0;
+ }
+ else if (innerChange < 0)
+ {
+ // Inner size decreased: allocate a new m_innerNonZeros
+ m_innerNonZeros = static_cast<Index*>(std::malloc((m_outerSize+outerChange+1) * sizeof(Index)));
+ if (!m_innerNonZeros) internal::throw_std_bad_alloc();
+ for(Index i = 0; i < m_outerSize; i++)
+ m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i];
+ }
+
+ // Change the m_innerNonZeros in case of a decrease of inner size
+ if (m_innerNonZeros && innerChange < 0) {
+ for(Index i = 0; i<m_outerSize; i++)
+ {
+ Index &n = m_innerNonZeros[i];
+ Index start = m_outerIndex[i];
+ while (n >= 0 && m_data.index(start+n-1) >= newInnerSize) --n;
+ }
+ }
+
+ m_innerSize = newInnerSize;
+
+ // Re-allocate outer index structure if necessary
+ if (outerChange == 0)
+ return;
+
+ Index *newOuterIndex = static_cast<Index*>(std::realloc(m_outerIndex, (m_outerSize + outerChange + 1) * sizeof(Index)));
+ if (!newOuterIndex) internal::throw_std_bad_alloc();
+ m_outerIndex = newOuterIndex;
+ Index last = m_outerSize == 0 ? 0 : m_outerIndex[m_outerSize];
+ for(Index i=m_outerSize; i<m_outerSize+outerChange+1; i++)
+ m_outerIndex[i] = last;
+ m_outerSize += outerChange;
+
+ }
+
/** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero.
* \sa resizeNonZeros(Index), reserve(), setZero()
*/
@@ -516,13 +577,15 @@ class SparseMatrix
m_data.clear();
if (m_outerSize != outerSize || m_outerSize==0)
{
- delete[] m_outerIndex;
- m_outerIndex = new Index [outerSize+1];
+ std::free(m_outerIndex);
+ m_outerIndex = static_cast<Index*>(std::malloc((outerSize + 1) * sizeof(Index)));
+ if (!m_outerIndex) internal::throw_std_bad_alloc();
+
m_outerSize = outerSize;
}
if(m_innerNonZeros)
{
- delete[] m_innerNonZeros;
+ std::free(m_innerNonZeros);
m_innerNonZeros = 0;
}
memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index));
@@ -714,8 +777,8 @@ class SparseMatrix
/** Destructor */
inline ~SparseMatrix()
{
- delete[] m_outerIndex;
- delete[] m_innerNonZeros;
+ std::free(m_outerIndex);
+ std::free(m_innerNonZeros);
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -735,7 +798,7 @@ protected:
resize(other.rows(), other.cols());
if(m_innerNonZeros)
{
- delete[] m_innerNonZeros;
+ std::free(m_innerNonZeros);
m_innerNonZeros = 0;
}
}
@@ -1105,7 +1168,7 @@ void SparseMatrix<Scalar,_Options,_Index>::sumupDuplicates()
m_outerIndex[m_outerSize] = count;
// turn the matrix into compressed form
- delete[] m_innerNonZeros;
+ std::free(m_innerNonZeros);
m_innerNonZeros = 0;
m_data.resize(m_outerIndex[m_outerSize]);
}