More unit tests and fix statistic

This commit is contained in:
Dennis Eichhorn 2018-02-22 20:48:13 +01:00
parent cc904e772a
commit 510842727c
8 changed files with 231 additions and 73 deletions

View File

@ -157,7 +157,7 @@ class Average
*
* @return float
*
* @throws \Exception
* @throws phpOMS\Math\Exception\ZeroDevisionException
*
* @since 1.0.0
*/
@ -309,52 +309,6 @@ class Average
return rad2deg(atan2($y, $x));
}
/**
* Calculate angle based on time.
*
* Example: ('08:44:28')
*
* @param string $time Time
*
* @return float
*
* @throws \Exception
*
* @since 1.0.0
*/
public static function timeToAngle(string $time) : float
{
$parts = explode(':', $time);
if (count($parts) !== 3) {
throw new \Exception('Wrong time format');
}
$sec = ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
$angle = 360.0 * ($sec / 86400.0);
return $angle;
}
/**
* Calculate time based on angle.
*
* Example: ('08:44:28')
*
* @param float $angle Angle
*
* @return string
*
* @since 1.0.0
*/
public static function angleToTime(float $angle) : string
{
$sec = 86400.0 * $angle / 360.0;
$time = sprintf('%02d:%02d:%02d', floor($sec / 3600), floor(($sec % 3600) / 60), $sec % 60);
return $time;
}
/**
* Calculate the angle mean.
*

View File

@ -36,7 +36,7 @@ class Basic
*
* @since 1.0.0
*/
public static function freaquency(array $values) : array
public static function frequency(array $values) : array
{
$freaquency = [];
$sum = 1;
@ -46,8 +46,8 @@ class Basic
}
foreach ($values as $value) {
if ($isArray) {
$freaquency[] = self::freaquency($value);
if (is_array($value)) {
$freaquency[] = self::frequency($value);
} else {
$freaquency[] = $value / $sum;
}

View File

@ -59,11 +59,11 @@ class Correlation
$count = count($x);
$sum = 0.0;
for ($i = $k + 1; $i < $count; ++$i) {
for ($i = $k; $i < $count; ++$i) {
$sum += ($x[$i] - $mean) * ($x[$i - $k] - $mean);
}
return $sum / ($squaredMeanDeviation * count($x));
return $sum / ($squaredMeanDeviation * $count);
}
/**
@ -71,40 +71,41 @@ class Correlation
*
* @param array $autocorrelations Autocorrelations
* @param int $h Maximum leg considered
* @param int $n Amount of observations
*
* @return float
*
* @since 1.0.0
*/
public static function boxPierceTest(array $autocorrelations, int $h) : float
public static function boxPierceTest(array $autocorrelations, int $h, int $n) : float
{
$sum = 0;
for ($i = 0; $i < $h; ++$i) {
$sum += $autocorrelations[$i] ** 2;
}
return count($autocorrelations) * $sum;
return $n * $sum;
}
/**
* Box Pierce test (portmanteau test).
* Ljung Box test (portmanteau test).
*
* @param array $autocorrelations Autocorrelations
* @param int $h Maximum leg considered
* @param int $n Amount of observations
*
* @return float
*
* @since 1.0.0
*/
public static function ljungBoxTest(array $autocorrelations, int $h) : float
public static function ljungBoxTest(array $autocorrelations, int $h, int $n) : float
{
$count = count($autocorrelations);
$sum = 0;
$sum = 0;
for ($i = 0; $i < $h; ++$i) {
$sum += 1 / ($count - $i) * $autocorrelations[$i] ** 2;
$sum += 1 / ($n - ($i + 1)) * $autocorrelations[$i] ** 2;
}
return $count * ($count + 2) * $sum;
return $n * ($n + 2) * $sum;
}
}

View File

@ -85,7 +85,14 @@ class MeasureOfDispersion
*/
public static function standardDeviation(array $values) : float
{
return sqrt(self::sampleVariance($values));
$mean = Average::arithmeticMean($values);
$sum = 0.0;
foreach ($values as $value) {
$sum += ($value - $mean) ** 2;
}
return sqrt($sum / (count($values) - 1));
}
/**
@ -109,7 +116,7 @@ class MeasureOfDispersion
throw new ZeroDevisionException();
}
return $count * self::empiricalVariance($values) / ($count - 1);
return self::empiricalVariance($values) * $count / ($count - 1);
}
/**
@ -117,7 +124,8 @@ class MeasureOfDispersion
*
* Example: ([4, 5, 9, 1, 3])
*
* @param array $values Values
* @param array $values Values
* @param array $probabilities Probabilities
*
* @return float
*
@ -125,22 +133,23 @@ class MeasureOfDispersion
*
* @since 1.0.0
*/
public static function empiricalVariance(array $values) : float
public static function empiricalVariance(array $values, array $probabilities = []) : float
{
$count = count($values);
$count = count($values);
$hasProbability = !empty($probabilities);
if ($count === 0) {
throw new ZeroDevisionException();
}
$mean = Average::arithmeticMean($values);
$mean = $hasProbability ? Average::weightedAverage($values, $probabilities) : Average::arithmeticMean($values);
$sum = 0;
foreach ($values as $value) {
$sum += $value - $mean;
foreach ($values as $key => $value) {
$sum += ($hasProbability ? $probabilities[$key] : 1) * ($value - $mean) ** 2;
}
return $sum / ($count - 1);
return $hasProbability ? $sum : $sum / $count;
}
/**
@ -216,6 +225,27 @@ class MeasureOfDispersion
return $sum / count($x);
}
/**
* Get mean absolute deviation.
*
* @param array $x Values
*
* @return float
*
* @since 1.0.0
*/
public static function meanAbsoluteDeviation(array $x) : float
{
$mean = Average::arithmeticMean($x);
$sum = 0.0;
foreach ($x as $xi) {
$sum += abs($xi - $mean);
}
return $sum / count($x);
}
/**
* Get squared mean deviation.
*

View File

@ -21,4 +21,66 @@ class AverageTest extends \PHPUnit\Framework\TestCase
{
self::assertEquals(-3 / 2, Average::averageDatasetChange([6, 7, 6, 3, 0]));
}
public function testMean()
{
self::assertEquals(4, Average::arithmeticMean([1, 2, 3, 4, 5, 6, 7]), '', 0.01);
self::assertEquals(69 / 20, Average::weightedAverage(
[1, 2, 3, 4, 5, 6, 7],
[0.1, 0.2, 0.3, 0.1, 0.2, 0.05, 0.05]
), '', 0.01);
self::assertEquals(3.3800151591413, Average::geometricMean([1, 2, 3, 4, 5, 6, 7]), '', 0.01);
self::assertEquals(2.6997245179063, Average::harmonicMean([1, 2, 3, 4, 5, 6, 7]), '', 0.01);
self::assertEquals(-90, Average::angleMean([90.0, 180.0, 270.0, 360.0]), '', 0.01);
self::assertEquals(9.999999999999977, Average::angleMean([370.0]), '', 0.01);
self::assertEquals(270, Average::angleMean2([90.0, 180.0, 270.0, 360.0]), '', 0.01);
self::assertEquals(9.999999999999977, Average::angleMean2([370.0]), '', 0.01);
}
/**
* @expectedException phpOMS\Math\Matrix\Exception\InvalidDimensionException
*/
public function testInvalidWeightedAverageDimension()
{
Average::weightedAverage([1, 2, 3, 4, 5, 6, 7], [0.1, 0.2, 0.3, 0.1, 0.2, 0.05]);
}
/**
* @expectedException phpOMS\Math\Exception\ZeroDevisionException
*/
public function testInvalidArithmeticMeanZeroDevision()
{
Average::arithmeticMean([]);
}
/**
* @expectedException phpOMS\Math\Exception\ZeroDevisionException
*/
public function testInvalidGeometricMean()
{
Average::geometricMean([]);
}
/**
* @expectedException phpOMS\Math\Exception\ZeroDevisionException
*/
public function testInvalidHarmonicMean()
{
Average::harmonicMean([1, 2, 3, 0, 5, 6, 7]);
}
public function testMode()
{
self::assertEquals(2, Average::mode([1, 2, 2, 3, 4, 4, 2]), '', 0.01);
}
public function testMedia()
{
self::assertEquals(4, Average::median([1, 2, 3, 4, 5, 6, 7]), '', 0.01);
self::assertEquals(3.5, Average::median([1, 2, 3, 4, 5, 6]), '', 0.01);
}
}

View File

@ -17,8 +17,16 @@ use phpOMS\Math\Statistic\Basic;
class BasicTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
public function testFrequency()
{
self::markTestIncomplete();
self::assertEquals(
[1 / 10, 2 / 10, 3 / 10, 4 / 10],
Basic::frequency([1, 2, 3, 4])
);
self::assertEquals(
[1 / 10, 2 / 10, 3 / 10, [1 / 6, 2 / 6, 3 / 6], 4 / 10],
Basic::frequency([1, 2, 3, [1, 2, 3], 4])
);
}
}

