123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790 |
- <?php
- namespace MathPHP\Tests\NumericalAnalysis\Interpolation;
- use MathPHP\Exception\BadDataException;
- use MathPHP\NumericalAnalysis\Interpolation\RegularGridInterpolator;
- class RegularGridInterpolatorTest extends \PHPUnit\Framework\TestCase
- {
-
- public function testRegularGridAgrees(array $point, float $expected)
- {
-
- [$points, $values] = $this->getSample4d();
-
- $p = new RegularGridInterpolator($points, $values);
-
- $evaluated = $p($point);
-
- $this->assertEqualsWithDelta($expected, $evaluated, 0.00001);
- }
-
- public function dataProviderForRegularGridAgrees(): array
- {
- return [
-
- [[0.1, 0.1, 1., .9], 1001.1],
- [[0.2, 0.1, .45, .8], 846.2],
- [[0.5, 0.5, .5, .5], 555.5],
-
- [[0., 0., 0., 0.], 0.],
- [[1., 1., 1., 1.], 1111.],
- ];
- }
-
- public function testRegularGridNearestAgrees(array $point, $expected)
- {
-
- [$points, $values] = $this->getSample4d();
-
- $p = new RegularGridInterpolator($points, $values, RegularGridInterpolator::METHOD_NEAREST);
-
- $evaluated = $p($point);
-
- $this->assertEquals($expected, $evaluated);
- }
-
- public function dataProviderForRegularGridNearestAgrees(): array
- {
- return [
- [[0.1, 0.1, .9, .9], 1100],
- [[0.1, 0.1, 0.1, 0.1], 0.],
- [[0., 0., 0., 0.], 0.],
- [[1., 1., 1., 1.], 1111.],
- [[0.1, 0.4, 0.6, 0.9], 1055.]
- ];
- }
-
- public function testIssue382ExampleLinear()
- {
-
- $xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
- $ys = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
- $zs = [110, 111, 112, 113, 114, 115, 116, 117, 118, 119];
-
- $func = function ($x, $y, $z) {
- return 2 * $x + 3 * $y - $z;
- };
-
- $data = [];
- foreach ($xs as $i => $x) {
- foreach ($ys as $j => $y) {
- foreach ($zs as $k => $z) {
- $data[$i][$j][$k] = $func($x, $y, $z);
- }
- }
- }
-
- $interp = new RegularGridInterpolator([$xs, $ys, $zs], $data, 'linear');
- $result = $interp([2.21, 12.1, 115.9]);
-
- $this->assertEqualsWithDelta(-75.18, $result, 0.00001);
- }
-
- public function testIssue382ExampleNearest()
- {
-
- $xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
- $ys = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
- $zs = [110, 111, 112, 113, 114, 115, 116, 117, 118, 119];
-
- $func = function ($x, $y, $z) {
- return 2 * $x + 3 * $y - $z;
- };
-
- $data = [];
- foreach ($xs as $i => $x) {
- foreach ($ys as $j => $y) {
- foreach ($zs as $k => $z) {
- $data[$i][$j][$k] = $func($x, $y, $z);
- }
- }
- }
-
- $interp = new RegularGridInterpolator([$xs, $ys, $zs], $data, 'nearest');
- $result = $interp([2.21, 12.1, 115.9]);
-
- $this->assertEqualsWithDelta(-76, $result, 0.00001);
- }
-
- public function testSciPyExample1()
- {
-
- $xs = [1. , 1.3, 1.6, 1.9, 2.2, 2.5, 2.8, 3.1, 3.4, 3.7, 4.];
- $ys = [
- 4. , 4.14285714, 4.28571429, 4.42857143, 4.57142857,
- 4.71428571, 4.85714286, 5. , 5.14285714, 5.28571429,
- 5.42857143, 5.57142857, 5.71428571, 5.85714286, 6. ,
- 6.14285714, 6.28571429, 6.42857143, 6.57142857, 6.71428571,
- 6.85714286, 7.
- ];
- $zs = [
- 7. , 7.0625, 7.125 , 7.1875, 7.25 , 7.3125, 7.375 , 7.4375,
- 7.5 , 7.5625, 7.625 , 7.6875, 7.75 , 7.8125, 7.875 , 7.9375,
- 8. , 8.0625, 8.125 , 8.1875, 8.25 , 8.3125, 8.375 , 8.4375,
- 8.5 , 8.5625, 8.625 , 8.6875, 8.75 , 8.8125, 8.875 , 8.9375,
- 9.
- ];
-
- $func = function ($x, $y, $z) {
- return 2 * $x ** 3 + 3 * $y ** 2 - $z;
- };
-
- $data = [];
- foreach ($xs as $i => $x) {
- foreach ($ys as $j => $y) {
- foreach ($zs as $k => $z) {
- $data[$i][$j][$k] = $func($x, $y, $z);
- }
- }
- }
-
- $interp = new RegularGridInterpolator([$xs, $ys, $zs], $data, 'linear');
- $result = $interp([2.1, 6.2, 8.3]);
-
- $this->assertEqualsWithDelta(125.80469388, $result, 0.00001);
- }
-
- public function testSciPyExample2()
- {
-
- $xs = [1. , 1.3, 1.6, 1.9, 2.2, 2.5, 2.8, 3.1, 3.4, 3.7, 4.];
- $ys = [
- 4. , 4.14285714, 4.28571429, 4.42857143, 4.57142857,
- 4.71428571, 4.85714286, 5. , 5.14285714, 5.28571429,
- 5.42857143, 5.57142857, 5.71428571, 5.85714286, 6. ,
- 6.14285714, 6.28571429, 6.42857143, 6.57142857, 6.71428571,
- 6.85714286, 7.
- ];
- $zs = [
- 7. , 7.0625, 7.125 , 7.1875, 7.25 , 7.3125, 7.375 , 7.4375,
- 7.5 , 7.5625, 7.625 , 7.6875, 7.75 , 7.8125, 7.875 , 7.9375,
- 8. , 8.0625, 8.125 , 8.1875, 8.25 , 8.3125, 8.375 , 8.4375,
- 8.5 , 8.5625, 8.625 , 8.6875, 8.75 , 8.8125, 8.875 , 8.9375,
- 9.
- ];
-
- $func = function ($x, $y, $z) {
- return 2 * $x ** 3 + 3 * $y ** 2 - $z;
- };
-
- $data = [];
- foreach ($xs as $i => $x) {
- foreach ($ys as $j => $y) {
- foreach ($zs as $k => $z) {
- $data[$i][$j][$k] = $func($x, $y, $z);
- }
- }
- }
-
- $interp = new RegularGridInterpolator([$xs, $ys, $zs], $data, 'linear');
- $result = $interp([3.3, 5.2, 7.1]);
-
- $this->assertEqualsWithDelta(146.30069388, $result, 0.00001);
- }
-
- public function testInterpolatedPointValuesOutsideDomainOfInputDataGridAreExtrapolatedLinear()
- {
-
- $xs = [1. , 1.3, 1.6, 1.9, 2.2, 2.5, 2.8, 3.1, 3.4, 3.7, 4.];
- $ys = [
- 4. , 4.14285714, 4.28571429, 4.42857143, 4.57142857,
- 4.71428571, 4.85714286, 5. , 5.14285714, 5.28571429,
- 5.42857143, 5.57142857, 5.71428571, 5.85714286, 6. ,
- 6.14285714, 6.28571429, 6.42857143, 6.57142857, 6.71428571,
- 6.85714286, 7.
- ];
- $zs = [
- 7. , 7.0625, 7.125 , 7.1875, 7.25 , 7.3125, 7.375 , 7.4375,
- 7.5 , 7.5625, 7.625 , 7.6875, 7.75 , 7.8125, 7.875 , 7.9375,
- 8. , 8.0625, 8.125 , 8.1875, 8.25 , 8.3125, 8.375 , 8.4375,
- 8.5 , 8.5625, 8.625 , 8.6875, 8.75 , 8.8125, 8.875 , 8.9375,
- 9.
- ];
-
- $func = function ($x, $y, $z) {
- return 2 * $x ** 3 + 3 * $y ** 2 - $z;
- };
-
- $data = [];
- foreach ($xs as $i => $x) {
- foreach ($ys as $j => $y) {
- foreach ($zs as $k => $z) {
- $data[$i][$j][$k] = $func($x, $y, $z);
- }
- }
- }
-
- $interp = new RegularGridInterpolator([$xs, $ys, $zs], $data, 'linear');
- $result = $interp([3.3, 7.2, 7.1]);
-
- $this->assertEqualsWithDelta(220.48028571, $result, 0.00001);
- }
-
- public function testInterpolatedPointValuesOutsideDomainOfInputDataGridAreExtrapolatedNearest()
- {
-
- $xs = [1. , 1.3, 1.6, 1.9, 2.2, 2.5, 2.8, 3.1, 3.4, 3.7, 4.];
- $ys = [
- 4. , 4.14285714, 4.28571429, 4.42857143, 4.57142857,
- 4.71428571, 4.85714286, 5. , 5.14285714, 5.28571429,
- 5.42857143, 5.57142857, 5.71428571, 5.85714286, 6. ,
- 6.14285714, 6.28571429, 6.42857143, 6.57142857, 6.71428571,
- 6.85714286, 7.
- ];
- $zs = [
- 7. , 7.0625, 7.125 , 7.1875, 7.25 , 7.3125, 7.375 , 7.4375,
- 7.5 , 7.5625, 7.625 , 7.6875, 7.75 , 7.8125, 7.875 , 7.9375,
- 8. , 8.0625, 8.125 , 8.1875, 8.25 , 8.3125, 8.375 , 8.4375,
- 8.5 , 8.5625, 8.625 , 8.6875, 8.75 , 8.8125, 8.875 , 8.9375,
- 9.
- ];
-
- $func = function ($x, $y, $z) {
- return 2 * $x ** 3 + 3 * $y ** 2 - $z;
- };
-
- $data = [];
- foreach ($xs as $i => $x) {
- foreach ($ys as $j => $y) {
- foreach ($zs as $k => $z) {
- $data[$i][$j][$k] = $func($x, $y, $z);
- }
- }
- }
-
- $interp = new RegularGridInterpolator([$xs, $ys, $zs], $data, 'nearest');
- $result = $interp([3.3, 7.2, 7.1]);
-
- $this->assertEqualsWithDelta(218.483, $result, 0.00001);
- }
-
- public function testSimilarValues(array $point, float $expected)
- {
-
- $xs = [1, 2, 3];
- $ys = [1, 2, 3];
- $zs = [1, 2, 3];
-
- $func = function ($x, $y, $z) {
- return 2 * $x + 3 * $y - $z;
- };
-
- $data = [];
- foreach ($xs as $i => $x) {
- foreach ($ys as $j => $y) {
- foreach ($zs as $k => $z) {
- $data[$i][$j][$k] = $func($x, $y, $z);
- }
- }
- }
-
- $interp = new RegularGridInterpolator([$xs, $ys, $zs], $data, 'linear');
- $result = $interp($point);
-
- $this->assertEqualsWithDelta($expected, $result, 0.00001);
- }
-
- public function dataProviderForSimilarValues(): array
- {
- return [
- [[1, 1, 1], 4.],
- [[1, 1, 2], 3.],
- [[1, 1, 3], 2.],
- [[1, 2, 1], 7.],
- [[1, 2, 2], 6.],
- [[1, 2, 3], 5.],
- [[1, 3, 1], 10.],
- [[1, 3, 2], 9.],
- [[1, 3, 3], 8.],
- [[2, 1, 1], 6.],
- [[2, 1, 2], 5.],
- [[2, 1, 3], 4.],
- [[2, 2, 1], 9.],
- [[2, 2, 2], 8.],
- [[2, 2, 3], 7.],
- [[2, 3, 1], 12.],
- [[2, 3, 2], 11.],
- [[2, 3, 3], 10.],
- [[3, 1, 1], 8.],
- [[3, 1, 2], 7.],
- [[3, 1, 3], 6.],
- [[3, 2, 1], 11.],
- [[3, 2, 2], 10.],
- [[3, 2, 3], 9.],
- [[3, 3, 1], 14.],
- [[3, 3, 2], 13.],
- [[3, 3, 3], 12.],
- ];
- }
-
- public function testPointsAndValuesNotSorted()
- {
-
- $xs = [1, 2, 3];
- $ys = [1, 2, 3];
- $zs = [1, 2, 3];
-
- $func = function ($x, $y, $z) {
- return 2 * $x + 3 * $y - $z;
- };
-
- $data = [];
- foreach ([3, 2, 1] as $i => $x) {
- foreach ([3, 2, 1] as $j => $y) {
- foreach ([3, 2, 1] as $k => $z) {
- $data[$i][$j][$k] = $func($x, $y, $z);
- }
- }
- }
-
- $interp = new RegularGridInterpolator([$xs, $ys, $zs], $data, 'linear');
- $result = $interp([1, 1, 2]);
-
- $this->assertEqualsWithDelta(13, $result, 0.00001);
- }
-
- public function testStackOverflowExample()
- {
-
- $x = [0., 0.5, 1.];
-
- $vals = [
- [
- [1. , 1.54630249, 2.55740772],
- [0.87758256, 1.42388505, 2.43499029],
- [0.54030231, 1.0866048 , 2.09771003]
- ],
- [
- [1.47942554, 2.02572803, 3.03683326],
- [1.3570081 , 1.90331059, 2.91441583],
- [1.01972784, 1.56603033, 2.57713557]],
- [
- [1.84147098, 2.38777347, 3.39887871],
- [1.71905355, 2.26535604, 3.27646127],
- [1.38177329, 1.92807578, 2.93918102]
- ]
- ];
-
- $tst = [0.47, 0.49, 0.53];
-
- $rgi = new RegularGridInterpolator([$x, $x, $x], $vals, 'linear');
- $result = $rgi($tst);
-
- $this->assertEqualsWithDelta(1.93765972, $result, 0.00001);
- }
-
- public function testBadMethodException()
- {
-
- $invalidMethod = 'methodDoesNotExist';
-
- $this->expectException(BadDataException::class);
-
- $rgi = new RegularGridInterpolator([0], [0], $invalidMethod);
- }
-
- public function testBadValuesException()
- {
-
- $points = [[0], [1]];
- $values = [0];
-
- $this->expectException(BadDataException::class);
-
- $rgi = new RegularGridInterpolator($points, $values);
- }
-
- public function testInvokeBadPointDimensionException()
- {
-
- $interp = new RegularGridInterpolator([0], [0]);
-
- $this->expectException(BadDataException::class);
-
- $interp([0, 2]);
- }
-
- private function getSample4d(): array
- {
- $points = [[0.0, 0.5, 1.0], [0.0, 0.5, 1.0], [0.0, 0.5, 1.0], [0.0, 0.5, 1.0]];
- $values = [
- [
- [
- [0.0000e+00, 5.0000e+02, 1.0000e+03],
- [5.0000e+01, 5.5000e+02, 1.0500e+03],
- [1.0000e+02, 6.0000e+02, 1.1000e+03]
- ],
- [
- [5.0000e+00, 5.0500e+02, 1.0050e+03],
- [5.5000e+01, 5.5500e+02, 1.0550e+03],
- [1.0500e+02, 6.0500e+02, 1.1050e+03]
- ],
- [
- [1.0000e+01, 5.1000e+02, 1.0100e+03],
- [6.0000e+01, 5.6000e+02, 1.0600e+03],
- [1.1000e+02, 6.1000e+02, 1.1100e+03]
- ]
- ],
- [
- [
- [5.0000e-01, 5.0050e+02, 1.0005e+03],
- [5.0500e+01, 5.5050e+02, 1.0505e+03],
- [1.0050e+02, 6.0050e+02, 1.1005e+03]
- ],
- [
- [5.5000e+00, 5.0550e+02, 1.0055e+03],
- [5.5500e+01, 5.5550e+02, 1.0555e+03],
- [1.0550e+02, 6.0550e+02, 1.1055e+03]
- ],
- [
- [1.0500e+01, 5.1050e+02, 1.0105e+03],
- [6.0500e+01, 5.6050e+02, 1.0605e+03],
- [1.1050e+02, 6.1050e+02, 1.1105e+03]
- ]
- ],
- [
- [
- [1.0000e+00, 5.0100e+02, 1.0010e+03],
- [5.1000e+01, 5.5100e+02, 1.0510e+03],
- [1.0100e+02, 6.0100e+02, 1.1010e+03]
- ],
- [
- [6.0000e+00, 5.0600e+02, 1.0060e+03],
- [5.6000e+01, 5.5600e+02, 1.0560e+03],
- [1.0600e+02, 6.0600e+02, 1.1060e+03]
- ],
- [
- [1.1000e+01, 5.1100e+02, 1.0110e+03],
- [6.1000e+01, 5.6100e+02, 1.0610e+03],
- [1.1100e+02, 6.1100e+02, 1.1110e+03]
- ]
- ]
- ];
- return [$points, $values];
- }
- }
|