2016-04-27 21:04:59 +00:00
|
|
|
<?php
|
2016-04-27 21:28:01 +00:00
|
|
|
|
2016-11-20 21:53:17 +00:00
|
|
|
declare(strict_types=1);
|
2016-04-27 21:04:59 +00:00
|
|
|
|
|
|
|
namespace Phpml\Math\Statistic;
|
|
|
|
|
|
|
|
use Phpml\Exception\InvalidArgumentException;
|
|
|
|
|
|
|
|
class StandardDeviation
|
|
|
|
{
|
|
|
|
/**
|
2018-02-10 17:07:09 +00:00
|
|
|
* @param array|float[]|int[] $numbers
|
2016-04-27 21:04:59 +00:00
|
|
|
*/
|
2018-02-10 17:07:09 +00:00
|
|
|
public static function population(array $numbers, bool $sample = true): float
|
2016-04-27 21:04:59 +00:00
|
|
|
{
|
2018-10-28 06:44:52 +00:00
|
|
|
$n = count($numbers);
|
|
|
|
if ($n === 0) {
|
2018-03-03 15:03:53 +00:00
|
|
|
throw new InvalidArgumentException('The array has zero elements');
|
2016-04-27 21:04:59 +00:00
|
|
|
}
|
2016-04-27 21:28:01 +00:00
|
|
|
|
2016-04-27 21:04:59 +00:00
|
|
|
if ($sample && $n === 1) {
|
2018-03-03 15:03:53 +00:00
|
|
|
throw new InvalidArgumentException('The array must have at least 2 elements');
|
2016-04-27 21:04:59 +00:00
|
|
|
}
|
2016-04-27 21:28:01 +00:00
|
|
|
|
2018-02-10 17:07:09 +00:00
|
|
|
$mean = Mean::arithmetic($numbers);
|
2016-04-27 21:04:59 +00:00
|
|
|
$carry = 0.0;
|
2018-02-10 17:07:09 +00:00
|
|
|
foreach ($numbers as $val) {
|
|
|
|
$carry += ($val - $mean) ** 2;
|
2016-11-20 21:53:17 +00:00
|
|
|
}
|
2016-04-27 21:04:59 +00:00
|
|
|
|
2016-04-27 21:28:01 +00:00
|
|
|
if ($sample) {
|
2016-04-27 21:04:59 +00:00
|
|
|
--$n;
|
|
|
|
}
|
|
|
|
|
2018-10-28 06:44:52 +00:00
|
|
|
return sqrt($carry / $n);
|
2016-04-27 21:04:59 +00:00
|
|
|
}
|
2018-02-10 17:07:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sum of squares deviations
|
|
|
|
* ∑⟮xᵢ - μ⟯²
|
|
|
|
*
|
|
|
|
* @param array|float[]|int[] $numbers
|
|
|
|
*/
|
|
|
|
public static function sumOfSquares(array $numbers): float
|
|
|
|
{
|
2018-10-28 06:44:52 +00:00
|
|
|
if (count($numbers) === 0) {
|
2018-03-03 15:03:53 +00:00
|
|
|
throw new InvalidArgumentException('The array has zero elements');
|
2018-02-10 17:07:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$mean = Mean::arithmetic($numbers);
|
|
|
|
|
|
|
|
return array_sum(array_map(
|
|
|
|
function ($val) use ($mean) {
|
|
|
|
return ($val - $mean) ** 2;
|
|
|
|
},
|
|
|
|
$numbers
|
|
|
|
));
|
|
|
|
}
|
2016-04-27 21:04:59 +00:00
|
|
|
}
|