Wayverb
linear_regression.h
1 #pragma once
2 
3 #include <cmath>
4 #include <numeric>
5 #include <stdexcept>
6 
7 namespace wayverb {
8 namespace core {
9 struct linear_regression final {
10  double m;
11  double c;
12  double r;
13 };
14 
15 template <typename It>
16 linear_regression simple_linear_regression(It begin, It end) {
17  const auto n = std::distance(begin, end);
18 
19  if (!n) {
20  throw std::runtime_error(
21  "Empty range passed to simple linear regression.");
22  }
23 
24  const auto sx =
25  std::accumulate(begin, end, 0.0, [](auto running_total, auto i) {
26  return running_total + i.x;
27  });
28  const auto sy =
29  std::accumulate(begin, end, 0.0, [](auto running_total, auto i) {
30  return running_total + i.y;
31  });
32  const auto sxx =
33  std::accumulate(begin, end, 0.0, [](auto running_total, auto i) {
34  return running_total + i.x * i.x;
35  });
36  const auto sxy =
37  std::accumulate(begin, end, 0.0, [](auto running_total, auto i) {
38  return running_total + i.x * i.y;
39  });
40  const auto syy =
41  std::accumulate(begin, end, 0.0, [](auto running_total, auto i) {
42  return running_total + i.y * i.y;
43  });
44 
45  const auto denominator = n * sxx - sx * sx;
46  if (denominator == 0.0) {
47  throw std::runtime_error(
48  "Linear regression estimated a denominator of 0");
49  }
50 
51  const auto numerator = n * sxy - sx * sy;
52  const auto m = numerator / denominator;
53  const auto c = sy / n - m * sx / n;
54  const auto r =
55  numerator / std::sqrt((n * sxx - sx * sx) * (n * syy - sy * sy));
56  return {m, c, r};
57 }
58 } // namespace core
59 } // namespace wayverb
Definition: traits.cpp:2
double c
gradient of regression line
Definition: linear_regression.h:11
Definition: capsule_base.h:9
Definition: linear_regression.h:9
double r
y intercept
Definition: linear_regression.h:12