numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
gmres.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22// IWYU pragma: no_include <utility>
23// IWYU pragma: no_include <Eigen/SparseCore>
24
25#include <limits>
26
27#include <Eigen/Core>
28#include <Eigen/QR>
29
35
36namespace num_collect::ode::impl {
37
44template <base::concepts::real_scalar_dense_vector Vector>
45class gmres {
46public:
48 using vector_type = Vector;
49
51 using scalar_type = typename vector_type::Scalar;
52
54 using matrix_type = Eigen::MatrixX<scalar_type>;
55
72 template <typename CoeffFunction>
73 void solve(CoeffFunction&& coeff_function, const vector_type& rhs,
74 vector_type& solution) {
75 if (max_subspace_dim_ > solution.size()) {
76 max_subspace_dim_ = solution.size();
77 }
78
79 // Initialize matrices.
80 basis_.resize(solution.size(), max_subspace_dim_);
82 hessenberg_.setZero();
83 temp_rhs_.resize(max_subspace_dim_ + 1);
84 temp_rhs_.setZero();
86
87 const scalar_type residual_thresh =
88 rhs.norm() * std::numeric_limits<scalar_type>::epsilon();
89
90 index_type k = 0;
91 coeff_function(solution, residual_);
92 residual_ = rhs - residual_;
93 const scalar_type initial_residual_norm = residual_.norm();
94 scalar_type residual_norm = initial_residual_norm;
95 while (residual_norm > residual_thresh && k < max_subspace_dim_) {
96 basis_.col(k) = residual_ / residual_norm;
97 ++k;
98 coeff_function(basis_.col(k - 1), residual_);
99 for (index_type i = 0; i < k; ++i) {
100 scalar_type& current_coeff = hessenberg_(i, k - 1);
101 current_coeff = basis_.col(i).dot(residual_);
102 residual_ -= current_coeff * basis_.col(i);
103 }
104 residual_norm = residual_.norm();
105 hessenberg_(k, k - 1) = residual_norm;
106 }
107 if (k == 0) {
108 return;
109 }
110 qr_.compute(hessenberg_.topLeftCorner(k + 1, k));
111 temp_rhs_(0) = initial_residual_norm;
112 temp_sol_.head(k) = qr_.solve(temp_rhs_.head(k + 1));
113 solution += basis_.leftCols(k) * temp_sol_.head(k);
114 }
115
124 "Maximum number of dimensions of subspace must be a positive "
125 "integer.");
126 max_subspace_dim_ = val;
127 return *this;
128 }
129
130private:
133
136
139
142
145
147 Eigen::VectorX<scalar_type> temp_rhs_{};
148
150 Eigen::VectorX<scalar_type> temp_sol_{};
151
153 Eigen::ColPivHouseholderQR<matrix_type> qr_{};
154};
155
156} // namespace num_collect::ode::impl
Class to solve linear equations using generalized minimal residual (GMRES) golub2013.
Definition gmres.h:45
Eigen::MatrixX< scalar_type > matrix_type
Type of matrices.
Definition gmres.h:54
Eigen::VectorX< scalar_type > temp_rhs_
Temporary vector for solving internal equation.
Definition gmres.h:147
static constexpr index_type default_max_subspace_dim
Default maximum number of dimensions of subspace.
Definition gmres.h:132
Eigen::VectorX< scalar_type > temp_sol_
Temporary vector for solving internal equation.
Definition gmres.h:150
vector_type residual_
Residual.
Definition gmres.h:138
matrix_type basis_
Basis of subspace.
Definition gmres.h:141
void solve(CoeffFunction &&coeff_function, const vector_type &rhs, vector_type &solution)
Solve.
Definition gmres.h:73
index_type max_subspace_dim_
Maximum number of dimensions of subspace.
Definition gmres.h:135
auto max_subspace_dim(index_type val) -> gmres &
Set the maximum number of dimensions of subspace.
Definition gmres.h:122
Eigen::ColPivHouseholderQR< matrix_type > qr_
QR decomposition.
Definition gmres.h:153
typename vector_type::Scalar scalar_type
Type of scalars.
Definition gmres.h:51
matrix_type hessenberg_
Hessenberg matrix.
Definition gmres.h:144
Vector vector_type
Type of vectors.
Definition gmres.h:48
Definition of exceptions.
Definition of index_type type.
Definition of macros for logging.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Namespace of internal implementations.
Definition of NUM_COLLECT_PRECONDITION macro.
#define NUM_COLLECT_PRECONDITION(CONDITION,...)
Check whether a precondition is satisfied and throw an exception if not.
Definition of real_scalar_dense_vector concept.