reset(); } public function reset(): void { $squares = ($this->degree - 1) * 2; for ($i = 0; $i <= $squares; $i++) { $this->xPowers[$i] = 0.0; $this->xyPowers[$i] = 0.0; } } public function addData(float $x, float $y): void { $squares = ($this->degree - 1) * 2; for ($i = 0; $i <= $squares; $i++) { $this->xPowers[$i] += $x ** $i; $this->xyPowers[$i] += $y * ($x ** $i); } } /** * Współczynniki [c0, c1, ...] (c0 = wyraz wolny). * * @return float[] */ public function getCoefficients(?int $degree = null): array { $degree ??= $this->degree; $eps = 1e-12; // Macierz równań normalnych + kolumna augmentacji. $matrix = []; for ($row = 0; $row < $degree; $row++) { for ($col = 0; $col < $degree; $col++) { $matrix[$row][$col] = $this->xPowers[$row + $col]; } $matrix[$row][$degree] = $this->xyPowers[$row]; } $rows = count($matrix); $isDone = array_fill(0, $rows, false); $order = []; // Eliminacja wierszowa do macierzy górnotrójkątnej z 1 na przekątnej. for ($column = 0; $column < $rows; $column++) { $activeRow = 0; while ($activeRow < $rows && (abs($matrix[$activeRow][$column]) < $eps || $isDone[$activeRow])) { $activeRow++; } if ($activeRow < $rows) { $order[$column] = $activeRow; $firstTerm = $matrix[$activeRow][$column]; for ($sub = $column; $sub <= $rows; $sub++) { $matrix[$activeRow][$sub] /= $firstTerm; } $isDone[$activeRow] = true; for ($row = 0; $row < $rows; $row++) { if (! $isDone[$row] && abs($matrix[$row][$column]) >= $eps) { $factor = $matrix[$row][$column]; for ($sub = $column; $sub <= $rows; $sub++) { $matrix[$row][$sub] -= $factor * $matrix[$activeRow][$sub]; } } } } } // Podstawianie wsteczne. $isDone = array_fill(0, $rows, false); $coefficients = []; for ($column = $rows - 1; $column >= 0; $column--) { $activeRow = $order[$column]; $isDone[$activeRow] = true; for ($row = 0; $row < $rows; $row++) { if (! $isDone[$row]) { $factor = $matrix[$row][$column]; for ($sub = $column; $sub <= $rows; $sub++) { $matrix[$row][$sub] -= $factor * $matrix[$activeRow][$sub]; } } } $coefficients[$column] = $matrix[$activeRow][$rows]; } ksort($coefficients); return $coefficients; } /** @param float[] $coefficients */ public function interpolate(array $coefficients, float $x): float { $y = 0.0; foreach ($coefficients as $i => $c) { $y += $c * ($x ** $i); } return $y; } }