View File

@ -17,8 +17,45 @@ use phpOMS\Math\Statistic\Correlation;
class CorrelationTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
public function testBravisPersonCorrelationCoefficient()
{
self::markTestIncomplete();
self::assertEquals(
0.8854,
Correlation::bravaisPersonCorrelationCoefficient(
[1, 2, 3, 4, 5, 6, 7],
[3, 4, 5, 9, 7, 8, 9]
), '', 0.01
);
}
public function testAutocorrelationCoefficient()
{
$data = [
1, 20, 31, 8, 40, 41, 46, 89, 72, 45, 81, 93,
41, 63, 17, 96, 68, 27, 41, 17, 26, 75, 63, 93,
18, 93, 80, 36, 4, 23, 81, 47, 61, 27, 13, 25,
51, 20, 65, 45, 87, 68, 36, 31, 79, 7, 95, 37
];
self::assertEquals(0.022, Correlation::autocorrelationCoefficient($data, 1), '', 0.01);
self::assertEquals(0.098, Correlation::autocorrelationCoefficient($data, 2), '', 0.01);
}
public function testPortmanteauTest()
{
$data = [
1, 20, 31, 8, 40, 41, 46, 89, 72, 45, 81, 93,
41, 63, 17, 96, 68, 27, 41, 17, 26, 75, 63, 93,
18, 93, 80, 36, 4, 23, 81, 47, 61, 27, 13, 25,
51, 20, 65, 45, 87, 68, 36, 31, 79, 7, 95, 37
];
$correlations = [];
for ($i = 0; $i < 24; $i++) {
$correlations[] = Correlation::autocorrelationCoefficient($data, $i + 1);
}
self::assertEquals(16.46, Correlation::boxPierceTest($correlations, 24, 48), '', 0.01);
self::assertEquals(24.92, Correlation::ljungBoxTest($correlations, 24, 48), '', 0.01);
}
}

