Skip to content

Instantly share code, notes, and snippets.

@sagittaracc
Last active March 31, 2021 10:24
Show Gist options
  • Save sagittaracc/110ace4bce2850dfde6d08faa037ec4c to your computer and use it in GitHub Desktop.
Save sagittaracc/110ace4bce2850dfde6d08faa037ec4c to your computer and use it in GitHub Desktop.
Lagrange interpolation PHP Decorator (Интерполяционные полиномы Лагранжа на PHP Декораторе)
<?php
interface Dataset
{
public function output();
}
<?php
class Decorator implements Dataset
{
protected $dataset;
public function __construct(Dataset $dataset)
{
$this->dataset = $dataset;
}
public function output()
{
$this->dataset->output();
}
}
<?php
require('Dataset.php');
require('PointDataset.php');
require('Decorator.php');
require('Lagrange.php');
$pointDataset = new PointDataset([
[0, 0],
[1, 0.5],
[2, 1],
]);
echo (new Lagrange($pointDataset))->setStep(0.01)->output();
<?php
/**
*
* $pointDataset = new PointDataset([
* [0, 0],
* [1, 0.5],
* [2, 1],
* ]);
*
* echo (new Lagrange($pointDataset))->setStep(0.1)->output();
*
*/
class Lagrange extends Decorator
{
private $step = 0.1;
public function setStep($step)
{
$this->step = $step;
return $this;
}
public function output()
{
$this->dataset->setPoints($this->interpolate($this->step));
parent::output();
}
private function polynomial($i, $x)
{
$p = 1;
for ($j = 0, $k = $this->dataset->count(); $j < $k; $j++)
{
if ($j === $i) continue;
$p *= ($x - $this->dataset->x($j)) / ($this->dataset->x($i) - $this->dataset->x($j));
}
return $p;
}
private function value($x)
{
$sum = 0;
for ($i = 0, $n = $this->dataset->count(); $i < $n; $i++)
{
$sum += $this->dataset->y($i) * $this->polynomial($i, $x);
}
return $sum;
}
public function interpolate($step)
{
if (is_null($this->dataset->getPoints()))
return null;
$xs = $this->dataset->x(0);
$xe = $this->dataset->x($this->dataset->count());
$points = [];
for ($x = $xs; $x <= $xe; $x += $step)
{
$points[] = [
$x,
$this->value($x),
];
}
return $points;
}
}
<?php
class PointDataset implements Dataset
{
private $points;
public function __construct($points)
{
$this->setPoints($points);
}
public function getPoints()
{
return $this->points;
}
public function setPoints($points)
{
$this->points = $points;
}
public function x($i)
{
return $this->points[$i][0];
}
public function y($i)
{
return $this->points[$i][1];
}
public function count()
{
return count($this->points) - 1;
}
public function output()
{
foreach ($this->points as $point)
{
echo "{$point[0]};{$point[1]}<br>";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment