DryChem 1.0.0
A generic, compile-time C++ toolbox with no dependencies for the modern computational chemistry project.
Loading...
Searching...
No Matches
quadraticLeastSquaresFitting.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: quadraticLeastSquaresFitting.hpp
5// Author: crdrisko
6// Date: 10/11/2023-07:27:16
7// Description: Function to perform a quadratic least-squares fitting for the supplied inputs
8
9#ifndef DRYCHEM_COMMON_UTILITIES_INCLUDE_COMMON_UTILS_MATH_STATISTICS_QUADRATICLEASTSQUARESFITTING_HPP
10#define DRYCHEM_COMMON_UTILITIES_INCLUDE_COMMON_UTILS_MATH_STATISTICS_QUADRATICLEASTSQUARESFITTING_HPP
11
12#include <cstddef>
13#include <iterator>
14#include <type_traits>
15
18
19namespace CppUtils::Math
20{
21 namespace details
22 {
32 template<typename T_a, typename T_b = T_a, typename T_c = T_a,
33 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<T_a>,
34 std::is_default_constructible<T_b>,
35 std::is_default_constructible<T_c>>>>
37 {
38 T_a a {};
39 T_b b {};
40 T_c c {};
41 };
42 } // namespace details
43
66 template<typename IteratorX, typename IteratorY = IteratorX,
67 typename Tx = typename std::iterator_traits<IteratorX>::value_type,
68 typename Ty = typename std::iterator_traits<IteratorY>::value_type,
69 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<Tx>, std::is_default_constructible<Ty>>>>
70 constexpr decltype(auto) quadraticLeastSquaresFitting(IteratorX x_begin, IteratorX x_end, IteratorY y_begin, IteratorY y_end)
71 {
72 using Txx = decltype(*x_begin * *x_begin);
73 using Txxx = decltype(*x_begin * *x_begin * *x_begin);
74 using Txxxx = decltype(*x_begin * *x_begin * *x_begin * *x_begin);
75
76 using Txy = decltype(*x_begin * *y_begin);
77 using Txxy = decltype(*x_begin * *x_begin * *y_begin);
78
79 using Ty_x = decltype(*y_begin / *x_begin);
80 using Ty_xx = decltype(*y_begin / *x_begin / *x_begin);
81
82 const std::ptrdiff_t x_size {x_end - x_begin}, y_size {y_end - y_begin};
83
84 if (x_size != y_size)
85 throw InputSizeMismatch {"Common-Utilities", __FILE__, __LINE__};
86
88
89 Tx x1 {};
90 Txx x2 {};
91 Txxx x3 {};
92 Txxxx x4 {};
93
94 Ty y1 {};
95
96 Txy x1y1 {};
97 Txxy x2y1 {};
98
99 IteratorX x_iter = x_begin;
100 IteratorY y_iter = y_begin;
101
102 while (x_iter != x_end)
103 {
104 const Tx x_i = (*x_iter);
105 const Ty y_i = (*y_iter);
106
107 x1 += x_i;
108 x2 += x_i * x_i;
109 x3 += x_i * x_i * x_i;
110 x4 += x_i * x_i * x_i * x_i;
111
112 y1 += y_i;
113
114 x1y1 += x_i * y_i;
115 x2y1 += x_i * x_i * y_i;
116
117 ++x_iter;
118 ++y_iter;
119 }
120
121 auto denominator = x4 * (x2 * x_size - x1 * x1) - x3 * (x3 * x_size - x1 * x2) + x2 * (x3 * x1 - x2 * x2);
122
123 auto a_numerator = x2y1 * (x2 * x_size - x1 * x1) - x3 * (x1y1 * x_size - x1 * y1) + x2 * (x1y1 * x1 - x2 * y1);
124 auto b_numerator = x4 * (x1y1 * x_size - x1 * y1) - x2y1 * (x3 * x_size - x1 * x2) + x2 * (x3 * y1 - x1y1 * x2);
125 auto c_numerator = x4 * (x2 * y1 - x1y1 * x1) - x3 * (x3 * y1 - x1y1 * x2) + x2y1 * (x3 * x1 - x2 * x2);
126
127 results.a = a_numerator / denominator;
128 results.b = b_numerator / denominator;
129 results.c = c_numerator / denominator;
130
131 return results;
132 }
133} // namespace CppUtils::Math
134
135#endif
Definition mathExceptions.hpp:25
Definition nPointStencil.hpp:25
Definition backwardsDifferenceMethod.hpp:20
constexpr decltype(auto) quadraticLeastSquaresFitting(IteratorX x_begin, IteratorX x_end, IteratorY y_begin, IteratorY y_end)
Definition quadraticLeastSquaresFitting.hpp:70
Definition quadraticLeastSquaresFitting.hpp:37
T_c c
Definition quadraticLeastSquaresFitting.hpp:40
T_b b
Definition quadraticLeastSquaresFitting.hpp:39
T_a a
Definition quadraticLeastSquaresFitting.hpp:38