// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008 Guillaume Saupin <guillaume.saupin@cea.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 Skyline_Module * * \class SkylineInplaceLU * * \brief Inplace LU decomposition of a skyline matrix and associated features * * \param MatrixType the type of the matrix of which we are computing the LU factorization *
*/ template<typename MatrixType> class SkylineInplaceLU { protected: typedeftypename MatrixType::Scalar Scalar; typedeftypename MatrixType::Index Index;
/** Creates a LU object and compute the respective factorization of \a matrix using
* flags \a flags. */
SkylineInplaceLU(MatrixType& matrix, int flags = 0)
: /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0), m_lu(matrix) {
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar > ();
m_lu.IsRowMajor ? computeRowMajor() : compute();
}
/** Sets the relative threshold value used to prune zero coefficients during the decomposition. * * Setting a value greater than zero speeds up computation, and yields to an incomplete * factorization with fewer non zero coefficients. Such approximate factors are especially * useful to initialize an iterative solver. * * Note that the exact meaning of this parameter might depends on the actual * backend. Moreover, not all backends support this feature. *
* \sa precision() */ void setPrecision(RealScalar v) {
m_precision = v;
}
/** \returns the current precision. *
* \sa setPrecision() */
RealScalar precision() const { return m_precision;
}
/** Sets the flags. Possible values are: * - CompleteFactorization * - IncompleteFactorization * - MemoryEfficient * - one of the ordering methods * - etc... *
* \sa flags() */ void setFlags(int f) {
m_flags = f;
}
/** \returns the current flags */ int flags() const { return m_flags;
}
void setOrderingMethod(int m) {
m_flags = m;
}
int orderingMethod() const { return m_flags;
}
/** Computes/re-computes the LU factorization */ void compute(); void computeRowMajor();
/** \returns the lower triangular matrix L */ //inline const MatrixType& matrixL() const { return m_matrixL; }
/** \returns the upper triangular matrix U */ //inline const MatrixType& matrixU() const { return m_matrixU; }
/** Computes / recomputes the in place LU decomposition of the SkylineInplaceLU. * using the default algorithm.
*/ template<typename MatrixType> //template<typename _Scalar> void SkylineInplaceLU<MatrixType>::compute() { const size_t rows = m_lu.rows(); const size_t cols = m_lu.cols();
eigen_assert(rows == cols && "We do not (yet) support rectangular LU.");
eigen_assert(!m_lu.IsRowMajor && "LU decomposition does not work with rowMajor Storage");
eigen_assert(rows == cols && "We do not (yet) support rectangular LU.");
eigen_assert(m_lu.IsRowMajor && "You're trying to apply rowMajor decomposition on a ColMajor matrix !");
Scalar newCoeff = m_lu.coeffLower(row, col) - rowVal.dot(colVal); #else if (offset > 0) //Skip zero value of lIt
uIt += offset; else//Skip zero values of uIt
lIt += -offset;
Scalar newCoeff = m_lu.coeffLower(row, col);
for (Index k = 0; k < stop; ++k) { const Scalar tmp = newCoeff;
newCoeff = tmp - lIt.value() * uIt.value();
++lIt;
++uIt;
} #endif
Scalar newCoeff = m_lu.coeffUpper(rrow, col) - rowVal.dot(colVal); #else if (offset > 0) //Skip zero value of lIt
uIt += offset; else//Skip zero values of uIt
lIt += -offset;
Scalar newCoeff = m_lu.coeffUpper(rrow, col); for (Index k = 0; k < stop; ++k) { const Scalar tmp = newCoeff;
newCoeff = tmp - lIt.value() * uIt.value();
Index stop = offset > 0 ? lIt.size() : uIt.size(); #ifdef VECTORIZE
Map<VectorXd > rowVal(lIt.valuePtr() + (offset > 0 ? 0 : -offset), stop);
Map<VectorXd > colVal(uIt.valuePtr() + (offset > 0 ? offset : 0), stop);
Scalar newCoeff = m_lu.coeffDiag(row) - rowVal.dot(colVal); #else if (offset > 0) //Skip zero value of lIt
uIt += offset; else//Skip zero values of uIt
lIt += -offset;
Scalar newCoeff = m_lu.coeffDiag(row); for (Index k = 0; k < stop; ++k) { const Scalar tmp = newCoeff;
newCoeff = tmp - lIt.value() * uIt.value();
++lIt;
++uIt;
} #endif
m_lu.coeffRefDiag(row) = newCoeff;
}
}
/** Computes *x = U^-1 L^-1 b * * If \a transpose is set to SvTranspose or SvAdjoint, the solution * of the transposed/adjoint system is computed instead. * * Not all backends implement the solution of the transposed or * adjoint system.
*/ template<typename MatrixType> template<typename BDerived, typename XDerived> bool SkylineInplaceLU<MatrixType>::solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x, constint transposed) const { const size_t rows = m_lu.rows(); const size_t cols = m_lu.cols();
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.