Skip to content

Instantly share code, notes, and snippets.

@jlsa
Created January 18, 2018 10:40
Show Gist options
  • Select an option

  • Save jlsa/cafb5af21d03942967f8a3814040c356 to your computer and use it in GitHub Desktop.

Select an option

Save jlsa/cafb5af21d03942967f8a3814040c356 to your computer and use it in GitHub Desktop.
<?php
/**
* A class that can be used for calculating statistics.
* Created to help me learn statistical formulas for my exam.
* @author Joël Hoekstra
* @version 2015-07-03
* @since 2015-07-01
*/
class Statistic
{
public function __construct() { }
/**
* Gets the average from a list of numbers
* @param List with numbers
* @return The average of the given numbers
*/
public function getAverage($numbers) {
$sum = 0;
foreach($numbers as $number) {
$sum += $number;
}
$average = $sum / $this->numRows($numbers);
return $average;
}
/**
* Synonym for getAverage.
*/
public function getMean($numbers) {
return $this->getAverage($numbers);
}
/**
* Gets the Highest number from a list of numbers
* @param List with numbers
* @return The highest number
*/
public function getHighest($numbers) {
$highest = ~PHP_INT_MIN;
for($i = 0; $i < $this->numRows($numbers); $i++) {
$number = $numbers[$i];
if($number > $highest) {
$highest = $number;
}
}
return $highest;
}
/**
* Gets the Lowest number from a list of numbers
* @param List with numbers
* @return The lowest number
*/
public function getLowest($numbers) {
$lowest = PHP_INT_MAX;
for($i = 0; $i < $this->numRows($numbers); $i++) {
$number = $numbers[$i];
if($number < $lowest) {
$lowest = $number;
}
}
return $lowest;
}
/**
* Gets the Median from a list of numbers
* @param List with numbers
* @return Median
*/
public function getMedian($numbers) {
$count = $this->numRows($numbers);
$even = $this->isEven($count);
$median = 0;
$num1 = ($count / 2);
if($even) {
// get two numbers from the numbers list
$num2 = $num1;
$median = ($numbers[$num1-1] + $numbers[$num2]) / 2;
} else {
// get just the middle number
$median = $numbers[$num1];
}
return $median;
}
/**
* Gets the First Quartile from a list of numbers
* @param List with numbers
* @return The First Quartile
*/
public function getFirstQuartile($numbers) {
$count = $this->numRows($numbers)/2;
$even = $this->isEven($count);
$median = 0;
$num1 = ($count / 2)-1;
$num2 = ($count / 2);
if($even) {
// get two numbers from the numbers list
$median = ($numbers[$num1] + $numbers[$num2]) / 2;
} else {
// get just the middle number
$median = $numbers[$num1];
}
return $median;
}
/**
* Gets the Third Quartile from a list of numbers
* @param List with numbers
* @return The Third Quartile
*/
public function getThirdQuartile($numbers) {
$count = $this->numRows($numbers)/2;
$even = $this->isEven($count);
$median = 0;
$num1 = (($count / 2)-1) + $count;
$num2 = ($count / 2)+$count;
if($even) {
// get two numbers from the numbers list
$median = ($numbers[$num1] + $numbers[$num2]) / 2;
} else {
// get just the middle number
$median = $numbers[$num1];
}
return $median;
}
/**
* Calculates and returns the Quartile Deviation
* @param List with numbers
* @return The Quartile Deviation
*/
public function getQuartileDeviation($numbers) {
$qd = ($this->getThirdQuartile($numbers) - $this->getFirstQuartile($numbers)) / 2;
return $qd;
}
/**
* Calculates and returns the Inter Quartile Range
* @param List with numbers
* @return The Inter Quartile Range
*/
public function getInterquartileRange($numbers) {
$iqr = $this->getThirdQuartile($numbers) - $this->getFirstQuartile($numbers);
return $iqr;
}
/**
* Gets the Variance
* @param List with numbers
* @return The Variance
*/
public function getVariance($numbers) {
$mean = $this->getMean($numbers);
$sum = 0;
foreach($numbers as $grade) {
$num = $grade - $mean;
$sum += pow($num, 2);
}
return $sum / ($this->numRows($numbers)-1);
}
/**
* Calculates and returns the Standard Deviation
* @param List with numbers
* @return The Standard Deviation
*/
public function getStandardDeviation($numbers) {
$sd = sqrt($this->getVariance($numbers));
return $sd;
}
/**
* Calculates and returns the Minimum Standard Deviation
* @param List with numbers
* @return The Minimum Standard Deviation
*/
public function getMinimumStandardDeviation($numbers) {
$minsd = $this->getMean($numbers) - $this->getStandardDeviation($numbers);
return $minsd;
}
/**
* Calculates and returns the Maximum Standard Deviation
* @param List with numbers
* @return The Maximum Standard Deviation
*/
public function getMaximumStandardDeviation($numbers) {
$maxsd = $this->getMean($numbers) + $this->getStandardDeviation($numbers);
return $maxsd;
}
/**
* Calculates and returns the Population Standard Deviation
* @param List with numbers
* @return The Population Standard Deviation
*/
public function getPopulationStandardDeviation($numbers) {
$mean = $this->getMean($numbers);
$sum = 0;
foreach($numbers as $grade) {
$num = $grade - $mean;
$sum += pow($num, 2);
}
$psd = sqrt($sum / $this->numRows($numbers));
return $psd;
}
/**
* Calculates and returns the Range of the numbers
* @param List with numbers
* @return The Range
*/
public function getRange($numbers) {
$range = $this->getHighest($numbers) - $this->getLowest($numbers);
return $range;
}
/**
* Gets a single Mode from the list of numbers.
* @return A single mode
*/
public function getMode($numbers) {
$mode = 0;
$occurence = array();
$grades = array();
$i = 0;
foreach($numbers as $grade) {
if(!in_array($grade, $grades)) {
$grades[$i] = $grade;
$i++;
}
$occurence[array_search($grade, $grades)]++;
}
return $grades[array_search(max($occurence), $occurence)];
}
/**
* Check if a number is even or uneven.
*
* @param Number
* @return True when even, false when uneven
*/
public function isEven($num) {
if($num % 2 == 0) {
return true;
} else {
return false;
}
}
/**
* Synonym for count. I think it looks better for someone
* who doesnt really know PHP.
*
* @param The list with numbers
* @return The number of rows in the list
*/
public function numRows($numbers) {
return count($numbers);
}
/**
* Find the Mean Absolute Deviation in the array of numbers.
* @return The Mean Absolute Deviation
*/
public function getMad($numbers) {
$distance = 0;
foreach($numbers as $number) {
$distance += abs($this->getDistance($number, $numbers) );
}
$distance = $distance/$this->numRows($numbers);
return $distance;
}
/**
* Calculates the distance between the total numbers and the given number
*
* @param Number to calculate the distance with
* @param Numbers list
* @return Distance
*/
public function getDistance($number, $numbers) {
$distance = $number - $this->getMean($numbers);
return $distance;
}
/**
* Calculates the Mean from an classes table
*
* @param Data array
* @return The class Mean
*/
public function getClassMean($data) {
$orderedData = array();
$total = 0;
foreach($data as $keys => $values) {
if($keys === 'classes') {
foreach($values as $class) {
$orderedData[$class] = array();
}
}
if($keys === 'ranges') {
$i = 0;
foreach($values as $ranges) {
$sum = (($ranges['high'] - $ranges['low']) / 2) + $ranges['low'];
$classRange = $ranges['high'] - $ranges['low'];
$orderedData[$i+1]['m'] = $sum;
$i++;
}
}
if($keys === 'frequency') {
$i = 0;
foreach($values as $frequency) {
$orderedData[$i+1]['f'] = $frequency;
$total += $frequency;
$i++;
}
}
}
$sum = 0;
foreach($orderedData as $od) {
$sum += $od['m'] * $od['f'];
}
$mean = $sum / $total;
return $mean;
}
/**
* Calculates the Median from an classes table
*
* @param Data array
* @return The class Median
*/
public function getClassMedian($data) {
$l = 0;
$r = 0;
$b = 0;
$f = 0;
$total = 0;
$orderedData = array();
foreach($data as $keys => $values) {
if($keys === 'classes') {
foreach($values as $class) {
$orderedData[$class] = array();
}
}
if($keys === 'ranges') {
$i = 0;
foreach($values as $ranges) {
$classRange = $ranges['high'] - $ranges['low'];
$orderedData[$i+1]['l'] = $ranges['low'];
$orderedData[$i+1]['b'] = $classRange;
$i++;
}
}
if($keys === 'frequency') {
$i = 0;
foreach($values as $frequency) {
$orderedData[$i+1]['f'] = $frequency;
$total += $frequency;
$i++;
}
}
}
// time for some math
$medianPosition = ($total/2);
if($this->isEven($medianPosition)) {
$medianPositionLow = $medianPosition;
$medianPositionHigh = $medianPosition+1;
}
$count = 0;
$class = 0;
foreach($orderedData as $keys => $values) {
if($count+$values['f'] < $medianPosition) {
if($class !== $keys) {
$class = $keys;
$count += $values['f'];
}
}
}
$class++;
$r = $medianPosition - $count;
$f = $orderedData[$class]['f'];
$l = $orderedData[$class]['l'];
$b = $orderedData[$class]['b'];
$sum = $l + ($r - 0.5) * ($b / $f);
if($this->isEven($medianPosition)) {
$r = $medianPositionHigh - $count;
$f = $orderedData[$class]['f'];
$l = $orderedData[$class]['l'];
$b = $orderedData[$class]['b'];
$sum = ($sum + $l + ($r - 0.5) * ($b / $f)) / 2;
}
return $sum;
}
/**
* Calculates the Correlation Co-Efficient from the given data
*
* @param Data array
* @return The Correlation Co-Efficient
*/
public function getCorrelationCoEfficient($data) {
// preparing all the data
$correlation = 0;
$xTotal = 0;
$yTotal = 0;
$n = count($data['x']);
foreach($data['x'] as $x) {
$xTotal+=$x;
}
foreach($data['y'] as $y) {
$yTotal+=$y;
}
$xy = array();
$xx = array();
$yy = array();
$xyTotal = 0;
$xxTotal = 0;
$yyTotal = 0;
for($i = 0; $i < count($data['x']); $i++) {
$x = $data['x'][$i];
$y = $data['y'][$i];
$xy[$i] = $x * $y;
$xyTotal += $xy[$i];
$xx[$i] = $x * $x;
$xxTotal += $xx[$i];
$yy[$i] = $y * $y;
$yyTotal += $yy[$i];
}
/*
* Now calculating all the data into the Correlation Co-Efficient
* r = sum(x * y) - n * mean(x) * mean(y) / sqrt( (sum(x2) - n * mean(x)2) * (sum(y2) - n * mean(y)2) )
*/
$xMean = $xTotal/$n;
$yMean = $yTotal/$n;
// r is split in two parts because the formula is very long and this makes it more clear
$rTop = $xyTotal - ($n * ($xMean) * round($yMean,2));
$rBottom = sqrt( ($xxTotal - $n * pow($xMean,2)) * ($yyTotal - $n * pow($yMean,2)) );
$r = $rTop / $rBottom;
// debug purposes!
/*echo '<pre>';
echo 'n: ' . $n . '<br>';
echo 'x total: ' . $xTotal . '<br>';
echo 'y total: ' . $yTotal . '<br>';
echo 'xy total: ' . $xyTotal . '<br>';
echo 'xx total: ' . $xxTotal . '<br>';
echo 'yy total: ' . $yyTotal . '<br>';
echo 'mean x: ' . $xMean . '<br>';
echo 'mean y: ' . round($yMean, 2) . '<br>';
echo 'r bottom: ' . $rBottom . '<br>';
echo 'r top: ' . $rTop . '<br>';
echo 'r: ' . $r . '<br>';
echo 'sqrt(' . sqrt(($xxTotal - $n * pow($xMean,2))) . ')<br>';
echo "($xxTotal - $n * pow($xMean,2)) <br>";
echo "($yyTotal - $n * pow($yMean,2))";
echo '</pre>';
*/
return $r;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment