Add more unit tests

This commit is contained in:
Dennis Eichhorn 2018-10-06 15:50:27 +02:00
parent 246001a1f2
commit 795e0f29d6
17 changed files with 347 additions and 75 deletions

View File

@ -206,9 +206,4 @@ class BernoulliDistribution
{
return (1 - 6 * $p * (1 - $p)) / ($p * (1 - $p));
}
public static function getRandom()
{
}
}

View File

@ -189,9 +189,4 @@ class BinomialDistribution
{
return $n * $p * (1 - $p);
}
public static function getRandom()
{
}
}

View File

@ -97,9 +97,4 @@ class CauchyDistribution
{
return \log(4 * M_PI * $gamma);
}
public static function getRandom()
{
}
}

View File

@ -97,7 +97,7 @@ class ChiSquaredDistribution
$sum = 0.0;
for ($i = 0; $i < $count; ++$i) {
$sum += ($dataset[$i] - $expected[$i]) * ($dataset[$i] - $expected[$i]) / $expected[$i];
$sum += ($dataset[$i] - $expected[$i]) ** 2 / $expected[$i];
}
$p = null;
@ -106,7 +106,7 @@ class ChiSquaredDistribution
$df = self::getDegreesOfFreedom($dataset);
}
if (!defined('self::TABLE') || !array_key_exists($df, self::TABLE)) {
if (!defined('self::TABLE') || !\array_key_exists($df, self::TABLE)) {
throw new \Exception('Degrees of freedom not supported');
}
@ -117,11 +117,14 @@ class ChiSquaredDistribution
}
}
$tableCopy = self::TABLE[$df];
$key = \key(\end($tableCopy));
$p = 1 - ($p ?? ($key === false ? 1 : (float) $key));
$p = $p ?? 0;
return ['P' => $p, 'H0' => ($p > $significance), 'df' => $df];
return [
'Chi2' => $sum,
'P' => $p,
'H0' => ($p > $significance),
'df' => $df
];
}
/**
@ -150,17 +153,17 @@ class ChiSquaredDistribution
*
* @return float
*
* @throws \Exception
* @throws \OutOfBoundsException
*
* @since 1.0.0
*/
public static function getPdf(float $x, int $df) : float
{
if ($x < 0) {
throw new \Exception('Out of bounds');
throw new \OutOfBoundsException('Out of bounds');
}
return 1 / (\pow(2, $df / 2) * Gamma::lanczosApproximationReal(($df / 2))) * \pow($x, $df / 2 - 1) * \exp(-$x / 2);
return 0.0;
}
/**
@ -174,7 +177,7 @@ class ChiSquaredDistribution
*/
public static function getMode(int $df) : int
{
return \max([$df - 2, 0]);
return \max($df - 2, 0);
}
/**
@ -227,14 +230,14 @@ class ChiSquaredDistribution
*
* @return float
*
* @throws \Exception
* @throws \OutOfBoundsException
*
* @since 1.0.0
*/
public static function getMgf(int $df, float $t) : float
{
if ($t > 0.5) {
throw new \Exception('Out of bounds');
throw new \OutOfBoundsException('Out of bounds');
}
return \pow(1 - 2 * $t, -$df / 2);
@ -267,9 +270,4 @@ class ChiSquaredDistribution
{
return 12 / $df;
}
public static function getRandom()
{
}
}

View File

@ -51,7 +51,7 @@ class ExponentialDistribution
*/
public static function getCdf(float $x, float $lambda) : float
{
return $x >= 0 ? 1 - \exp($lambda * $x) : 0;
return $x >= 0 ? 1 - 1 / \exp($lambda * $x) : 0;
}
/**
@ -91,7 +91,7 @@ class ExponentialDistribution
*/
public static function getMedian(float $lambda) : float
{
return 1 / $lambda;
return 1 / $lambda * \log(2);
}
/**
@ -116,14 +116,14 @@ class ExponentialDistribution
*
* @return float
*
* @throws \Exception
* @throws \OutOfBoundsException
*
* @since 1.0.0
*/
public static function getMgf(float $t, float $lambda) : float
{
if ($t >= $lambda) {
throw new \Exception('Out of bounds');
throw new \OutOfBoundsException('Out of bounds');
}
return $lambda / ($lambda - $t);
@ -152,9 +152,4 @@ class ExponentialDistribution
{
return 6;
}
public static function getRandom()
{
}
}

View File

