numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
pi_step_size_controller.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
30#include "num_collect/ode/error_tolerances.h" // IWYU pragma: keep
33#include "num_collect/ode/step_size_limits.h" // IWYU pragma: keep
34
35namespace num_collect::ode {
36
39 logging::log_tag_view("num_collect::ode::pi_step_size_controller");
40
46template <concepts::formula Formula>
48 : public step_size_controller_base<pi_step_size_controller<Formula>,
49 Formula> {
50public:
52 using base_type =
54
55 using typename base_type::formula_type;
56 using typename base_type::problem_type;
57 using typename base_type::scalar_type;
58 using typename base_type::variable_type;
59
63
70 static_cast<scalar_type>(0.7) /
72
79 static_cast<scalar_type>(0.4) /
81
86
90 void init() {
91 // no operation.
92 }
93
103 [[nodiscard]] auto check_and_calc_next(scalar_type& step_size,
104 const variable_type& variable, const variable_type& error) -> bool {
105 if (this->reduce_if_needed(step_size, variable, error)) {
106 return false;
107 }
108 calc_next(step_size, variable, error);
109 return true;
110 }
111
121 "0 <= previous_step_error_exponent <= "
122 "current_step_error_exponent must be satisfied.");
124 return *this;
125 }
126
135 NUM_COLLECT_PRECONDITION(static_cast<scalar_type>(0) <= val &&
137 "0 <= previous_step_error_exponent <= "
138 "current_step_error_exponent must be satisfied.");
140 return *this;
141 }
142
151 NUM_COLLECT_PRECONDITION(val > static_cast<scalar_type>(0),
152 "Safety coefficient for factors of step sizes must be a positive "
153 "value.");
155 return *this;
156 }
157
167 "0 < min_step_size_factor < max_step_size_factor must be "
168 "satisfied.");
170 return *this;
171 }
172
182 static_cast<scalar_type>(0) < val && val < max_step_size_factor_,
183 "0 < min_step_size_factor < max_step_size_factor must be "
184 "satisfied.");
186 return *this;
187 }
188
189private:
197 void calc_next(scalar_type& step_size, const variable_type& variable,
198 const variable_type& error) {
199 // First, calculate factor of step size using a formula in the
200 // reference.
201 const scalar_type error_norm =
202 this->tolerances().calc_norm(variable, error);
203 scalar_type factor = pow(error_norm, -current_step_error_exponent_) *
205
206 // Secondly, change the factor for safety.
207 using std::isfinite;
209 if (!isfinite(factor)) {
210 factor = static_cast<scalar_type>(1);
211 }
212 if (factor > max_step_size_factor_) {
213 factor = max_step_size_factor_;
214 } else if (factor < min_step_size_factor_) {
215 factor = min_step_size_factor_;
216 }
217
218 // Finally, multiply the factor to the step size.
219 step_size *= factor;
220 step_size = this->limits().apply(step_size);
221
222 // Prepare for the next step.
223 previous_step_error_ = error_norm;
224 }
225
228
232
236
239 static_cast<scalar_type>(0.9);
240
244
246 static constexpr auto default_max_step_size_factor =
247 static_cast<scalar_type>(2);
248
251
253 static constexpr auto default_min_step_size_factor =
254 static_cast<scalar_type>(0.1);
255
258};
259
260} // namespace num_collect::ode
Class of tags of logs without memory management.
Class to control step sizes using PI controller gustafsson1991.
auto previous_step_error_exponent(const scalar_type &val) -> pi_step_size_controller &
Set the exponent of the error of the previous time step.
auto min_step_size_factor(const scalar_type &val) -> pi_step_size_controller &
Set the minimum factor of step sizes.
static constexpr scalar_type default_previous_step_error_exponent
Default exponent of the error of the previous time step.
scalar_type previous_step_error_
Error of the previous time step.
scalar_type previous_step_error_exponent_
Exponent of the error of the previous time step.
static constexpr auto default_max_step_size_factor
Default maximum factor of step sizes.
static constexpr auto default_step_size_factor_safety_coeff
Default safety coefficient for factors of step sizes.
auto step_size_factor_safety_coeff(const scalar_type &val) -> pi_step_size_controller &
Set the safety coefficient for factors of step sizes.
scalar_type current_step_error_exponent_
Exponent of the error of the current time step.
scalar_type step_size_factor_safety_coeff_
Safety coefficient for factors of step sizes.
static constexpr auto default_min_step_size_factor
Default minimum factor of step sizes.
scalar_type max_step_size_factor_
Maximum factor of step sizes.
static constexpr scalar_type default_current_step_error_exponent
Default exponent of the error of the current time step.
auto max_step_size_factor(const scalar_type &val) -> pi_step_size_controller &
Set the maximum factor of step sizes.
auto check_and_calc_next(scalar_type &step_size, const variable_type &variable, const variable_type &error) -> bool
Check the error estimate and calculate the next step size.
void calc_next(scalar_type &step_size, const variable_type &variable, const variable_type &error)
Calculate the next step size.
static constexpr index_type formula_order_for_exponent
Order of the formula used in exponents.
scalar_type min_step_size_factor_
Minimum factor of step sizes.
auto current_step_error_exponent(const scalar_type &val) -> pi_step_size_controller &
Set the exponent of the error of the current time step.
Base class of classes to control step sizes.
auto reduce_if_needed(scalar_type &step_size, const variable_type &variable, const variable_type &error) -> bool
Definition of error_tolerances class.
Definition of exceptions.
Definition of formula concept.
Definition of get_least_known_order function.
Definition of index_type type.
Definition of log_tag_view class.
Definition of macros for logging.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
auto isfinite(const T &val) -> bool
Check whether a number is finite.
Definition isfinite.h:39
constexpr auto get_least_known_order() -> index_type
Get the least known order of a formula.
Namespace of solvers of ordinary differential equations (ODE).
constexpr auto pi_step_size_controller_log_tag
Log tag.
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 step_size_controller_base class.
Definition of step_size_limits class.