numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
bicgstab.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 <Eigen/Core>
23// IWYU pragma: no_include <Eigen/SparseCore>
24
25#include <cmath>
26#include <limits>
27
35
36namespace num_collect::ode::impl {
37
39constexpr auto bicgstab_tag =
40 logging::log_tag_view("num_collect::ode::impl::bicgstab");
41
47template <base::concepts::real_scalar_dense_vector Vector>
49public:
51 using vector_type = Vector;
52
54 using scalar_type = typename vector_type::Scalar;
55
57 using matrix_type = Eigen::MatrixX<scalar_type>;
58
61
78 template <base::concepts::invocable<const vector_type&, vector_type&>
79 CoeffFunction>
80 void solve(CoeffFunction&& coeff_function, const vector_type& rhs,
81 vector_type& solution) {
82 using std::abs;
83
84 iterations_ = 0;
85 initialize(coeff_function, rhs, solution);
86
87 scalar_type residual_norm = tolerances_.calc_norm(rhs, residual_);
88 if (residual_norm <= tolerance_rate_) {
90 "No iteration needed. residual_norm={}", residual_norm);
91 return;
92 }
93
94 while (true) {
95 coeff_function(p_, ap_);
96 const scalar_type as_dot = r0_.dot(ap_);
97 if (abs(as_dot) < std::numeric_limits<scalar_type>::min()) {
99 this->logger(), "No further iteration can be done.");
100 return;
101 }
102 const scalar_type mu = rho_ / r0_.dot(ap_);
103 residual_ -= mu * ap_; // s in reference.
104
105 coeff_function(residual_, as_);
106 const scalar_type as_norm2 = as_.squaredNorm();
107 solution += mu * p_;
108 if (abs(as_norm2) < std::numeric_limits<scalar_type>::min()) {
109 initialize(coeff_function, rhs, solution);
110 ++iterations_;
111 continue;
112 }
113 const scalar_type omega = residual_.dot(as_) / as_norm2;
114 solution += omega * residual_;
115 residual_ -= omega * as_; // r in reference.
116
117 residual_norm = tolerances_.calc_norm(rhs, residual_);
118 if (residual_norm <= tolerance_rate_ ||
121 "Finished iterations: iterations={}, residual_norm={}",
122 iterations_, residual_norm);
123 return;
124 }
125
126 const scalar_type rho_old = rho_;
127 rho_ = r0_.dot(residual_);
128 const scalar_type tau = rho_ * mu / (rho_old * omega);
129 p_ = residual_ + tau * (p_ - omega * ap_);
130
131 ++iterations_;
132 }
133 }
134
142 tolerances_ = val;
143 return *this;
144 }
145
151 auto iterations() -> index_type { return iterations_; }
152
153private:
164 template <base::concepts::invocable<const vector_type&, vector_type&>
165 CoeffFunction>
166 void initialize(CoeffFunction&& coeff_function, const vector_type& rhs,
167 const vector_type& solution) {
168 coeff_function(solution, residual_);
169 residual_ = rhs - residual_;
170 r0_ = residual_;
171 p_ = residual_;
172 rho_ = r0_.dot(residual_);
173 }
174
177
179 static constexpr index_type default_max_iterations = 1000;
180
183
186
188 static constexpr auto default_tolerance_rate =
189 static_cast<scalar_type>(1e-2);
190
193
196
208};
209
210} // namespace num_collect::ode::impl
Class of tags of logs without memory management.
Class to incorporate logging in algorithms.
logging_mixin(log_tag_view tag)
Constructor.
auto logger() const noexcept -> const num_collect::logging::logger &
Access to the logger.
Class of error tolerances hairer1993.
Class to solve linear equations using BiCGstab golub2013.
Definition bicgstab.h:48
auto tolerances(const error_tolerances< vector_type > &val) -> bicgstab &
Set the error tolerances.
Definition bicgstab.h:141
Eigen::MatrixX< scalar_type > matrix_type
Type of matrices.
Definition bicgstab.h:57
index_type max_iterations_
Maximum number of iterations.
Definition bicgstab.h:182
void initialize(CoeffFunction &&coeff_function, const vector_type &rhs, const vector_type &solution)
Initialize.
Definition bicgstab.h:166
static constexpr index_type default_max_iterations
Default maximum number of iterations.
Definition bicgstab.h:179
typename vector_type::Scalar scalar_type
Type of scalars.
Definition bicgstab.h:54
void solve(CoeffFunction &&coeff_function, const vector_type &rhs, vector_type &solution)
Solve.
Definition bicgstab.h:80
index_type iterations_
Number of iterations.
Definition bicgstab.h:176
vector_type residual_
Residual.
Definition bicgstab.h:195
error_tolerances< vector_type > tolerances_
Tolerances.
Definition bicgstab.h:185
static constexpr auto default_tolerance_rate
Default rate of tolerance in this solver.
Definition bicgstab.h:188
auto iterations() -> index_type
Get the number of iterations.
Definition bicgstab.h:151
Vector vector_type
Type of vectors.
Definition bicgstab.h:51
scalar_type tolerance_rate_
Rate of tolerance in this solver.
Definition bicgstab.h:192
Definition of error_tolerances class.
Definition of index_type type.
Definition of invocable concept.
Definition of log_tag_view class.
Definition of macros for logging.
#define NUM_COLLECT_LOG_WARNING(LOGGER,...)
Write a warning log.
#define NUM_COLLECT_LOG_DEBUG(LOGGER,...)
Write a debug log.
Definition of logging_mixin class.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Namespace of internal implementations.
constexpr auto bicgstab_tag
Log tag.
Definition bicgstab.h:39
Definition of real_scalar_dense_vector concept.