DryChem 1.0.0
A generic, compile-time C++ toolbox with no dependencies for the modern computational chemistry project.
Loading...
Searching...
No Matches
nPointStencil.hpp
Go to the documentation of this file.
1// Copyright (c) 2020-2025 Cody R. Drisko. All rights reserved.
2// Licensed under the MIT License. See the LICENSE file in the project root for more information.
3//
4// Name: nPointStencil.hpp
5// Author: crdrisko
6// Date: 10/06/2023-08:10:58
7// Description: Approximating the derivative of a function using an n-point stencil determined at compile time
8
9#ifndef DRYCHEM_COMMON_UTILITIES_INCLUDE_COMMON_UTILS_MATH_CALCULUS_DIFFERENTIATION_NPOINTSTENCIL_HPP
10#define DRYCHEM_COMMON_UTILITIES_INCLUDE_COMMON_UTILS_MATH_CALCULUS_DIFFERENTIATION_NPOINTSTENCIL_HPP
11
12#include <algorithm>
13#include <cstddef>
14#include <iterator>
15#include <type_traits>
16#include <vector>
17
21
22namespace CppUtils::Math
23{
24 namespace details
25 {
42 template<std::size_t N, typename ContainerX, typename ContainerY = ContainerX,
43 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<typename ContainerX::value_type>,
44 std::is_default_constructible<typename ContainerY::value_type>>>>
45 constexpr auto nPointStencilMethod(const ContainerX& x, const ContainerY& y)
46 {
47 using Ty_x = decltype(y.at(0) / x.at(0));
48
49 if (x.size() != y.size())
50 throw InputSizeMismatch {"Common-Utilities", __FILE__, __LINE__};
51
52 std::vector<Ty_x> dy_dx(x.size());
53
54 if constexpr(N == 5)
55 {
56 for (std::size_t i {2}; i < x.size() - 2; ++i)
57 {
58 dy_dx[i] = (y[i - 2] - (8 * y[i + 1]) + (8 * y[i - 1]) - y[i + 2])
59 / (12 * (x[i + 1] - x[i]));
60 }
61 }
62 else if constexpr(N == 7)
63 {
64 for (std::size_t i {3}; i < x.size() - 3; ++i)
65 {
66 dy_dx[i] = ((-1 * y[i - 3]) + (9 * y[i - 2]) - (45 * y[i + 1]) + (45 * y[i - 1]) - (9 * y[i + 2]) + y[i + 3])
67 / (60 * (x[i + 1] - x[i]));
68 }
69 }
70 else if constexpr(N == 9)
71 {
72 for (std::size_t i {4}; i < x.size() - 4; ++i)
73 {
74 dy_dx[i] = ((3 * y[i - 4]) - (32 * y[i - 3]) + (168 * y[i - 2]) - (672 * y[i + 1]) + (672 * y[i - 1]) - (168 * y[i + 2]) + (32 * y[i + 3]) - (3 * y[i + 4]))
75 / (840 * (x[i + 1] - x[i]));
76 }
77 }
78
79 return dy_dx;
80 }
81 } // namespace details
82
86 template<typename ContainerX, typename ContainerY = ContainerX,
87 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<typename ContainerX::value_type>,
88 std::is_default_constructible<typename ContainerY::value_type>>>>
89 constexpr auto fivePointStencilMethod(const ContainerX& x, const ContainerY& y) { return details::nPointStencilMethod<5>(x, y); }
90
94 template<typename ContainerX, typename ContainerY = ContainerX,
95 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<typename ContainerX::value_type>,
96 std::is_default_constructible<typename ContainerY::value_type>>>>
97 constexpr auto sevenPointStencilMethod(const ContainerX& x, const ContainerY& y) { return details::nPointStencilMethod<7>(x, y); }
98
102 template<typename ContainerX, typename ContainerY = ContainerX,
103 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<typename ContainerX::value_type>,
104 std::is_default_constructible<typename ContainerY::value_type>>>>
105 constexpr auto ninePointStencilMethod(const ContainerX& x, const ContainerY& y) { return details::nPointStencilMethod<9>(x, y); }
106} // namespace CppUtils::Math
107
108#endif
Definition mathExceptions.hpp:25
Definition nPointStencil.hpp:25
constexpr auto nPointStencilMethod(const ContainerX &x, const ContainerY &y)
Definition nPointStencil.hpp:45
Definition backwardsDifferenceMethod.hpp:20
constexpr auto fivePointStencilMethod(const ContainerX &x, const ContainerY &y)
Definition nPointStencil.hpp:89
constexpr auto ninePointStencilMethod(const ContainerX &x, const ContainerY &y)
Definition nPointStencil.hpp:105
constexpr auto sevenPointStencilMethod(const ContainerX &x, const ContainerY &y)
Definition nPointStencil.hpp:97