@ -120,7 +120,7 @@ class GeometricDistribution
*/
public static function getMgf(float $p, float $t) : float
{
return $p * \exp($t) / (1 - (1 - $p) * \exp($t));
return $t < -\log(1 - $p) ? $p * \exp($t) / (1 - (1 - $p) * \exp($t)) : $p / (1 - (1 - $p) * \exp($t));
}
/**
@ -150,9 +150,4 @@ class GeometricDistribution
{
return 6 + $lambda ** 2 / (1 - $lambda);
}
public static function getRandom()
{
}
}

View File

@ -157,9 +157,4 @@ class LaplaceDistribution
{
return 3;
}
public static function getRandom()
{
}
}

View File

@ -150,9 +150,4 @@ class NormalDistribution
{
return 0;
}
public static function getRandom()
{
}
}

View File

@ -177,9 +177,4 @@ class PoissonDistribution
{
return \pow($lambda, -1);
}
public static function getRandom()
{
}
}

View File

@ -151,9 +151,4 @@ class UniformDistributionDiscrete
{
return (($b - $a + 1) ** 2 - 1) / 12;
}
public static function getRandom()
{
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Math\Stochastic\Distribution
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Math\Stochastic\Distribution;
/**
* ZTest
*
* @package phpOMS\Math\Stochastic\Distribution
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
class ZTest
{
public const TABLE = [
'2.58' => 0.99,
'2.33' => 0.98,
'1.96' => 0.95,
'1.64' => 0.90,
'1.44' => 0.85,
'1.28' => 0.80,
];
/**
* Test hypthesis.
*
* @param float $dataset Value observed
* @param float $expected Expected value
* @param float $total Observed dataset size
* @param float $significance Significance
*
* @return bool
*
* @since 1.0.0
*/
public static function testHypothesis(float $dataset, float $expected, float $total, float $significance = 0.95) : bool
{
$z = ($dataset - $expected) / \sqrt($expected * (1 - $expected) / $total);
$zSignificance = 0.0;
foreach (self::TABLE as $key => $value) {
if ($significance === $value) {
$zSignificance = (float) $key;
}
}
return $z > -$key && $z < $key;
}
}

View File

@ -20,6 +20,15 @@ use phpOMS\Utils\TestUtils;
class MemCachedTest extends \PHPUnit\Framework\TestCase
{
protected function setUp()
{
if (!extension_loaded('memcached')) {
$this->markTestSkipped(
'The Memcached extension is not available.'
);
}
}
public function testDefault()
{
$cache = new MemCached($GLOBALS['CONFIG']['cache']['memcached']);

View File

@ -20,6 +20,15 @@ use phpOMS\Utils\TestUtils;
class RedisCacheTest extends \PHPUnit\Framework\TestCase
{
protected function setUp()
{
if (!extension_loaded('redis')) {
$this->markTestSkipped(
'The Redis extension is not available.'
);
}
}
public function testDefault()
{
$cache = new RedisCache($GLOBALS['CONFIG']['cache']['redis']);
@ -82,7 +91,7 @@ class RedisCacheTest extends \PHPUnit\Framework\TestCase
[
'status' => CacheStatus::OK,
'count' => 6,
],
],
$cache->stats()
);
@ -96,7 +105,7 @@ class RedisCacheTest extends \PHPUnit\Framework\TestCase
[
'status' => CacheStatus::OK,
'count' => 0,
],
],
$cache->stats()
);
}

View File

@ -17,8 +17,110 @@ use phpOMS\Math\Stochastic\Distribution\ChiSquaredDistribution;
class ChiSquaredDistributionTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
public function testHypothesisFalse()
{
self::markTestIncomplete();
$p = [0.6, 0.25, 0.15];
$a = 0.05;
$total = 470;
$observed = [255, 125, 90];
$expected = [$total * $p[0], $total * $p[1], $total * $p[2]];
$test = ChiSquaredDistribution::testHypothesis($observed, $expected, $a);
self::assertEquals(8.46, $test['Chi2'], '', 0.1);
self::assertNotEquals(0, $test['P']);
self::assertFalse($test['H0']);
self::assertEquals(2, $test['df']);
}
public function testDegreesOfFreedom()
{
self::assertEquals(2, ChiSquaredDistribution::getDegreesOfFreedom([1, 2, 3]));
self::assertEquals(6, ChiSquaredDistribution::getDegreesOfFreedom([
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
]));
}
public function testMode()
{
self::assertEquals(max(5 - 2, 0), ChiSquaredDistribution::getMode(5));
}
public function testMean()
{
$df = 5;
self::assertEquals($df, ChiSquaredDistribution::getMean($df));
}
public function testVariance()
{
$df = 5;
self::assertEquals(2 * $df, ChiSquaredDistribution::getVariance($df));
}
public function testMedian()
{
$df = 5;
self::assertEquals($df * (1 - 2 / (9 * $df)) ** 3, ChiSquaredDistribution::getMedian($df));
}
public function testSkewness()
{
$df = 5;
self::assertEquals(sqrt(8 / $df), ChiSquaredDistribution::getSkewness($df));
}
public function testExKurtosis()
{
$df = 5;
self::assertEquals(12 / $df, ChiSquaredDistribution::getExKurtosis($df));
}
public function testMgdf()
{
$df = 5;
$t = 0.3;
self::assertEquals((1 - 2 * $t) ** (-$df / 2), ChiSquaredDistribution::getMgf($df, $t));
}
/**
* @expectedException \Exception
*/
public function testHypothesisSizeException()
{
ChiSquaredDistribution::testHypothesis([1, 2], [2]);
}
/**
* @expectedException \Exception
*/
public function testHypothesisDegreesOfFreedomException()
{
ChiSquaredDistribution::testHypothesis([], []);
}
/**
* @expectedException \OutOfBoundsException
*/
public function testPdfOutOfBoundsException()
{
ChiSquaredDistribution::getPdf(-1, 0);
}
/**
* @expectedException \OutOfBoundsException
*/
public function testMgfOutOfBoundsException()
{
ChiSquaredDistribution::getMgf(1, 0.6);
}
}

