Eigen  5.0.1
 
Loading...
Searching...
No Matches
BasicPreconditioners.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2011-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_BASIC_PRECONDITIONERS_H
12#define EIGEN_BASIC_PRECONDITIONERS_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
39template <typename Scalar_>
40class DiagonalPreconditioner {
41 using Scalar = Scalar_;
42 using Vector = Matrix<Scalar, Dynamic, 1>;
43
44 public:
45 using StorageIndex = typename Vector::StorageIndex;
46 enum { ColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic };
47
48 DiagonalPreconditioner() = default;
49
50 template <typename MatType>
51 explicit DiagonalPreconditioner(const MatType& mat) : m_invdiag(mat.cols()) {
52 compute(mat);
53 }
54
55 constexpr Index rows() const noexcept { return m_invdiag.size(); }
56 constexpr Index cols() const noexcept { return m_invdiag.size(); }
57
58 template <typename MatType>
59 DiagonalPreconditioner& analyzePattern(const MatType&) {
60 return *this;
61 }
62
63 template <typename MatType>
64 DiagonalPreconditioner& factorize(const MatType& mat) {
65 m_invdiag.resize(mat.cols());
66 for (Index j = 0; j < mat.outerSize(); ++j) {
67 typename MatType::InnerIterator it(mat, j);
68 while (it && it.index() != j) ++it;
69 if (it && it.index() == j && it.value() != Scalar(0))
70 m_invdiag(j) = Scalar(1) / it.value();
71 else
72 m_invdiag(j) = Scalar(1);
73 }
74 m_isInitialized = true;
75 return *this;
76 }
77
78 template <typename MatType>
79 DiagonalPreconditioner& compute(const MatType& mat) {
80 return factorize(mat);
81 }
82
84 template <typename Rhs, typename Dest>
85 void _solve_impl(const Rhs& b, Dest& x) const {
86 x = m_invdiag.array() * b.array();
87 }
88
89 template <typename Rhs>
90 inline Solve<DiagonalPreconditioner, Rhs> solve(const MatrixBase<Rhs>& b) const {
91 eigen_assert(m_isInitialized && "DiagonalPreconditioner is not initialized.");
92 eigen_assert(m_invdiag.size() == b.rows() &&
93 "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b");
94 return Solve<DiagonalPreconditioner, Rhs>(*this, b.derived());
95 }
96
97 ComputationInfo info() const { return Success; }
98
99 protected:
100 Vector m_invdiag;
101 bool m_isInitialized = false;
102};
103
121template <typename Scalar_>
122class LeastSquareDiagonalPreconditioner : public DiagonalPreconditioner<Scalar_> {
123 using Scalar = Scalar_;
124 using RealScalar = typename NumTraits<Scalar>::Real;
125 using Base = DiagonalPreconditioner<Scalar_>;
126 using Base::m_invdiag;
127
128 public:
129 LeastSquareDiagonalPreconditioner() = default;
130
131 template <typename MatType>
132 explicit LeastSquareDiagonalPreconditioner(const MatType& mat) : Base() {
133 compute(mat);
134 }
135
136 template <typename MatType>
137 LeastSquareDiagonalPreconditioner& analyzePattern(const MatType&) {
138 return *this;
139 }
140
141 template <typename MatType>
142 LeastSquareDiagonalPreconditioner& factorize(const MatType& mat) {
143 // Compute the inverse squared-norm of each column of mat
144 m_invdiag.resize(mat.cols());
145 EIGEN_IF_CONSTEXPR (MatType::IsRowMajor) {
146 m_invdiag.setZero();
147 for (Index j = 0; j < mat.outerSize(); ++j) {
148 for (typename MatType::InnerIterator it(mat, j); it; ++it) m_invdiag(it.index()) += numext::abs2(it.value());
149 }
150 for (Index j = 0; j < mat.cols(); ++j) {
151 RealScalar sum = numext::real(m_invdiag(j));
152 m_invdiag(j) = sum > RealScalar(0) ? RealScalar(1) / sum : RealScalar(1);
153 }
154 } else {
155 for (Index j = 0; j < mat.outerSize(); ++j) {
156 RealScalar sum = mat.col(j).squaredNorm();
157 m_invdiag(j) = sum > RealScalar(0) ? RealScalar(1) / sum : RealScalar(1);
158 }
159 }
160 Base::m_isInitialized = true;
161 return *this;
162 }
163
164 template <typename MatType>
165 LeastSquareDiagonalPreconditioner& compute(const MatType& mat) {
166 return factorize(mat);
167 }
168
169 ComputationInfo info() const { return Success; }
170};
171
179class IdentityPreconditioner {
180 public:
181 IdentityPreconditioner() = default;
182
183 template <typename MatrixType>
184 explicit IdentityPreconditioner(const MatrixType&) {}
185
186 template <typename MatrixType>
187 IdentityPreconditioner& analyzePattern(const MatrixType&) {
188 return *this;
189 }
190
191 template <typename MatrixType>
192 IdentityPreconditioner& factorize(const MatrixType&) {
193 return *this;
194 }
195
196 template <typename MatrixType>
197 IdentityPreconditioner& compute(const MatrixType&) {
198 return *this;
199 }
200
201 template <typename Rhs>
202 inline const Rhs& solve(const Rhs& b) const {
203 return b;
204 }
205
206 ComputationInfo info() const { return Success; }
207};
208
209} // end namespace Eigen
210
211#endif // EIGEN_BASIC_PRECONDITIONERS_H
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 Solve.h:63
ComputationInfo
Definition Constants.h:455
@ Success
Definition Constants.h:457