- Added problem size constructor to decompositions that did not have one. It preallocates member data structures.

- Updated unit tests to check above constructor.
- In the compute() method of decompositions: Made temporary matrices/vectors class members to avoid heap allocations during compute() (when dynamic matrices are used, of course).

These  changes can speed up decomposition computation time when a solver instance is used to solve multiple same-sized problems. An added benefit is that the compute() method can now be invoked in contexts were heap allocations are forbidden, such as in real-time control loops.

CAVEAT: Not all of the decompositions in the Eigenvalues module have a heap-allocation-free compute() method. A future patch may address this issue, but some required API changes need to be incorporated first.
This commit is contained in:
Adolfo Rodriguez Tsouroukdissian
2010-04-21 17:15:57 +02:00
parent faf8f7732d
commit 28dde19e40
29 changed files with 396 additions and 121 deletions

View File

@@ -66,6 +66,7 @@ template<typename _MatrixType> class LDLT
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef typename ei_plain_col_type<MatrixType, int>::type IntColVectorType;
typedef Matrix<Scalar, RowsAtCompileTime, 1, Options, MaxRowsAtCompileTime, 1> TmpMatrixType;
/** \brief Default Constructor.
*
@@ -80,12 +81,17 @@ template<typename _MatrixType> class LDLT
* according to the specified problem \a size.
* \sa LDLT()
*/
LDLT(int size) : m_matrix(size,size), m_p(size), m_transpositions(size), m_isInitialized(false) {}
LDLT(int size) : m_matrix(size, size),
m_p(size),
m_transpositions(size),
m_temporary(size),
m_isInitialized(false) {}
LDLT(const MatrixType& matrix)
: m_matrix(matrix.rows(), matrix.cols()),
m_p(matrix.rows()),
m_transpositions(matrix.rows()),
m_temporary(matrix.rows()),
m_isInitialized(false)
{
compute(matrix);
@@ -175,6 +181,7 @@ template<typename _MatrixType> class LDLT
MatrixType m_matrix;
IntColVectorType m_p;
IntColVectorType m_transpositions; // FIXME do we really need to store permanently the transpositions?
TmpMatrixType m_temporary;
int m_sign;
bool m_isInitialized;
};
@@ -206,7 +213,7 @@ LDLT<MatrixType>& LDLT<MatrixType>::compute(const MatrixType& a)
// By using a temorary, packet-aligned products are guarenteed. In the LLT
// case this is unnecessary because the diagonal is included and will always
// have optimal alignment.
Matrix<Scalar, RowsAtCompileTime, 1, Options, MaxRowsAtCompileTime, 1> _temporary(size);
m_temporary.resize(size);
for (int j = 0; j < size; ++j)
{
@@ -251,11 +258,11 @@ LDLT<MatrixType>& LDLT<MatrixType>::compute(const MatrixType& a)
int endSize = size - j - 1;
if (endSize > 0) {
_temporary.tail(endSize).noalias() = m_matrix.block(j+1,0, endSize, j)
m_temporary.tail(endSize).noalias() = m_matrix.block(j+1,0, endSize, j)
* m_matrix.col(j).head(j).conjugate();
m_matrix.row(j).tail(endSize) = m_matrix.row(j).tail(endSize).conjugate()
- _temporary.tail(endSize).transpose();
- m_temporary.tail(endSize).transpose();
if(ei_abs(Djj) > cutoff)
{

View File

@@ -82,6 +82,15 @@ template<typename _MatrixType, int _UpLo> class LLT
*/
LLT() : m_matrix(), m_isInitialized(false) {}
/** \brief Default Constructor with memory preallocation
*
* Like the default constructor but with preallocation of the internal data
* according to the specified problem \a size.
* \sa LLT()
*/
LLT(int size) : m_matrix(size, size),
m_isInitialized(false) {}
LLT(const MatrixType& matrix)
: m_matrix(matrix.rows(), matrix.cols()),
m_isInitialized(false)