mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-08 09:49:03 +08:00
SimplicialCholesky: avoid multiple twisting of the same matrix when calling compute()
This commit is contained in:
parent
97cdf6ce9e
commit
7f63169f09
@ -104,7 +104,7 @@ class SimplicialCholeskyBase
|
|||||||
SimplicialCholeskyBase(const MatrixType& matrix)
|
SimplicialCholeskyBase(const MatrixType& matrix)
|
||||||
: m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1)
|
: m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1)
|
||||||
{
|
{
|
||||||
compute(matrix);
|
derived().compute(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SimplicialCholeskyBase()
|
~SimplicialCholeskyBase()
|
||||||
@ -128,14 +128,6 @@ class SimplicialCholeskyBase
|
|||||||
return m_info;
|
return m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Computes the sparse Cholesky decomposition of \a matrix */
|
|
||||||
Derived& compute(const MatrixType& matrix)
|
|
||||||
{
|
|
||||||
derived().analyzePattern(matrix);
|
|
||||||
derived().factorize(matrix);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||||
*
|
*
|
||||||
* \sa compute()
|
* \sa compute()
|
||||||
@ -258,10 +250,42 @@ class SimplicialCholeskyBase
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/** Computes the sparse Cholesky decomposition of \a matrix */
|
||||||
template<bool DoLDLT>
|
template<bool DoLDLT>
|
||||||
void factorize(const MatrixType& a);
|
void compute(const MatrixType& matrix)
|
||||||
|
{
|
||||||
|
eigen_assert(matrix.rows()==matrix.cols());
|
||||||
|
Index size = matrix.cols();
|
||||||
|
CholMatrixType ap(size,size);
|
||||||
|
ordering(matrix, ap);
|
||||||
|
analyzePattern_preordered(ap, DoLDLT);
|
||||||
|
factorize_preordered<DoLDLT>(ap);
|
||||||
|
}
|
||||||
|
|
||||||
void analyzePattern(const MatrixType& a, bool doLDLT);
|
template<bool DoLDLT>
|
||||||
|
void factorize(const MatrixType& a)
|
||||||
|
{
|
||||||
|
eigen_assert(a.rows()==a.cols());
|
||||||
|
int size = a.cols();
|
||||||
|
CholMatrixType ap(size,size);
|
||||||
|
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_Pinv);
|
||||||
|
factorize_preordered<DoLDLT>(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool DoLDLT>
|
||||||
|
void factorize_preordered(const CholMatrixType& a);
|
||||||
|
|
||||||
|
void analyzePattern(const MatrixType& a, bool doLDLT)
|
||||||
|
{
|
||||||
|
eigen_assert(a.rows()==a.cols());
|
||||||
|
int size = a.cols();
|
||||||
|
CholMatrixType ap(size,size);
|
||||||
|
ordering(a, ap);
|
||||||
|
analyzePattern_preordered(ap,doLDLT);
|
||||||
|
}
|
||||||
|
void analyzePattern_preordered(const CholMatrixType& a, bool doLDLT);
|
||||||
|
|
||||||
|
void ordering(const MatrixType& a, CholMatrixType& ap);
|
||||||
|
|
||||||
/** keeps off-diagonal entries; drops diagonal entries */
|
/** keeps off-diagonal entries; drops diagonal entries */
|
||||||
struct keep_diag {
|
struct keep_diag {
|
||||||
@ -375,6 +399,13 @@ public:
|
|||||||
return Traits::getU(Base::m_matrix);
|
return Traits::getU(Base::m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Computes the sparse Cholesky decomposition of \a matrix */
|
||||||
|
SimplicialLLT compute(const MatrixType& matrix)
|
||||||
|
{
|
||||||
|
Base::template compute<false>(matrix);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Performs a symbolic decomposition on the sparcity of \a matrix.
|
/** Performs a symbolic decomposition on the sparcity of \a matrix.
|
||||||
*
|
*
|
||||||
* This function is particularly useful when solving for several problems having the same structure.
|
* This function is particularly useful when solving for several problems having the same structure.
|
||||||
@ -459,6 +490,13 @@ public:
|
|||||||
return Traits::getU(Base::m_matrix);
|
return Traits::getU(Base::m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Computes the sparse Cholesky decomposition of \a matrix */
|
||||||
|
SimplicialLDLT compute(const MatrixType& matrix)
|
||||||
|
{
|
||||||
|
Base::template compute<true>(matrix);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Performs a symbolic decomposition on the sparcity of \a matrix.
|
/** Performs a symbolic decomposition on the sparcity of \a matrix.
|
||||||
*
|
*
|
||||||
* This function is particularly useful when solving for several problems having the same structure.
|
* This function is particularly useful when solving for several problems having the same structure.
|
||||||
@ -515,7 +553,7 @@ public:
|
|||||||
SimplicialCholesky(const MatrixType& matrix)
|
SimplicialCholesky(const MatrixType& matrix)
|
||||||
: Base(), m_LDLT(true)
|
: Base(), m_LDLT(true)
|
||||||
{
|
{
|
||||||
Base::compute(matrix);
|
compute(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimplicialCholesky& setMode(SimplicialCholeskyMode mode)
|
SimplicialCholesky& setMode(SimplicialCholeskyMode mode)
|
||||||
@ -544,6 +582,16 @@ public:
|
|||||||
return Base::m_matrix;
|
return Base::m_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Computes the sparse Cholesky decomposition of \a matrix */
|
||||||
|
SimplicialCholesky compute(const MatrixType& matrix)
|
||||||
|
{
|
||||||
|
if(m_LDLT)
|
||||||
|
Base::template compute<true>(matrix);
|
||||||
|
else
|
||||||
|
Base::template compute<false>(matrix);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Performs a symbolic decomposition on the sparcity of \a matrix.
|
/** Performs a symbolic decomposition on the sparcity of \a matrix.
|
||||||
*
|
*
|
||||||
* This function is particularly useful when solving for several problems having the same structure.
|
* This function is particularly useful when solving for several problems having the same structure.
|
||||||
@ -625,22 +673,17 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
void SimplicialCholeskyBase<Derived>::analyzePattern(const MatrixType& a, bool doLDLT)
|
void SimplicialCholeskyBase<Derived>::ordering(const MatrixType& a, CholMatrixType& ap)
|
||||||
{
|
{
|
||||||
eigen_assert(a.rows()==a.cols());
|
eigen_assert(a.rows()==a.cols());
|
||||||
const Index size = a.rows();
|
const Index size = a.rows();
|
||||||
m_matrix.resize(size, size);
|
|
||||||
m_parent.resize(size);
|
|
||||||
m_nonZerosPerCol.resize(size);
|
|
||||||
|
|
||||||
ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
|
|
||||||
|
|
||||||
// TODO allows to configure the permutation
|
// TODO allows to configure the permutation
|
||||||
{
|
{
|
||||||
CholMatrixType C;
|
CholMatrixType C;
|
||||||
C = a.template selfadjointView<UpLo>();
|
C = a.template selfadjointView<UpLo>();
|
||||||
// remove diagonal entries:
|
// remove diagonal entries:
|
||||||
C.prune(keep_diag());
|
// seems not to be needed
|
||||||
|
// C.prune(keep_diag());
|
||||||
internal::minimum_degree_ordering(C, m_P);
|
internal::minimum_degree_ordering(C, m_P);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,8 +692,19 @@ void SimplicialCholeskyBase<Derived>::analyzePattern(const MatrixType& a, bool d
|
|||||||
else
|
else
|
||||||
m_Pinv.resize(0);
|
m_Pinv.resize(0);
|
||||||
|
|
||||||
SparseMatrix<Scalar,ColMajor,Index> ap(size,size);
|
ap.resize(size,size);
|
||||||
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_Pinv);
|
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_Pinv);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
void SimplicialCholeskyBase<Derived>::analyzePattern_preordered(const CholMatrixType& ap, bool doLDLT)
|
||||||
|
{
|
||||||
|
const Index size = ap.rows();
|
||||||
|
m_matrix.resize(size, size);
|
||||||
|
m_parent.resize(size);
|
||||||
|
m_nonZerosPerCol.resize(size);
|
||||||
|
|
||||||
|
ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
|
||||||
|
|
||||||
for(Index k = 0; k < size; ++k)
|
for(Index k = 0; k < size; ++k)
|
||||||
{
|
{
|
||||||
@ -693,11 +747,11 @@ void SimplicialCholeskyBase<Derived>::analyzePattern(const MatrixType& a, bool d
|
|||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<bool DoLDLT>
|
template<bool DoLDLT>
|
||||||
void SimplicialCholeskyBase<Derived>::factorize(const MatrixType& a)
|
void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType& ap)
|
||||||
{
|
{
|
||||||
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
||||||
eigen_assert(a.rows()==a.cols());
|
eigen_assert(ap.rows()==ap.cols());
|
||||||
const Index size = a.rows();
|
const Index size = ap.rows();
|
||||||
eigen_assert(m_parent.size()==size);
|
eigen_assert(m_parent.size()==size);
|
||||||
eigen_assert(m_nonZerosPerCol.size()==size);
|
eigen_assert(m_nonZerosPerCol.size()==size);
|
||||||
|
|
||||||
@ -709,9 +763,6 @@ void SimplicialCholeskyBase<Derived>::factorize(const MatrixType& a)
|
|||||||
ei_declare_aligned_stack_constructed_variable(Index, pattern, size, 0);
|
ei_declare_aligned_stack_constructed_variable(Index, pattern, size, 0);
|
||||||
ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
|
ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
|
||||||
|
|
||||||
SparseMatrix<Scalar,ColMajor,Index> ap(size,size);
|
|
||||||
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_Pinv);
|
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
m_diag.resize(DoLDLT ? size : 0);
|
m_diag.resize(DoLDLT ? size : 0);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user