11#ifndef EIGEN_ITERATIVE_SOLVER_BASE_H
12#define EIGEN_ITERATIVE_SOLVER_BASE_H
15#include "./InternalHeaderCheck.h"
22auto is_ref_compatible_test(T& matrix) ->
decltype(Ref<const T>(matrix), std::true_type());
23std::false_type is_ref_compatible_test(...);
25template <
typename MatrixType>
26using is_ref_compatible =
decltype(is_ref_compatible_test(std::declval<remove_all_t<MatrixType>&>()));
31template <
typename MatrixType>
32MatrixType random_orthonormal_basis(Index rows, Index cols) {
33 HouseholderQR<MatrixType> qr(MatrixType::Random(rows, cols));
34 return qr.householderQ() * MatrixType::Identity(rows, cols);
37template <
typename RealScalar>
38EIGEN_DEVICE_FUNC RealScalar iterative_solver_scaling_factor(RealScalar norm) {
40 const RealScalar sqrtMin = numext::sqrt((std::numeric_limits<RealScalar>::min)());
41 const RealScalar sqrtMax = numext::sqrt((std::numeric_limits<RealScalar>::max)());
42 return norm < sqrtMin || norm > sqrtMax ? norm : RealScalar(1);
45template <typename MatrixType, bool MatrixFree = !internal::is_ref_compatible<MatrixType>::value>
46class generic_matrix_wrapper;
49template <
typename MatrixType>
50class generic_matrix_wrapper<MatrixType, false> {
52 using ActualMatrixType = Ref<const MatrixType>;
54 struct ConstSelfAdjointViewReturnType {
55 using Type =
typename ActualMatrixType::template ConstSelfAdjointViewReturnType<UpLo>::Type;
58 enum { MatrixFree =
false };
61 generic_matrix_wrapper() : m_dummy(), m_matrix(m_dummy) {}
63 template <
typename InputType>
64 generic_matrix_wrapper(
const InputType& mat) : m_matrix(mat) {}
66 const ActualMatrixType& matrix()
const {
return m_matrix; }
68 template <
typename MatrixDerived>
69 void grab(
const EigenBase<MatrixDerived>& mat) {
70 internal::destroy_at(&m_matrix);
71 internal::construct_at(&m_matrix, mat.derived());
74 void grab(
const Ref<const MatrixType>& mat) {
75 if (&(mat.derived()) != &m_matrix) {
76 internal::destroy_at(&m_matrix);
77 internal::construct_at(&m_matrix, mat);
83 ActualMatrixType m_matrix;
87template <
typename MatrixType>
88class generic_matrix_wrapper<MatrixType, true> {
90 using ActualMatrixType = MatrixType;
92 struct ConstSelfAdjointViewReturnType {
93 using Type = ActualMatrixType;
96 enum { MatrixFree =
true };
98 generic_matrix_wrapper() =
default;
100 generic_matrix_wrapper(
const MatrixType& mat) : mp_matrix(&mat) {}
102 const ActualMatrixType& matrix()
const {
return *mp_matrix; }
104 void grab(
const MatrixType& mat) { mp_matrix = &mat; }
107 const ActualMatrixType* mp_matrix =
nullptr;
117template <
typename Derived>
121 using Base::m_isInitialized;
124 using MatrixType =
typename internal::traits<Derived>::MatrixType;
125 using Preconditioner =
typename internal::traits<Derived>::Preconditioner;
126 using Scalar =
typename MatrixType::Scalar;
127 using StorageIndex =
typename MatrixType::StorageIndex;
128 using RealScalar =
typename MatrixType::RealScalar;
130 enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };
148 template <
typename MatrixDerived>
161 template <
typename MatrixDerived>
164 m_preconditioner.analyzePattern(matrix());
165 m_isInitialized =
true;
166 m_analysisIsOk =
true;
167 m_info = m_preconditioner.info();
181 template <
typename MatrixDerived>
183 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
185 m_preconditioner.factorize(matrix());
186 m_factorizationIsOk =
true;
187 m_info = m_preconditioner.info();
201 template <
typename MatrixDerived>
204 m_preconditioner.compute(matrix());
205 m_isInitialized =
true;
206 m_analysisIsOk =
true;
207 m_factorizationIsOk =
true;
208 m_info = m_preconditioner.info();
213 constexpr Index rows() const noexcept {
return matrix().rows(); }
216 constexpr Index cols() const noexcept {
return matrix().cols(); }
245 Index
maxIterations()
const {
return (m_maxIterations < 0) ? 2 * matrix().cols() : m_maxIterations; }
251 m_maxIterations = maxIters;
257 eigen_assert(m_isInitialized &&
"IterativeSolverBase is not initialized.");
267 eigen_assert(m_isInitialized &&
"IterativeSolverBase is not initialized.");
276 template <
typename Rhs,
typename Guess>
278 eigen_assert(m_isInitialized &&
"Solver is not initialized.");
279 eigen_assert(derived().rows() == b.rows() &&
"solve(): invalid number of rows of the right hand side matrix b");
293 template <
typename Rhs,
typename Dest>
295 eigen_assert(m_isInitialized &&
"Solver is not initialized.");
296 eigen_assert(derived().rows() == b.rows() &&
297 "solveWithGuessInPlace(): invalid number of rows of the right hand side b");
298 derived()._solve_vector_with_guess_impl(b, x);
303 eigen_assert(m_isInitialized &&
"IterativeSolverBase is not initialized.");
308 template <
typename Rhs,
typename DestDerived>
310 eigen_assert(rows() == b.rows());
312 Index rhsCols = b.cols();
313 Index size = b.rows();
314 DestDerived& dest(aDest.
derived());
315 using DestScalar =
typename DestDerived::Scalar;
321 typename DestDerived::PlainObject tmp(cols(), rhsCols);
323 for (Index k = 0; k < rhsCols; ++k) {
326 derived()._solve_vector_with_guess_impl(tb, tx);
327 tmp.col(k) = tx.sparseView(0);
336 m_info = global_info;
340 template <
typename Rhs,
typename DestDerived>
341 std::enable_if_t<Rhs::ColsAtCompileTime != 1 && DestDerived::ColsAtCompileTime != 1> _solve_with_guess_impl(
342 const Rhs& b, MatrixBase<DestDerived>& aDest)
const {
343 eigen_assert(rows() == b.rows());
345 Index rhsCols = b.cols();
346 DestDerived& dest(aDest.derived());
348 for (Index k = 0; k < rhsCols; ++k) {
349 typename DestDerived::ColXpr xk(dest, k);
350 typename Rhs::ConstColXpr bk(b, k);
351 derived()._solve_vector_with_guess_impl(bk, xk);
360 m_info = global_info;
363 template <
typename Rhs,
typename DestDerived>
364 std::enable_if_t<Rhs::ColsAtCompileTime == 1 || DestDerived::ColsAtCompileTime == 1> _solve_with_guess_impl(
365 const Rhs& b, MatrixBase<DestDerived>& dest)
const {
366 derived()._solve_vector_with_guess_impl(b, dest.derived());
370 template <
typename Rhs,
typename Dest>
371 void _solve_impl(
const Rhs& b, Dest& x)
const {
373 derived()._solve_with_guess_impl(b, x);
378 m_isInitialized =
false;
379 m_analysisIsOk =
false;
380 m_factorizationIsOk =
false;
381 m_maxIterations = -1;
382 m_tolerance = NumTraits<Scalar>::epsilon();
385 using MatrixWrapper = internal::generic_matrix_wrapper<MatrixType>;
386 using ActualMatrixType =
typename MatrixWrapper::ActualMatrixType;
388 const ActualMatrixType& matrix()
const {
return m_matrixWrapper.matrix(); }
390 template <
typename InputType>
391 void grab(
const InputType& A) {
392 m_matrixWrapper.grab(A);
395 MatrixWrapper m_matrixWrapper;
396 Preconditioner m_preconditioner;
398 Index m_maxIterations;
399 RealScalar m_tolerance;
401 mutable RealScalar m_error;
402 mutable Index m_iterations;
404 mutable bool m_analysisIsOk, m_factorizationIsOk;
Base class for linear iterative solvers.
Definition IterativeSolverBase.h:118
IterativeSolverBase()
Definition IterativeSolverBase.h:136
ComputationInfo info() const
Definition IterativeSolverBase.h:302
RealScalar error() const
Definition IterativeSolverBase.h:266
Index maxIterations() const
Definition IterativeSolverBase.h:245
Derived & setMaxIterations(Index maxIters)
Definition IterativeSolverBase.h:250
Derived & compute(const EigenBase< MatrixDerived > &A)
Definition IterativeSolverBase.h:202
IterativeSolverBase(const EigenBase< MatrixDerived > &A)
Definition IterativeSolverBase.h:149
void solveWithGuessInPlace(const Rhs &b, Dest &x) const
Definition IterativeSolverBase.h:294
const Preconditioner & preconditioner() const
Definition IterativeSolverBase.h:239
Derived & analyzePattern(const EigenBase< MatrixDerived > &A)
Definition IterativeSolverBase.h:162
Derived & factorize(const EigenBase< MatrixDerived > &A)
Definition IterativeSolverBase.h:182
Preconditioner & preconditioner()
Definition IterativeSolverBase.h:236
Derived & setTolerance(const RealScalar &tolerance)
Definition IterativeSolverBase.h:230
RealScalar tolerance() const
Definition IterativeSolverBase.h:221
const SolveWithGuess< Derived, Rhs, Guess > solveWithGuess(const MatrixBase< Rhs > &b, const Guess &x0) const
Definition IterativeSolverBase.h:277
Index iterations() const
Definition IterativeSolverBase.h:256
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
Pseudo expression representing a solving operation.
Definition SolveWithGuess.h:44
Base class of any sparse matrices or sparse expressions.
Definition SparseMatrixBase.h:31
SparseSolverBase()=default
ComputationInfo
Definition Constants.h:455
@ NumericalIssue
Definition Constants.h:459
@ Success
Definition Constants.h:457
@ NoConvergence
Definition Constants.h:461
Definition EigenBase.h:34
constexpr Derived & derived()
Definition EigenBase.h:50