numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
gauss_legendre_integrator.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 <complex>
23
24#include <type_traits>
25
26#include <Eigen/Core>
27
32#include "num_collect/constants/half.h" // IWYU pragma: keep
33#include "num_collect/constants/one.h" // IWYU pragma: keep
34#include "num_collect/constants/two.h" // IWYU pragma: keep
39
41
44 "num_collect::integration::gauss_legendre_integrator");
45
51template <typename Signature>
53
60template <typename Result, base::concepts::real_scalar Variable>
61class gauss_legendre_integrator<Result(Variable)>
62 : public logging::logging_mixin {
63public:
65 using variable_type = std::decay_t<Variable>;
66
68 using result_type = std::decay_t<Result>;
69
71 static constexpr index_type default_degree = 20;
72
78 explicit gauss_legendre_integrator(index_type degree = default_degree)
79 : logging::logging_mixin(gauss_legendre_integrator_tag),
80 roots_(degree) {
81 NUM_COLLECT_PRECONDITION(degree >= 1, this->logger(),
82 "Degree of Legendre function must be at least one.");
83 update_weight();
84 }
85
91 void prepare(index_type degree) {
92 NUM_COLLECT_PRECONDITION(degree >= 1, this->logger(),
93 "Degree of Legendre function must be at least one.");
94 roots_.compute(degree);
95 update_weight();
96 }
97
107 template <base::concepts::invocable_as<result_type(variable_type)> Function>
108 [[nodiscard]] auto integrate(const Function& function, variable_type left,
109 variable_type right) const -> result_type {
110 const auto degree = roots_.degree();
111 const auto mean = constants::half<variable_type> * (left + right);
112 const auto half_width = constants::half<variable_type> * (right - left);
113 Result sum = function(mean) * constants::zero<variable_type>;
114 for (index_type i = 0; i < degree; ++i) {
115 const variable_type x = mean + half_width * roots_[i];
116 const variable_type weight = weights_[i];
117 sum += weight * function(x);
118 }
119 return sum * half_width;
120 }
121
131 template <base::concepts::invocable_as<result_type(variable_type)> Function>
132 [[nodiscard]] auto operator()(const Function& function, variable_type left,
133 variable_type right) const -> result_type {
134 return integrate(function, left, right);
135 }
136
137private:
142 const auto degree = roots_.degree();
143 weights_.resize(degree);
144 for (index_type i = 0; i < degree; ++i) {
145 const variable_type x = roots_[i];
146 const auto temp = static_cast<variable_type>(degree) *
147 functions::legendre(x, degree - 1);
148 weights_[i] = constants::two<variable_type> *
149 (constants::one<variable_type> - x * x) / (temp * temp);
150 }
151 }
152
155
157 Eigen::Matrix<variable_type, Eigen::Dynamic, 1> weights_{};
158};
159
160} // namespace num_collect::integration
Class of roots of Legendre function.
void prepare(index_type degree)
Compute internal variables for integration.
auto operator()(const Function &function, variable_type left, variable_type right) const -> result_type
Integrate a function.
functions::legendre_roots< variable_type > roots_
Roots of Legendre function.
auto integrate(const Function &function, variable_type left, variable_type right) const -> result_type
Integrate a function.
Class to perform numerical integration with Gauss-Legendre formula.
Class of tags of logs without memory management.
Class to incorporate logging in algorithms.
Definition of half.
Definition of index_type type.
Definition of invocable_as concept.
Definition of legendre function.
Definition of legendre_roots function.
Definition of log_tag_view class.
Definition of logging_mixin class.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
constexpr T two
Value 2.
Definition two.h:30
constexpr T zero
Value 0.
Definition zero.h:30
constexpr T half
Value 0.5.
Definition half.h:30
constexpr T one
Value 1.
Definition one.h:30
constexpr auto legendre(F x, I n) -> F
Calculate Legendre function.
Definition legendre.h:44
Namespace of numerical integration.
constexpr auto gauss_legendre_integrator_tag
Tag of gauss_legendre_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.
Definition of two.