DryChem 1.0.0
A generic, compile-time C++ toolbox with no dependencies for the modern computational chemistry project.
Loading...
Searching...
No Matches
integration.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: integration.hpp
5// Author: crdrisko
6// Date: 10/28/2020-07:49:21
7// Description:Some advanced mathematical functions relating to approximate integration methods
8
9#ifndef DRYCHEM_COMMON_UTILITIES_INCLUDE_COMMON_UTILS_MATH_CALCULUS_INTEGRATION_HPP
10#define DRYCHEM_COMMON_UTILITIES_INCLUDE_COMMON_UTILS_MATH_CALCULUS_INTEGRATION_HPP
11
12#include <cstddef>
13#include <iterator>
14#include <optional>
15#include <type_traits>
16#include <utility>
17#include <vector>
18
20
21namespace CppUtils::Math
22{
38 template<typename Tx, typename Ty = Tx>
39 constexpr auto trapz(Tx x1, Tx x2, Ty y1, Ty y2) noexcept
40 {
41 return ((x2 - x1) * (y1 + y2)) / 2;
42 }
43
44
65 template<typename IteratorX, typename IteratorY = IteratorX,
66 typename Tx = typename std::iterator_traits<IteratorX>::value_type,
67 typename Ty = typename std::iterator_traits<IteratorY>::value_type,
68 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<Tx>, std::is_default_constructible<Ty>>>>
69 constexpr auto cumulativeTrapzIntegration(IteratorX x_begin, IteratorX x_end, IteratorY y_begin, IteratorY y_end,
70 std::optional<decltype(*x_begin * *y_begin)> initialValue = std::nullopt)
71 {
72 using Txy = decltype(*x_begin * *y_begin);
73
74 std::ptrdiff_t x_size {x_end - x_begin}, y_size {y_end - y_begin};
75
76 if (x_size != y_size)
77 throw InputSizeMismatch {"Common-Utilities", __FILE__, __LINE__};
78
79 const Txy init {};
80 std::vector<Txy> y_cumulative;
81
82 IteratorX x_iter = x_begin;
83 IteratorY y_iter = y_begin;
84
85 if (initialValue)
86 y_cumulative.push_back(init);
87
88 for (std::size_t i {}; i < static_cast<std::size_t>(x_size - 1); ++i, ++x_iter, ++y_iter)
89 {
90 Txy temp = trapz(*x_iter, *(x_iter + 1), *y_iter, *(y_iter + 1));
91
92 if (!initialValue)
93 {
94 if (i == 0)
95 y_cumulative.push_back(temp);
96 else
97 y_cumulative.push_back(y_cumulative[i - 1] + temp);
98 }
99 else
100 y_cumulative.push_back(y_cumulative[i] + temp);
101 }
102
103 // Replace initial value if there is a non-zero value to replace
104 if (initialValue && initialValue.value() != init)
105 y_cumulative[0] = initialValue.value();
106
107 return y_cumulative;
108 }
109
113 template<typename ContainerX, typename ContainerY = ContainerX,
114 typename Tx = typename ContainerX::value_type,
115 typename Ty = typename ContainerY::value_type,
116 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<Tx>, std::is_default_constructible<Ty>>>>
117 constexpr auto cumulativeTrapzIntegration(const ContainerX& x, const ContainerY& y,
118 std::optional<decltype(std::declval<Tx>() * std::declval<Ty>())> initialValue = std::nullopt)
119 {
120 return cumulativeTrapzIntegration(x.begin(), x.end(), y.begin(), y.end(), initialValue);
121 }
122} // namespace CppUtils::Math
123
124#endif
Definition mathExceptions.hpp:25
Definition backwardsDifferenceMethod.hpp:20
constexpr auto trapz(Tx x1, Tx x2, Ty y1, Ty y2) noexcept
Definition integration.hpp:39
constexpr auto cumulativeTrapzIntegration(IteratorX x_begin, IteratorX x_end, IteratorY y_begin, IteratorY y_end, std::optional< decltype(*x_begin **y_begin)> initialValue=std::nullopt)
Definition integration.hpp:69