evaluate($x); // Then $this->assertEqualsWithDelta($expected, $estimate, 0.0001); } /** * @return array [data, x, expected] */ public function dataProviderForKernelDensity(): array { return [ [ $this->data, 1, 0.236055582 ], [ $this->data, .1, 0.421356196 ], [ $this->data, -1, 0.232277743 ], ]; } /** * @test evaluate when setting custom h using default kernel function * @dataProvider dataProviderForKernelDensityCustomH * @param array $data * @param float $h * @param float $x * @param float $expected */ public function testDefaultKernelDensityCustomH(array $data, float $h, float $x, float $expected) { // Given $KDE = new KernelDensityEstimation($data); $KDE->setBandwidth($h); // When $estimate = $KDE->evaluate($x); // Then $this->assertEqualsWithDelta($expected, $estimate, 0.0001); } /** * @return array [data, h, x, expected] */ public function dataProviderForKernelDensityCustomH(): array { $h = count($this->data) ** (-1 / 6); return [ [ $this->data, $h, 1, 0.237991168 ], [ $this->data, $h, .1, 0.40525027 ], [ $this->data, $h, -1, 0.232226496 ], ]; } /** * @test Custom kernel function and custom h * @dataProvider dataProviderForKernelDensityCustomBoth * @param float $h * @param callable $kernel * @param float $x * @param float $expected */ public function testDefaultKernelDensityCustomBoth(float $h, callable $kernel, float $x, float $expected) { // Given $KDE = new KernelDensityEstimation($this->data, $h, $kernel); $kernel2 = KernelDensityEstimation::TRICUBE; $KDE2 = new KernelDensityEstimation($this->data, $h, $kernel2); // When $estimate1 = $KDE->evaluate($x); $estimate2 = $KDE2->evaluate($x); // Then $this->assertEqualsWithDelta($expected, $estimate1, 0.0001); $this->assertEqualsWithDelta($expected, $estimate2, 0.0001); } /** * @return array [h, kernel, x, expected] */ public function dataProviderForKernelDensityCustomBoth(): array { $h = 1; // Tricube $kernel = function ($x) { if (\abs($x) > 1) { return 0; } else { return 70 / 81 * ((1 - \abs($x) ** 3) ** 3); } }; return [ [ $h, $kernel, 1, 0.238712304 ], [ $h, $kernel, .1, 0.420794741 ], [ $h, $kernel, -1, 0.229056709 ], ]; } /** * @test evaluate using optional kernel functions * @dataProvider dataProviderForTestKernels * @param string $kernel * @param float $x * @param float $expected */ public function testKernels(string $kernel, float $x, float $expected) { // Given $KDE = new KernelDensityEstimation($this->data, 1, $kernel); // When $estimate = $KDE->evaluate($x); // Then $this->assertEqualsWithDelta($expected, $estimate, 0.0001); } /** * @return array [kernel, x, expected] */ public function dataProviderForTestKernels(): array { return [ [KernelDensityEstimation::UNIFORM, 1, .25], [KernelDensityEstimation::TRIANGULAR, 1, .235], [KernelDensityEstimation::EPANECHNIKOV, 1, .2401905], ]; } /** * @test Kernel function NORMAL * Test data made with scipy.stats.gaussian_kde * @dataProvider dataProviderForNormalKde * @param float $x * @param float $expected */ public function testNormal(float $x, float $expected) { // Given $KDE = new KernelDensityEstimation($this->data); $h = 0.3932; $KDE->setBandwidth($h); $KDE->setKernelFunction(KernelDensityEstimation::NORMAL); // When $estimate = $KDE->evaluate($x); // Then $this->assertEqualsWithDelta($expected, $estimate, 0.00001, "Evaluate x = $x"); } /** * Test data made with scipy.stats.gaussian_kde * @return array (x, expected) */ public function dataProviderForNormalKde(): array { return [ [-3.939, 8.60829883e-05], [-2.222, 0.04138222], [-0.505, 0.36562621], [0, 0.43200043], [1.212, 0.19113825], [2.929, 9.09492454e-05], ]; } /** * @test Invalid kernel throws an Exception */ public function testBadKernel() { // Then $this->expectException(Exception\BadParameterException::class); // When $KDE = new KernelDensityEstimation($this->data, 1, 1.0); } /** * @test Unknown built-in kernel throws an Exception */ public function testUnknownBuildInKernel() { // Given $KDE = new KernelDensityEstimation($this->data); // Then $this->expectException(Exception\BadDataException::class); // When $KDE->setKernelFunction('DoesNotExist'); } /** * @test Invalid bandwidth throws an Exception */ public function testBadSetBandwidth() { // Given $KDE = new KernelDensityEstimation($this->data); // Then $this->expectException(Exception\OutOfBoundsException::class); // When $KDE->setBandwidth(-1); } /** * @test Empty data throws an Exception */ public function testEmptyData() { // Given $data = []; // Then $this->expectException(Exception\BadDataException::class); // When $KDE = new KernelDensityEstimation([]); } }