// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008-2012 Gael Guennebaud <gael.guennebaud@inria.fr> // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
/** \ingroup SparseCholesky_Module * \brief A base class for direct sparse Cholesky factorizations * * This is a base class for LL^T and LDL^T Cholesky factorizations of sparse matrices that are * selfadjoint and positive definite. These factorizations allow for solving A.X = B where * X and B can be either dense or sparse. * * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization * such that the factorized matrix is P A P^-1. * * \tparam Derived the type of the derived class, that is the actual factorization type. *
*/ template<typename Derived> class SimplicialCholeskyBase : public SparseSolverBase<Derived>
{ typedef SparseSolverBase<Derived> Base; using Base::m_isInitialized;
inline Index cols() const { return m_matrix.cols(); } inline Index rows() const { return m_matrix.rows(); }
/** \brief Reports whether previous computation was successful. * * \returns \c Success if computation was successful, * \c NumericalIssue if the matrix.appears to be negative.
*/
ComputationInfo info() const
{
eigen_assert(m_isInitialized && "Decomposition is not initialized."); return m_info;
}
/** \returns the permutation P
* \sa permutationPinv() */ const PermutationMatrix<Dynamic,Dynamic,StorageIndex>& permutationP() const
{ return m_P; }
/** \returns the inverse P^-1 of the permutation P
* \sa permutationP() */ const PermutationMatrix<Dynamic,Dynamic,StorageIndex>& permutationPinv() const
{ return m_Pinv; }
/** Sets the shift parameters that will be used to adjust the diagonal coefficients during the numerical factorization. * * During the numerical factorization, the diagonal coefficients are transformed by the following linear model:\n * \c d_ii = \a offset + \a scale * \c d_ii * * The default is the identity transformation with \a offset=0, and \a scale=1. * * \returns a reference to \c *this.
*/
Derived& setShift(const RealScalar& offset, const RealScalar& scale = 1)
{
m_shiftOffset = offset;
m_shiftScale = scale; return derived();
}
/** \internal */ template<typename Rhs,typename Dest> void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
{
eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
eigen_assert(m_matrix.rows()==b.rows());
template<bool DoLDLT> void factorize(const MatrixType& a)
{
eigen_assert(a.rows()==a.cols());
Index size = a.cols();
CholMatrixType tmp(size,size);
ConstCholMatrixPtr pmat;
if(m_P.size() == 0 && (int(UpLo) & int(Upper)) == Upper)
{ // If there is no ordering, try to directly use the input matrix without any copy
internal::simplicial_cholesky_grab_input<CholMatrixType,MatrixType>::run(a, pmat, tmp);
} else
{
tmp.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P);
pmat = &tmp;
}
/** \ingroup SparseCholesky_Module * \class SimplicialLLT * \brief A direct sparse LLT Cholesky factorizations * * This class provides a LL^T Cholesky factorizations of sparse matrices that are * selfadjoint and positive definite. The factorization allows for solving A.X = B where * X and B can be either dense or sparse. * * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization * such that the factorized matrix is P A P^-1. * * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower * or Upper. Default is Lower. * \tparam _Ordering The ordering method to use, either AMDOrdering<> or NaturalOrdering<>. Default is AMDOrdering<> * * \implsparsesolverconcept * * \sa class SimplicialLDLT, class AMDOrdering, class NaturalOrdering
*/ template<typename _MatrixType, int _UpLo, typename _Ordering> class SimplicialLLT : public SimplicialCholeskyBase<SimplicialLLT<_MatrixType,_UpLo,_Ordering> >
{ public: typedef _MatrixType MatrixType; enum { UpLo = _UpLo }; typedef SimplicialCholeskyBase<SimplicialLLT> Base; typedeftypename MatrixType::Scalar Scalar; typedeftypename MatrixType::RealScalar RealScalar; typedeftypename MatrixType::StorageIndex StorageIndex; typedef SparseMatrix<Scalar,ColMajor,Index> CholMatrixType; typedef Matrix<Scalar,Dynamic,1> VectorType; typedef internal::traits<SimplicialLLT> Traits; typedeftypename Traits::MatrixL MatrixL; typedeftypename Traits::MatrixU MatrixU; public: /** Default constructor */
SimplicialLLT() : Base() {} /** Constructs and performs the LLT factorization of \a matrix */ explicit SimplicialLLT(const MatrixType& matrix)
: Base(matrix) {}
/** \returns an expression of the factor L */ inlineconst MatrixL matrixL() const {
eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized"); return Traits::getL(Base::m_matrix);
}
/** \returns an expression of the factor U (= L^*) */ inlineconst MatrixU matrixU() const {
eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized"); 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. * * This function is particularly useful when solving for several problems having the same structure. * * \sa factorize()
*/ void analyzePattern(const MatrixType& a)
{
Base::analyzePattern(a, false);
}
/** Performs a numeric decomposition of \a matrix * * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. * * \sa analyzePattern()
*/ void factorize(const MatrixType& a)
{
Base::template factorize<false>(a);
}
/** \returns the determinant of the underlying matrix from the current factorization */
Scalar determinant() const
{
Scalar detL = Base::m_matrix.diagonal().prod(); return numext::abs2(detL);
}
};
/** \ingroup SparseCholesky_Module * \class SimplicialLDLT * \brief A direct sparse LDLT Cholesky factorizations without square root. * * This class provides a LDL^T Cholesky factorizations without square root of sparse matrices that are * selfadjoint and positive definite. The factorization allows for solving A.X = B where * X and B can be either dense or sparse. * * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization * such that the factorized matrix is P A P^-1. * * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower * or Upper. Default is Lower. * \tparam _Ordering The ordering method to use, either AMDOrdering<> or NaturalOrdering<>. Default is AMDOrdering<> * * \implsparsesolverconcept * * \sa class SimplicialLLT, class AMDOrdering, class NaturalOrdering
*/ template<typename _MatrixType, int _UpLo, typename _Ordering> class SimplicialLDLT : public SimplicialCholeskyBase<SimplicialLDLT<_MatrixType,_UpLo,_Ordering> >
{ public: typedef _MatrixType MatrixType; enum { UpLo = _UpLo }; typedef SimplicialCholeskyBase<SimplicialLDLT> Base; typedeftypename MatrixType::Scalar Scalar; typedeftypename MatrixType::RealScalar RealScalar; typedeftypename MatrixType::StorageIndex StorageIndex; typedef SparseMatrix<Scalar,ColMajor,StorageIndex> CholMatrixType; typedef Matrix<Scalar,Dynamic,1> VectorType; typedef internal::traits<SimplicialLDLT> Traits; typedeftypename Traits::MatrixL MatrixL; typedeftypename Traits::MatrixU MatrixU; public: /** Default constructor */
SimplicialLDLT() : Base() {}
/** Constructs and performs the LLT factorization of \a matrix */ explicit SimplicialLDLT(const MatrixType& matrix)
: Base(matrix) {}
/** \returns a vector expression of the diagonal D */ inlineconst VectorType vectorD() const {
eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); return Base::m_diag;
} /** \returns an expression of the factor L */ inlineconst MatrixL matrixL() const {
eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); return Traits::getL(Base::m_matrix);
}
/** \returns an expression of the factor U (= L^*) */ inlineconst MatrixU matrixU() const {
eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); 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. * * This function is particularly useful when solving for several problems having the same structure. * * \sa factorize()
*/ void analyzePattern(const MatrixType& a)
{
Base::analyzePattern(a, true);
}
/** Performs a numeric decomposition of \a matrix * * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. * * \sa analyzePattern()
*/ void factorize(const MatrixType& a)
{
Base::template factorize<true>(a);
}
/** \returns the determinant of the underlying matrix from the current factorization */
Scalar determinant() const
{ return Base::m_diag.prod();
}
};
/** \deprecated use SimplicialLDLT or class SimplicialLLT * \ingroup SparseCholesky_Module * \class SimplicialCholesky * * \sa class SimplicialLDLT, class SimplicialLLT
*/ template<typename _MatrixType, int _UpLo, typename _Ordering> class SimplicialCholesky : public SimplicialCholeskyBase<SimplicialCholesky<_MatrixType,_UpLo,_Ordering> >
{ public: typedef _MatrixType MatrixType; enum { UpLo = _UpLo }; typedef SimplicialCholeskyBase<SimplicialCholesky> Base; typedeftypename MatrixType::Scalar Scalar; typedeftypename MatrixType::RealScalar RealScalar; typedeftypename MatrixType::StorageIndex StorageIndex; typedef SparseMatrix<Scalar,ColMajor,StorageIndex> CholMatrixType; typedef Matrix<Scalar,Dynamic,1> VectorType; typedef internal::traits<SimplicialCholesky> Traits; typedef internal::traits<SimplicialLDLT<MatrixType,UpLo> > LDLTTraits; typedef internal::traits<SimplicialLLT<MatrixType,UpLo> > LLTTraits; public:
SimplicialCholesky() : Base(), m_LDLT(true) {}
/** Performs a symbolic decomposition on the sparcity of \a matrix. * * This function is particularly useful when solving for several problems having the same structure. * * \sa factorize()
*/ void analyzePattern(const MatrixType& a)
{
Base::analyzePattern(a, m_LDLT);
}
/** Performs a numeric decomposition of \a matrix * * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. * * \sa analyzePattern()
*/ void factorize(const MatrixType& a)
{ if(m_LDLT)
Base::template factorize<true>(a); else
Base::template factorize<false>(a);
}
/** \internal */ template<typename Rhs,typename Dest> void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
{
eigen_assert(Base::m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
eigen_assert(Base::m_matrix.rows()==b.rows());
if(Base::m_info!=Success) return;
if(Base::m_P.size()>0)
dest = Base::m_P * b; else
dest = b;
ap.resize(size,size);
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P);
} else
{
m_Pinv.resize(0);
m_P.resize(0); if(int(UpLo)==int(Lower) || MatrixType::IsRowMajor)
{ // we have to transpose the lower part to to the upper one
ap.resize(size,size);
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>();
} else
internal::simplicial_cholesky_grab_input<CholMatrixType,MatrixType>::run(a, pmat, ap);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.