View File

@ -17,8 +17,65 @@ use phpOMS\Math\Stochastic\Distribution\ExponentialDistribution;
class ExponentialDistributionTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
public function testPdf()
{
self::markTestIncomplete();
$lambda = 0.1;
$x = 7;
self::assertEquals(0.049659, ExponentialDistribution::getPdf($x, $lambda), '', 0.01);
}
public function testCdf()
{
$lambda = 0.1;
$x = 7;
self::assertEquals(0.5034, ExponentialDistribution::getCdf($x, $lambda), '', 0.01);
}
public function testMean()
{
self::assertEquals(1/3, ExponentialDistribution::getMean(3));
}
public function testMode()
{
self::assertEquals(0, ExponentialDistribution::getMode());
}
public function testMedian()
{
self::assertEquals(1/3 * log(2), ExponentialDistribution::getMedian(3));
}
public function testMgf()
{
$lambda = 3;
$t = 2;
self::assertEquals($lambda / ($lambda - $t), ExponentialDistribution::getMgf($t, $lambda));
}
public function testVariance()
{
self::assertEquals(1/(3 ** 2), ExponentialDistribution::getVariance(3));
}
public function testExKurtosis()
{
self::assertEquals(6, ExponentialDistribution::getExKurtosis());
}
public function testSkewness()
{
self::assertEquals(2, ExponentialDistribution::getSkewness());
}
/**
* @expectedException \OutOfBoundsException
*/
public function testMgfException()
{
ExponentialDistribution::getMgf(3, 3);
}
}

View File

@ -17,8 +17,59 @@ use phpOMS\Math\Stochastic\Distribution\GeometricDistribution;
class GeometricDistributionTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
public function testPmf()
{
self::markTestIncomplete();
$p = 0.2;
$k = 4;
self::assertEquals(0.1024, GeometricDistribution::getPmf($p, $k), '', 0.01);
}
public function testCdf()
{
$p = 0.2;
$k = 6;
// P(X > 6) = P(X <= 6) => 1 - CDF
self::assertEquals(0.262, 1 - GeometricDistribution::getCdf($p, $k), '', 0.01);
}
public function testMode()
{
self::assertEquals(1, GeometricDistribution::getMode());
}
public function testMean()
{
$p = 0.3;
self::assertEquals(1 / $p, GeometricDistribution::getMean($p));
}
public function testVariance()
{
$p = 0.3;
self::assertEquals((1 - $p) / $p ** 2, GeometricDistribution::getVariance($p));
}
public function testSkewness()
{
$p = 0.3;
self::assertEquals((2 - $p) / sqrt(1 - $p), GeometricDistribution::getSkewness($p));
}
public function testExKurtosis()
{
$p = 0.3;
self::assertEquals(6 + ($p ** 2) / (1 - $p), GeometricDistribution::getExKurtosis($p));
}
public function testMedian()
{
$p = 0.3;
self::assertEquals(ceil(-1 / log(1 - $p, 2)), GeometricDistribution::getMedian($p));
}
}

View File

@ -0,0 +1,30 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Math\Stochastic\Distribution;
use phpOMS\Math\Stochastic\Distribution\ZTest;
class ZTestTest extends \PHPUnit\Framework\TestCase
{
// http://sphweb.bumc.bu.edu/otlt/MPH-Modules/BS/BS704_HypothesisTesting-ChiSquare/BS704_HypothesisTesting-ChiSquare_print.html
public function testHypothesisFalse()
{
$a = 0.95;
$observed = 0.512;
$expected = 0.75;
$total = 125; // total count of observed sample size
self::assertFalse(ZTest::testHypothesis($observed, $expected, $total, $a));
}
}