Created
January 18, 2018 10:40
-
-
Save jlsa/cafb5af21d03942967f8a3814040c356 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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