numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
scalar_rosenbrock_equation_solver.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#include <cmath>
23#include <limits>
24#include <optional>
25
26#include <fmt/format.h> // IWYU pragma: keep
27
34
36
43template <concepts::single_variate_differentiable_problem Problem>
45public:
47 using problem_type = Problem;
48
50 using variable_type = typename problem_type::variable_type;
51
53 using scalar_type = typename problem_type::scalar_type;
54
56 using jacobian_type = typename problem_type::jacobian_type;
57
59 static constexpr bool use_time_derivative =
61
64
72 const scalar_type& inverted_jacobian_coeff)
73 : inverted_jacobian_coeff_(inverted_jacobian_coeff) {}
74
84 const scalar_type& time, const scalar_type& step_size,
85 const variable_type& variable) {
86 problem.evaluate_on(time, variable,
87 evaluation_type{.diff_coeff = true,
88 .jacobian = true,
89 .time_derivative = use_time_derivative,
90 .mass = use_mass});
91 jacobian_ = problem.jacobian();
92 if constexpr (use_time_derivative) {
93 time_derivative_ = problem.time_derivative();
94 }
95
96 auto inverted_value = static_cast<scalar_type>(1);
97 if constexpr (use_mass) {
98 inverted_value = problem.mass();
99 }
100 inverted_value -= step_size * inverted_jacobian_coeff_ * jacobian_;
101 using std::abs;
102 if (abs(inverted_value) < std::numeric_limits<scalar_type>::epsilon()) {
104 "Value to invert is too small: {}.", inverted_value);
105 }
106 inverted_coeff_ = static_cast<scalar_type>(1) / inverted_value;
107 }
108
115 void apply_jacobian(const variable_type& target, variable_type& result) {
116 result = jacobian_ * target;
117 }
118
127 const scalar_type& coeff, variable_type& target) {
128 if constexpr (use_time_derivative) {
129 if (time_derivative_) {
130 target += step_size * coeff * (*time_derivative_);
131 }
132 }
133 }
134
141 void solve(const variable_type& rhs, variable_type& result) {
142 result = inverted_coeff_ * rhs;
143 }
144
145private:
148
150 std::optional<variable_type> time_derivative_{};
151
154
157};
158
159} // namespace num_collect::ode::rosenbrock
Class of exception on failure in algorithm.
Definition exception.h:93
Class to solve equations in Rosenbrock methods for single-variate case.
std::optional< variable_type > time_derivative_
Partial derivative with respect to time.
typename problem_type::jacobian_type jacobian_type
Type of Jacobians.
void solve(const variable_type &rhs, variable_type &result)
Solve a linear equation.
void add_time_derivative_term(const scalar_type &step_size, const scalar_type &coeff, variable_type &target)
Add a term of partial derivative with respect to time.
void apply_jacobian(const variable_type &target, variable_type &result)
Multiply Jacobian to a value.
typename problem_type::variable_type variable_type
Type of variables.
void evaluate_and_update_jacobian(problem_type &problem, const scalar_type &time, const scalar_type &step_size, const variable_type &variable)
Update Jacobian and internal parameters.
scalar_rosenbrock_equation_solver(const scalar_type &inverted_jacobian_coeff)
Constructor.
static constexpr bool use_time_derivative
Whether to use partial derivative with respect to time.
scalar_type inverted_jacobian_coeff_
Coefficient multiplied to Jacobian in inverted values.
Concept of problems of ordinary differential equations with mass.
Concept of problems of ordinary differential equations differentiable by time variable.
Definition of evaluation_type enumeration.
Definition of exceptions.
Definition of macros for logging.
#define NUM_COLLECT_LOG_AND_THROW(EXCEPTION_TYPE,...)
Write an error log and throw an exception for an error.
Definition of mass_problem concept.
Definition of single_variate_differentiable_problem concept.
Struct to specify types of evaluations.
Definition of time_differentiable_problem concept.