| // This file is part of Eigen, a lightweight C++ template library | |
| // for linear algebra. | |
| // | |
| // Copyright (C) 2011 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/. | |
| #ifndef EIGEN_INCOMPLETE_LU_H | |
| #define EIGEN_INCOMPLETE_LU_H | |
| // IWYU pragma: private | |
| #include "./InternalHeaderCheck.h" | |
| namespace Eigen { | |
| template <typename Scalar_> | |
| class IncompleteLU : public SparseSolverBase<IncompleteLU<Scalar_> > { | |
| protected: | |
| typedef SparseSolverBase<IncompleteLU<Scalar_> > Base; | |
| using Base::m_isInitialized; | |
| typedef Scalar_ Scalar; | |
| typedef Matrix<Scalar, Dynamic, 1> Vector; | |
| typedef typename Vector::Index Index; | |
| typedef SparseMatrix<Scalar, RowMajor> FactorType; | |
| public: | |
| typedef Matrix<Scalar, Dynamic, Dynamic> MatrixType; | |
| IncompleteLU() {} | |
| template <typename MatrixType> | |
| IncompleteLU(const MatrixType& mat) { | |
| compute(mat); | |
| } | |
| Index rows() const { return m_lu.rows(); } | |
| Index cols() const { return m_lu.cols(); } | |
| template <typename MatrixType> | |
| IncompleteLU& compute(const MatrixType& mat) { | |
| m_lu = mat; | |
| int size = mat.cols(); | |
| Vector diag(size); | |
| for (int i = 0; i < size; ++i) { | |
| typename FactorType::InnerIterator k_it(m_lu, i); | |
| for (; k_it && k_it.index() < i; ++k_it) { | |
| int k = k_it.index(); | |
| k_it.valueRef() /= diag(k); | |
| typename FactorType::InnerIterator j_it(k_it); | |
| typename FactorType::InnerIterator kj_it(m_lu, k); | |
| while (kj_it && kj_it.index() <= k) ++kj_it; | |
| for (++j_it; j_it;) { | |
| if (kj_it.index() == j_it.index()) { | |
| j_it.valueRef() -= k_it.value() * kj_it.value(); | |
| ++j_it; | |
| ++kj_it; | |
| } else if (kj_it.index() < j_it.index()) | |
| ++kj_it; | |
| else | |
| ++j_it; | |
| } | |
| } | |
| if (k_it && k_it.index() == i) | |
| diag(i) = k_it.value(); | |
| else | |
| diag(i) = 1; | |
| } | |
| m_isInitialized = true; | |
| return *this; | |
| } | |
| template <typename Rhs, typename Dest> | |
| void _solve_impl(const Rhs& b, Dest& x) const { | |
| x = m_lu.template triangularView<UnitLower>().solve(b); | |
| x = m_lu.template triangularView<Upper>().solve(x); | |
| } | |
| protected: | |
| FactorType m_lu; | |
| }; | |
| } // end namespace Eigen | |
| #endif // EIGEN_INCOMPLETE_LU_H |