View File

@ -21,4 +21,70 @@ class MeasureOfDispersionTest extends \PHPUnit\Framework\TestCase
{
self::assertEquals((float) (9 - 1), MeasureOfDispersion::range([4, 5, 9, 1, 3]));
}
public function testStandardDeviation()
{
self::assertEquals(2.160246, MeasureOfDispersion::standardDeviation([1, 2, 3, 4, 5, 6, 7]), '', 0.01);
}
public function testEmpiricalCovariance()
{
self::assertEquals(
4.667,
MeasureOfDispersion::empiricalCovariance(
[1, 2, 3, 4, 5, 6, 7],
[3, 4, 5, 9, 7, 8, 9]
), '', 0.01
);
}
public function testVariance()
{
self::assertEquals(6219.9, MeasureOfDispersion::sampleVariance([3, 21, 98, 203, 17, 9]), '', 0.01);
self::assertEquals(5183.25, MeasureOfDispersion::empiricalVariance([3, 21, 98, 203, 17, 9]), '', 0.01);
}
public function testDeviation()
{
self::assertEquals(0.0, MeasureOfDispersion::meanDeviation([3, 4, 5, 9, 7, 8, 9]), '', 0.01);
self::assertEquals(2.0816, MeasureOfDispersion::meanAbsoluteDeviation([3, 4, 5, 9, 7, 8, 9]), '', 0.01);
self::assertEquals((12.96 + 2.56 + 0.36 + 5.76 + 11.56) / 5, MeasureOfDispersion::squaredMeanDeviation([1, 3, 4, 7, 8]), '', 0.01);
}
public function testEmpiricalVariationCoefficient()
{
self::assertEquals(0.5400, MeasureOfDispersion::empiricalVariationCoefficient([1, 2, 3, 4, 5, 6, 7]), '', 0.01);
}
/**
* @expectedException phpOMS\Math\Exception\ZeroDevisionException
*/
public function testInvalidEmpiricalCovariance()
{
MeasureOfDispersion::empiricalCovariance([], []);
}
/**
* @expectedException phpOMS\Math\Matrix\Exception\InvalidDimensionException
*/
public function testInvalidEmpiricalCovarianceDimension()
{
MeasureOfDispersion::empiricalCovariance([1, 2, 3, 4], [1, 2, 3]);
}
/**
* @expectedException phpOMS\Math\Exception\ZeroDevisionException
*/
public function testInvalidSampleVariance()
{
MeasureOfDispersion::sampleVariance([]);
}
/**
* @expectedException phpOMS\Math\Exception\ZeroDevisionException
*/
public function testInvalidEmpiricalVariance()
{
MeasureOfDispersion::empiricalVariance([]);
}
}