smooth
A C++ library for Lie theory
Loading...
Searching...
No Matches
quadrature.hpp
Go to the documentation of this file.
1// Copyright (C) 2021-2022 Petter Nilsson. MIT License.
2
3#pragma once
4
10#include <array>
11#include <numbers>
12#include <utility>
13
14#include "basis.hpp"
15#include "static_matrix.hpp"
16
17SMOOTH_BEGIN_NAMESPACE
18
19// \cond
20namespace detail {
21
23template<std::size_t K>
24constexpr auto pow_s(const auto x) noexcept
25{
26 const auto f = [&x]<auto... Is>(std::index_sequence<Is...>) {
27 return ((static_cast<void>(Is), x) * ... * 1.);
28 }; // NOLINT
29 return f(std::make_index_sequence<K>{});
30}
31
33template<std::size_t K>
34constexpr auto factorial_s() noexcept
35{
36 const auto f = []<auto... Is>(std::index_sequence<Is...>) { return ((Is + 1) * ... * 1.); }; // NOLINT
37 return f(std::make_index_sequence<K>{});
38}
39
41constexpr auto cos_s(const auto x) noexcept
42{
43 const auto f = [&x]<auto... Is>(std::index_sequence<Is...>) {
44 return ((pow_s<Is>(-1.) * pow_s<2 * Is>(x) / factorial_s<2 * Is>()) + ...);
45 }; // NOLINT
46 return f(std::make_index_sequence<8>{});
47}
48
49} // namespace detail
50// \endcond
51
57template<std::size_t K>
58constexpr std::array<double, K> cgr_nodes()
59{
60 std::array<double, K> x;
61 for (auto i = 0u; i < K; ++i) { x[i] = -detail::cos_s(2. * std::numbers::pi_v<double> * i / (2 * K - 1)); }
62 return x;
63}
64
86template<std::size_t K, std::size_t I = 8>
87 requires(K <= 40)
88constexpr std::pair<std::array<double, K>, std::array<double, K>> lgr_nodes()
89{
90 // initial guess
91 auto xs = cgr_nodes<K>();
92
93 // initialize weights
94 std::array<double, K> ws;
95 ws[0] = 2. / (K * K);
96
97 // two rightmost column of legendre basis matrix
98 constexpr auto B = polynomial_basis<PolynomialBasis::Legendre, K>().template block<K + 1, 2>(0, K - 1);
99
100 for (auto i = 1u; i < K; ++i) {
102 for (auto iter = 0u; iter < I; ++iter) {
103 U_B = monomial_derivative<K>(xs[i], 0) * B;
104 const auto dU_B = monomial_derivative<K>(xs[i], 1) * B;
105 const double fxi = U_B[0][0] + U_B[0][1];
106 const double dfxi = dU_B[0][0] + dU_B[0][1];
107 xs[i] -= fxi / dfxi;
108 }
109 ws[i] = (1. - xs[i]) / (K * K * U_B[0][0] * U_B[0][0]);
110 }
111
112 return {xs, ws};
113}
114
115SMOOTH_END_NAMESPACE
Compile-time polynomial manipulation.
constexpr std::pair< std::array< double, K >, std::array< double, K > > lgr_nodes()
Legendre-Gauss-Radau (LGR) nodes and weights on [-1, 1].
SMOOTH_BEGIN_NAMESPACE constexpr std::array< double, K > cgr_nodes()
Chebyshev-Gauss-Radau nodes on [-1, 1].
Utilities for compile-time matrix algebra.
Elementary structure for compile-time matrix algebra.