numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
iterative_solver_base.h
Go to the documentation of this file.
1/*
2 * Copyright 2023 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#include <Eigen/Core>
23#include <Eigen/IterativeLinearSolvers>
24#include <Eigen/SparseCore>
25
32
33namespace num_collect::linear {
34
35namespace impl {
36
42template <typename Solver, typename /*reserved for SFINAE*/ = void>
43struct iterative_solver_traits; // IWYU pragma: keep
44
45} // namespace impl
46
52template <typename Derived>
53class iterative_solver_base : public Eigen::SparseSolverBase<Derived> {
54protected:
56 using Base = Eigen::SparseSolverBase<Derived>;
57 using Base::m_isInitialized;
58
59public:
61 using MatrixType =
64 using Scalar = typename MatrixType::Scalar;
66 using StorageIndex = typename MatrixType::StorageIndex;
68 using RealScalar = typename MatrixType::RealScalar;
69
78
79 enum { // NOLINT(performance-enum-size): Preserve the same implementation as Eigen library.
81 ColsAtCompileTime = MatrixType::ColsAtCompileTime, // NOLINT
83 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime // NOLINT
84 };
85
86 using Base::derived;
87
91 iterative_solver_base() { m_isInitialized = false; }
92
101 auto compute(const matrix_type& coeff) -> Derived& {
102 coeff_ = &coeff;
103 m_isInitialized = true;
104 return derived();
105 }
106
112 [[nodiscard]] auto rows() const noexcept -> Eigen::Index {
113 return coeff().rows();
114 }
115
121 [[nodiscard]] auto cols() const noexcept -> Eigen::Index {
122 return coeff().cols();
123 }
124
130 [[nodiscard]] auto tolerance() const noexcept -> real_scalar_type {
131 return tolerance_;
132 }
133
140 auto tolerance(const real_scalar_type& val) -> Derived& {
141 NUM_COLLECT_PRECONDITION(val > static_cast<real_scalar_type>(0),
142 "Tolerance of rate of residual must be positive value.");
143 tolerance_ = val;
144 return derived();
145 }
146
152 [[nodiscard]] auto max_iterations() const noexcept -> index_type {
153 return max_iterations_;
154 }
155
162 auto max_iterations(index_type val) -> Derived& {
164 "Maximum number of iterations must be a positive integer.");
165 max_iterations_ = val;
166 return derived();
167 }
168
176 template <base::concepts::dense_vector_of<scalar_type> Right>
177 [[nodiscard]] auto solve(const Right& right) const
178 -> Eigen::Solve<Derived, Right> {
179 // TODO: Version for matrices.
180 return Eigen::Solve<Derived, Right>(derived(), right);
181 }
182
192 template <base::concepts::dense_vector_of<scalar_type> Right,
193 base::concepts::dense_vector_of<scalar_type> Solution>
194 [[nodiscard]] auto solve_with_guess(
195 const Right& right, const Solution& solution) const
196 -> Eigen::SolveWithGuess<Derived, Right, Solution> {
197 // TODO: Version for matrices.
198 return Eigen::SolveWithGuess<Derived, Right, Solution>(
199 derived(), right, solution);
200 }
201
210 template <base::concepts::dense_vector_of<scalar_type> Right,
211 base::concepts::dense_vector_of<scalar_type> Solution>
212 void _solve_impl( // NOLINT(readability-identifier-naming
213 // name required by Eigen.
214 const Right& right, Solution& solution) const {
215 // TODO: Version for matrices.
216 solution.setZero();
217 derived()._solve_with_guess_impl(right, solution);
218 }
219
228 template <base::concepts::dense_vector_of<scalar_type> Right,
229 base::concepts::dense_vector_of<scalar_type> Solution>
230 void _solve_with_guess_impl( // NOLINT(readability-identifier-naming
231 // name required by Eigen.
232 const Right& right, Solution& solution) const {
233 // TODO: Version for matrices.
234 derived().solve_vector_in_place(right, solution);
235 }
236
237protected:
243 [[nodiscard]] auto coeff() const noexcept -> const matrix_type& {
244 NUM_COLLECT_ASSERT(static_cast<const void*>(coeff_) != nullptr);
245 return *coeff_;
246 }
247
248private:
250 static constexpr index_type default_max_iterations = 10000;
251
254
256 static constexpr auto default_tolerance =
257 Eigen::NumTraits<real_scalar_type>::dummy_precision();
258
261
263 const matrix_type* coeff_{nullptr};
264};
265
266} // namespace num_collect::linear
Definition of assertion macros.
#define NUM_COLLECT_ASSERT(CONDITION)
Macro to check whether a condition is satisfied.
Definition assert.h:66
typename MatrixType::RealScalar RealScalar
Type of real scalars. (For Eigen library.)
StorageIndex storage_index_type
Type of indices in storages.
index_type max_iterations_
Maximum number of iterations.
static constexpr index_type default_max_iterations
Default maximum number of iterations.
typename impl::iterative_solver_traits< Derived >::matrix_type MatrixType
Type of matrices. (For Eigen library.)
auto coeff() const noexcept -> const matrix_type &
Get the coefficient matrix.
@ MaxColsAtCompileTime
Maximum number of columns at compile time. (For Eigen library.)
@ ColsAtCompileTime
Number of columns at compile time. (For Eigen library.)
Eigen::SparseSolverBase< Derived > Base
Base class.
auto max_iterations(index_type val) -> Derived &
Set the maximum number of iterations.
auto solve_with_guess(const Right &right, const Solution &solution) const -> Eigen::SolveWithGuess< Derived, Right, Solution >
Solve a linear equation with a guess of the solution.
const matrix_type * coeff_
Coefficient matrix.
auto solve(const Right &right) const -> Eigen::Solve< Derived, Right >
Solve a linear equation.
typename MatrixType::StorageIndex StorageIndex
Type of indices in storages. (For Eigen library.)
auto cols() const noexcept -> Eigen::Index
Get the number of columns.
void _solve_impl(const Right &right, Solution &solution) const
Internal function to solve for a right-hand-side vector.
auto tolerance() const noexcept -> real_scalar_type
Get the tolerance of rate of residual.
static constexpr auto default_tolerance
Default tolerance of rate of residual.
auto tolerance(const real_scalar_type &val) -> Derived &
Set the tolerance of rate of residual.
typename MatrixType::Scalar Scalar
Type of scalars. (For Eigen library.)
auto rows() const noexcept -> Eigen::Index
Get the number of rows.
real_scalar_type tolerance_
Tolerance of rate of residual.
RealScalar real_scalar_type
Type of real scalars.
auto compute(const matrix_type &coeff) -> Derived &
Initialize this solver using a coefficient matrix.
void _solve_with_guess_impl(const Right &right, Solution &solution) const
Internal function to solve for a right-hand-side vector.
auto max_iterations() const noexcept -> index_type
Get the maximum number of iterations.
Definition of dense_vector_of concept.
Definition of exceptions.
Definition of index_type type.
Definition of macros for logging.
Namespace of Eigen library.
Definition variable.h:416
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Namespace of solvers of linear equations.
Definition of NUM_COLLECT_PRECONDITION macro.
#define NUM_COLLECT_PRECONDITION(CONDITION,...)
Check whether a precondition is satisfied and throw an exception if not.