mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-12 11:06:28 +00:00
98 lines
3.8 KiB
PHP
98 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace PhpOffice\PhpSpreadsheetTests\Shared\Trend;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
|
|
use PhpOffice\PhpSpreadsheet\Shared\Trend\Trend;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class BestFitTest extends TestCase
|
|
{
|
|
private const LBF_PRECISION = 1.0E-4;
|
|
|
|
public function testBestFit(): void
|
|
{
|
|
$xValues = [45, 55, 47, 75, 90, 100, 100, 95, 88, 50, 45, 58];
|
|
$yValues = [15, 25, 17, 30, 41, 47, 50, 46, 37, 22, 20, 26];
|
|
$maxGoodness = -1000.0;
|
|
$maxType = '';
|
|
|
|
$type = Trend::TREND_LINEAR;
|
|
$result = Trend::calculate($type, $yValues, $xValues);
|
|
$goodness = $result->getGoodnessOfFit();
|
|
if ($maxGoodness < $goodness) {
|
|
$maxGoodness = $goodness;
|
|
$maxType = $type;
|
|
}
|
|
self::assertEqualsWithDelta(0.9628, $goodness, self::LBF_PRECISION);
|
|
|
|
$type = Trend::TREND_EXPONENTIAL;
|
|
$result = Trend::calculate($type, $yValues, $xValues);
|
|
$goodness = $result->getGoodnessOfFit();
|
|
if ($maxGoodness < $goodness) {
|
|
$maxGoodness = $goodness;
|
|
$maxType = $type;
|
|
}
|
|
self::assertEqualsWithDelta(0.9952, $goodness, self::LBF_PRECISION);
|
|
|
|
$type = Trend::TREND_LOGARITHMIC;
|
|
$result = Trend::calculate($type, $yValues, $xValues);
|
|
$goodness = $result->getGoodnessOfFit();
|
|
if ($maxGoodness < $goodness) {
|
|
$maxGoodness = $goodness;
|
|
$maxType = $type;
|
|
}
|
|
self::assertEqualsWithDelta(-0.0724, $goodness, self::LBF_PRECISION);
|
|
self::assertEqualsWithDelta(0.3116, $result->getValueOfXForY(2.1), self::LBF_PRECISION);
|
|
$equation = $result->getEquation();
|
|
$match = preg_match('/^Y = 0[.]01765\d+ [*] log[(]2.1205\d+ [*] X[)]$/', $equation);
|
|
self::assertSame(1, $match, $equation);
|
|
|
|
$type = Trend::TREND_POWER;
|
|
$result = Trend::calculate($type, $yValues, $xValues);
|
|
$goodness = $result->getGoodnessOfFit();
|
|
if ($maxGoodness < $goodness) {
|
|
$maxGoodness = $goodness;
|
|
$maxType = $type;
|
|
}
|
|
self::assertEqualsWithDelta(0.9946, $goodness, self::LBF_PRECISION);
|
|
self::assertEqualsWithDelta(28.0886, $result->getValueOfXForY(10.0), self::LBF_PRECISION);
|
|
$equation = $result->getEquation();
|
|
$match = preg_match('/^Y = 0[.]1705\d+ [*] X\^1[.]2207\d+$/', $equation);
|
|
self::assertSame(1, $match, $equation);
|
|
self::assertEqualsWithDelta(0.1705, $result->getIntersect(4), self::LBF_PRECISION);
|
|
|
|
$type = Trend::TREND_BEST_FIT_NO_POLY;
|
|
$result = Trend::calculate($type, $yValues, $xValues);
|
|
$goodness = $result->getGoodnessOfFit();
|
|
self::assertSame($maxGoodness, $goodness);
|
|
self::assertSame(lcfirst($maxType), $result->getBestFitType());
|
|
|
|
try {
|
|
$type = Trend::TREND_BEST_FIT;
|
|
Trend::calculate($type, $yValues, [0, 1, 2]);
|
|
self::fail('should have failed - mismatched number of elements');
|
|
} catch (SpreadsheetException $e) {
|
|
self::assertStringContainsString('Number of elements', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$type = Trend::TREND_BEST_FIT;
|
|
Trend::calculate($type, $yValues, $xValues);
|
|
self::fail('should have failed - TREND_BEST_FIT includes polynomials which are not implemented yet');
|
|
} catch (SpreadsheetException $e) {
|
|
self::assertStringContainsString('not yet implemented', $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$type = 'unknown';
|
|
Trend::calculate($type, $yValues, $xValues);
|
|
self::fail('should have failed - invalid trend type');
|
|
} catch (SpreadsheetException $e) {
|
|
self::assertStringContainsString('Unknown trend type', $e->getMessage());
|
|
}
|
|
}
|
|
}
|