numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
tanh_finite_integrator.h
Go to the documentation of this file.
1/*
2 * Copyright 2024 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> // IWYU pragma: keep
23#include <cstddef>
24#include <type_traits>
25#include <vector>
26
39
41
44 logging::log_tag_view("num_collect::integration::tanh_finite_integrator");
45
46namespace impl {
47
53template <typename Variable>
55
59template <>
61public:
63 static constexpr double default_max_point = 10.0F;
64};
65
69template <>
71public:
73 static constexpr double default_max_point = 20.0;
74};
75
76} // namespace impl
77
84template <typename Signature>
86
94template <typename Result, base::concepts::real_scalar Variable>
95class tanh_finite_integrator<Result(Variable)> : public logging::logging_mixin {
96public:
98 using variable_type = std::decay_t<Variable>;
99
101 using result_type = std::decay_t<Result>;
102
110
120 template <base::concepts::invocable_as<result_type(variable_type)> Function>
121 [[nodiscard]] auto integrate(const Function& function, variable_type left,
122 variable_type right) const -> result_type {
123 const variable_type center =
124 constants::half<variable_type> * (left + right);
125 const variable_type width = right - left;
126
127 constexpr auto center_weight_rate = static_cast<variable_type>(0.5);
128 const variable_type center_weight = width * center_weight_rate;
130 sum += function(center) * center_weight;
131
132 for (index_type i = 0; i < points_; ++i) {
133 const variable_type variable_distance =
134 width * variable_rate_list_[static_cast<std::size_t>(i)];
135 const variable_type weight =
136 width * weight_rate_list_[static_cast<std::size_t>(i)];
137
138 const variable_type var_plus = right - variable_distance;
139 const variable_type var_minus = left + variable_distance;
140 const result_type function_values =
141 function(var_plus) + function(var_minus);
142 if (!base::isfinite(function_values)) [[unlikely]] {
144 "A function value was not a finite value. "
145 "Stopped numerical integration.");
146 break;
147 }
148 sum += function_values * weight;
149 }
150
151 return sum.sum() * interval_;
152 }
153
168 template <base::concepts::invocable_as<result_type(variable_type)>
169 LeftBoundaryFunction,
170 base::concepts::invocable_as<result_type(variable_type)>
171 RightBoundaryFunction>
172 [[nodiscard]] auto integrate(
173 const LeftBoundaryFunction& left_boundary_function,
174 const RightBoundaryFunction& right_boundary_function,
175 variable_type left, variable_type right) const -> result_type {
176 using constants::half;
177
178 const variable_type width = right - left;
179 const variable_type half_width = half<variable_type> * width;
180
181 constexpr auto center_weight_rate = static_cast<variable_type>(0.5);
182 const variable_type center_weight = width * center_weight_rate;
184 sum += left_boundary_function(half_width) * center_weight;
185
186 for (index_type i = 0; i < points_; ++i) {
187 const variable_type variable_distance =
188 width * variable_rate_list_[static_cast<std::size_t>(i)];
189 const variable_type weight =
190 width * weight_rate_list_[static_cast<std::size_t>(i)];
191
192 const result_type function_values =
193 left_boundary_function(variable_distance) +
194 right_boundary_function(-variable_distance);
195 if (!base::isfinite(function_values)) [[unlikely]] {
197 "A function value was not a finite value. "
198 "Stopped numerical integration.");
199 break;
200 }
201 sum += function_values * weight;
202 }
203
204 return sum.sum() * interval_;
205 }
206
216 template <base::concepts::invocable_as<result_type(variable_type)> Function>
217 [[nodiscard]] auto operator()(const Function& function, variable_type left,
218 variable_type right) const -> result_type {
219 return integrate(function, left, right);
220 }
221
236 template <base::concepts::invocable_as<result_type(variable_type)>
237 LeftBoundaryFunction,
238 base::concepts::invocable_as<result_type(variable_type)>
239 RightBoundaryFunction>
240 [[nodiscard]] auto operator()(
241 const LeftBoundaryFunction& left_boundary_function,
242 const RightBoundaryFunction& right_boundary_function,
243 variable_type left, variable_type right) const -> result_type {
244 return integrate(
245 left_boundary_function, right_boundary_function, left, right);
246 }
247
255 NUM_COLLECT_PRECONDITION(val > static_cast<variable_type>(0),
256 this->logger(), "Maximum point must be a positive value.");
257 max_point_ = val;
259 return *this;
260 }
261
269 NUM_COLLECT_PRECONDITION(val > 0, this->logger(),
270 "Number of points must a positive integer.");
271 points_ = val;
273 return *this;
274 }
275
276private:
283 using constants::one;
284
285 variable_rate_list_.clear();
286 variable_rate_list_.reserve(static_cast<std::size_t>(points_));
287 weight_rate_list_.clear();
288 weight_rate_list_.reserve(static_cast<std::size_t>(points_));
289
290 interval_ = max_point_ / static_cast<variable_type>(points_);
291 for (index_type i = 1; i <= points_; ++i) {
292 const variable_type changed_variable =
293 interval_ * static_cast<variable_type>(i);
294 const variable_type exp_value =
295 std::exp(static_cast<variable_type>(-2) * changed_variable);
296 const variable_type denominator = one<variable_type> + exp_value;
297 variable_rate_list_.push_back(exp_value / denominator);
298 weight_rate_list_.push_back(static_cast<variable_type>(2) *
299 exp_value / (denominator * denominator));
300 }
301 }
302
304 static constexpr auto default_max_point =
306
309
311 static constexpr index_type default_points = 50;
312
315
318
320 std::vector<variable_type> variable_rate_list_{};
321
323 std::vector<variable_type> weight_rate_list_{};
324};
325
326} // namespace num_collect::integration
std::vector< variable_type > variable_rate_list_
List of rates of distances of points from the upper bound.
auto operator()(const LeftBoundaryFunction &left_boundary_function, const RightBoundaryFunction &right_boundary_function, variable_type left, variable_type right) const -> result_type
Integrate a function.
auto integrate(const LeftBoundaryFunction &left_boundary_function, const RightBoundaryFunction &right_boundary_function, variable_type left, variable_type right) const -> result_type
Integrate a function.
auto integrate(const Function &function, variable_type left, variable_type right) const -> result_type
Integrate a function.
static constexpr index_type default_points
Default number of points.
auto max_point(variable_type val) -> tanh_finite_integrator &
Set maximum point in changed variable.
static constexpr auto default_max_point
Default maximum point in changed variable.
std::vector< variable_type > weight_rate_list_
List of rates of weights of points.
auto operator()(const Function &function, variable_type left, variable_type right) const -> result_type
Integrate a function.
auto points(index_type val) -> tanh_finite_integrator &
Set number of points.
Class to perform numerical integration on finite range using TANH rule.
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 to add numbers using Kahan summation kahan1965.
Definition kahan_adder.h:32
auto sum() const noexcept -> const T &
Get sum.
Definition of exceptions.
Definition of half.
Definition of index_type type.
Definition of invocable_as concept.
Definition of isfinite function.
Definition of kahan_adder class.
Definition of log_tag_view class.
Definition of macros for logging.
#define NUM_COLLECT_LOG_WARNING(LOGGER,...)
Write a warning log.
Definition of logging_mixin class.
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 T half
Value 0.5.
Definition half.h:30
constexpr T one
Value 1.
Definition one.h:30
Namespace of internal implementations.
Namespace of numerical integration.
constexpr auto tanh_finite_integrator_tag
Tag of de_finite_integrator.
Definition of one.
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 concept.
static constexpr double default_max_point
Default maximum point in changed variable.
static constexpr double default_max_point
Default maximum point in changed variable.
Helper class of constants for use in tanh_finite_integrator class.