DryChem 1.0.0
A generic, compile-time C++ toolbox with no dependencies for the modern computational chemistry project.
Loading...
Searching...
No Matches
linearLeastSquaresFitting.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: linearLeastSquaresFitting.hpp
5// Author: crdrisko
6// Date: 10/26/2020-11:46:29
7// Description: Function to perform a linear least-squares fitting for the supplied inputs
8
9#ifndef DRYCHEM_COMMON_UTILITIES_INCLUDE_COMMON_UTILS_MATH_STATISTICS_LINEARLEASTSQUARESFITTING_HPP
10#define DRYCHEM_COMMON_UTILITIES_INCLUDE_COMMON_UTILS_MATH_STATISTICS_LINEARLEASTSQUARESFITTING_HPP
11
12#include <cstddef>
13#include <iterator>
14#include <type_traits>
15
18
19namespace CppUtils::Math
20{
21 namespace details
22 {
30 template<typename T_slope, typename T_intercept = T_slope, typename T_variance = T_slope,
31 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<T_slope>,
32 std::is_default_constructible<T_intercept>,
33 std::is_default_constructible<T_variance>>>>
35 {
36 T_slope slope {};
37 T_intercept intercept {};
38 T_variance variance {};
39 };
40 } // namespace details
41
67 template<typename IteratorX, typename IteratorY = IteratorX,
68 typename Tx = typename std::iterator_traits<IteratorX>::value_type,
69 typename Ty = typename std::iterator_traits<IteratorY>::value_type,
70 typename = std::enable_if_t<std::conjunction_v<std::is_default_constructible<Tx>, std::is_default_constructible<Ty>>>>
71 constexpr decltype(auto) linearLeastSquaresFitting(IteratorX x_begin, IteratorX x_end, IteratorY y_begin, IteratorY y_end)
72 {
73 using Txx = decltype(*x_begin * *x_begin);
74 using Txy = decltype(*x_begin * *y_begin);
75 using Tyy = decltype(*y_begin * *y_begin);
76 using Ty_x = decltype(*y_begin / *x_begin);
77 using Tyy_xx = decltype(*y_begin * *y_begin / *x_begin / *x_begin);
78
79 std::ptrdiff_t x_size {x_end - x_begin}, y_size {y_end - y_begin};
80
81 if (x_size != y_size)
82 throw InputSizeMismatch {"Common-Utilities", __FILE__, __LINE__};
83
85
86 Tx x_average {calculateAverage(x_begin, x_end)};
87 Ty y_average {calculateAverage(y_begin, y_end)};
88
89 IteratorX x_iter = x_begin;
90 IteratorY y_iter = y_begin;
91
92 Txy slope_numerator {};
93 Txx slope_denominator {};
94
95 while (x_iter != x_end)
96 {
97 slope_numerator += (*x_iter - x_average) * (*y_iter - y_average);
98 slope_denominator += (*x_iter - x_average) * (*x_iter - x_average);
99
100 ++x_iter;
101 ++y_iter;
102 }
103
104 results.slope = slope_numerator / slope_denominator;
105 results.intercept = y_average - (results.slope * x_average);
106
107 Tyy var_numerator {};
108
109 x_iter = x_begin;
110 y_iter = y_begin;
111
112 while (y_iter != y_end)
113 {
114 Ty res {*y_iter - (results.slope * (*x_iter) + results.intercept)};
115 var_numerator += res * res;
116
117 ++x_iter;
118 ++y_iter;
119 }
120
121 results.variance = var_numerator / (slope_denominator * (y_size - 2));
122
123 return results;
124 }
125} // namespace CppUtils::Math
126
127#endif
Definition mathExceptions.hpp:25
Definition nPointStencil.hpp:25
Definition backwardsDifferenceMethod.hpp:20
constexpr T calculateAverage(Iterator x_begin, Iterator x_end)
Definition statistics.hpp:62
constexpr decltype(auto) linearLeastSquaresFitting(IteratorX x_begin, IteratorX x_end, IteratorY y_begin, IteratorY y_end)
Definition linearLeastSquaresFitting.hpp:71
Definition linearLeastSquaresFitting.hpp:35
T_variance variance
Definition linearLeastSquaresFitting.hpp:38
T_slope slope
Definition linearLeastSquaresFitting.hpp:36
T_intercept intercept
Definition linearLeastSquaresFitting.hpp:37