Sequoia
Loading...
Searching...
No Matches
StatisticalAlgorithms.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2019. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
14#include <cmath>
15#include <numeric>
16#include <optional>
17#include <iterator>
18
19namespace sequoia::maths
20{
21 template<std::input_iterator Iter, class T = typename std::iterator_traits<Iter>::value_type>
22 [[nodiscard]]
23 std::optional<T> mean(Iter first, Iter last)
24 {
25 std::optional<T> m{};
26
27 if(const auto dist{std::ranges::distance(first, last)})
28 {
29 m = std::accumulate(first, last, T{}) / dist;
30 }
31
32 return m;
33 }
34
35 template<std::input_iterator Iter, class T = typename std::iterator_traits<Iter>::value_type>
36 [[nodiscard]]
37 std::pair<std::optional<T>, std::optional<T>>
38 cummulative_square_diffs(Iter first, Iter last)
39 {
40 if(std::ranges::distance(first, last))
41 {
42 const auto m{mean(first, last)};
43 const auto var{
44 std::accumulate(first, last, T{}, [m](const T& sum, const T& datum){
45 return sum + (datum - m.value())*(datum - m.value());
46 }
47 )
48 };
49
50 return {var, m};
51 }
52
53 return {{}, {}};
54 }
55
56 template<std::input_iterator Iter, class T = typename std::iterator_traits<Iter>::value_type>
57 [[nodiscard]]
58 std::pair<std::optional<T>, std::optional<T>>
59 variance(Iter first, Iter last)
60 {
61 if(const auto dist{std::ranges::distance(first, last)})
62 {
63 auto [sq, mean]{cummulative_square_diffs(first, last)};
64
65 return {sq.value()/dist, mean.value()};
66 }
67
68 return {{}, {}};
69 }
70
71 template<std::input_iterator Iter, class T = typename std::iterator_traits<Iter>::value_type>
72 [[nodiscard]]
73 std::pair<std::optional<T>, std::optional<T>>
74 sample_variance(Iter first, Iter last)
75 {
76 if(const auto dist{std::ranges::distance(first, last)}; !dist)
77 {
78 return {{}, {}};
79 }
80 else if(dist == 1)
81 {
82 return {{}, mean(first, last)};
83 }
84 else
85 {
86 auto [sq, mean]{cummulative_square_diffs(first, last)};
87
88 return {sq.value()/(dist - 1), mean.value()};
89 }
90 }
91
92 template<std::input_iterator Iter, class T = typename std::iterator_traits<Iter>::value_type>
93 [[nodiscard]]
94 std::pair<std::optional<T>, std::optional<T>>
95 standard_deviation(Iter first, Iter last)
96 {
97 if(const auto dist{std::ranges::distance(first, last)})
98 {
99 auto [var, mean]{variance(first, last)};
100
101 return {std::sqrt(var.value()), mean.value()};
102 }
103
104 return {{}, {}};
105 }
106
107 namespace bias
108 {
110 {
111 template<std::input_iterator Iter, class T = typename std::iterator_traits<Iter>::value_type>
112 [[nodiscard]]
113 std::pair<std::optional<T>, std::optional<T>>
114 operator()(Iter first, Iter last) const
115 {
116 if(const auto dist{std::ranges::distance(first, last)}; !dist)
117 {
118 return {{}, {}};
119 }
120 else if(dist == 1)
121 {
122 return {{}, mean(first, last)};
123 }
124 else
125 {
126 auto [sq, mean]{cummulative_square_diffs(first, last)};
127
128 return {std::sqrt(sq.value()/(dist - 1.5)), mean.value()};
129 }
130 }
131 };
132 }
133
134 template<std::input_iterator Iter, class Estimator = bias::gaussian_approx_estimator, class T = typename std::iterator_traits<Iter>::value_type>
135 [[nodiscard]]
136 std::pair<std::optional<T>, std::optional<T>>
137 sample_standard_deviation(Iter first, Iter last, Estimator estimator = Estimator{})
138 {
139 return estimator(first, last);
140 }
141}
Definition: StatisticalAlgorithms.hpp:110