Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
PolynomialRegression
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
1 / 1
7
100.00% covered (success)
100.00%
1 / 1
 getRegression
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
1 / 1
7
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Math\Statistic\Forecast\Regression
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Math\Statistic\Forecast\Regression;
16
17use phpOMS\Math\Matrix\Exception\InvalidDimensionException;
18use phpOMS\Math\Statistic\Average;
19
20/**
21 * Regression class.
22 *
23 * @package phpOMS\Math\Statistic\Forecast\Regression
24 * @license OMS License 2.0
25 * @link    https://jingga.app
26 * @since   1.0.0
27 */
28final class PolynomialRegression
29{
30    /**
31     * Get linear regression based on scatter plot.
32     *
33     * @param array<int|float> $x Obersved x values
34     * @param array<int|float> $y Observed y values
35     *
36     * @return array [a => ?, b => ?, c => ?]
37     *
38     * @throws InvalidDimensionException throws this exception if the dimension of both arrays is not equal
39     *
40     * @since 1.0.0
41     */
42    public static function getRegression(array $x, array $y) : array
43    {
44        if (($n = \count($x)) !== \count($y)) {
45            throw new InvalidDimensionException(\count($x) . 'x' . \count($y));
46        }
47
48        $xm = Average::arithmeticMean($x);
49        $ym = Average::arithmeticMean($y);
50
51        $r = \range(0, $n - 1);
52
53        $xTemp = [];
54        foreach ($r as $e) {
55            $xTemp[] = $e * $e;
56        }
57
58        $x2m = Average::arithmeticMean($xTemp);
59
60        $xTemp = [];
61        foreach ($r as $e) {
62            $xTemp[] = $e * $e * $e;
63        }
64
65        $x3m = Average::arithmeticMean($xTemp);
66
67        $xTemp = [];
68        foreach ($r as $e) {
69            $xTemp[] = $e * $e * $e * $e;
70        }
71
72        $x4m = Average::arithmeticMean($xTemp);
73        $xym = 0.0;
74
75        for ($i = 0; $i < $n; ++$i) {
76            $xym += $x[$i] * $y[$i];
77        }
78
79        $xym /= $n;
80
81        $x2ym = 0.0;
82        for ($i = 0; $i < $n; ++$i) {
83            $x2ym += $x[$i] * $x[$i] * $y[$i];
84        }
85
86        $x2ym /= $n;
87
88        $sxx   = $x2m - $xm * $xm;
89        $sxy   = $xym - $xm * $ym;
90        $sxx2  = $x3m - $xm * $x2m;
91        $sx2x2 = $x4m - $x2m * $x2m;
92        $sx2y  = $x2ym - $x2m * $ym;
93
94        $b = ($sxy * $sx2x2 - $sx2y * $sxx2) / ($sxx * $sx2x2 - $sxx2 * $sxx2);
95        $c = ($sx2y * $sxx - $sxy * $sxx2) / ($sxx * $sx2x2 - $sxx2 * $sxx2);
96        $a = $ym - $b * $xm - $c * $x2m;
97
98        return [
99            'a' => $a,
100            'b' => $b,
101            'c' => $c,
102        ];
103    }
104}