22 include_once
'PEAR.php';
32 define(
'STATS_BASIC', 1);
36 define(
'STATS_FULL', 2);
44 define(
'STATS_DATA_SIMPLE', 0);
51 define(
'STATS_DATA_CUMMULATIVE', 1);
59 define(
'STATS_REJECT_NULL', -1);
64 define(
'STATS_IGNORE_NULL', -2);
69 define(
'STATS_USE_NULL_AS_ZERO', -3);
177 $this->_nullOption = $nullOption;
190 if (!is_array($arr)) {
191 return PEAR::raiseError(
'invalid data, an array of numeric data was expected');
194 $this->_dataExpanded = null;
195 $this->_dataOption = null;
196 $this->_calculatedValues = array();
198 $this->_dataOption = $opt;
199 $this->_data = array_values($arr);
201 $this->_dataOption = $opt;
203 $this->_dataExpanded = array();
218 if ($this->_data == null) {
240 $this->_nullOption = $nullOption;
244 'STATS_REJECT_NULL, STATS_IGNORE_NULL or STATS_USE_NULL_AS_ZERO');
260 $mean = $this->
mean();
264 $std = $this->
stDev();
269 return PEAR::raiseError(
'cannot studentize data, standard deviation is zero.');
273 foreach ($this->_data as $val=>$freq) {
274 $newval = ($val - $mean) / $std;
275 $arr[
"$newval"] = $freq;
278 foreach ($this->_data as $val) {
279 $newval = ($val - $mean) / $std;
283 return $this->
setData($arr, $this->_dataOption);
296 $mean = $this->
mean();
302 foreach ($this->_data as $val=>$freq) {
303 $newval = $val - $mean;
304 $arr[
"$newval"] = $freq;
307 foreach ($this->_data as $val) {
308 $newval = $val - $mean;
312 return $this->
setData($arr, $this->_dataOption);
326 function calc($mode, $returnErrorObject=
true) {
327 if ($this->_data == null) {
331 return $this->
calcBasic($returnErrorObject);
333 return $this->
calcFull($returnErrorObject);
335 return PEAR::raiseError(
'incorrect mode, expected STATS_BASIC or STATS_FULL');
351 'min' => $this->
__format($this->
min(), $returnErrorObject),
352 'max' => $this->
__format($this->
max(), $returnErrorObject),
353 'sum' => $this->
__format($this->
sum(), $returnErrorObject),
354 'sum2' => $this->
__format($this->
sum2(), $returnErrorObject),
355 'count' => $this->
__format($this->
count(), $returnErrorObject),
356 'mean' => $this->
__format($this->
mean(), $returnErrorObject),
357 'stdev' => $this->
__format($this->
stDev(), $returnErrorObject),
359 'range' => $this->
__format($this->
range(), $returnErrorObject)
375 'min' => $this->
__format($this->
min(), $returnErrorObject),
376 'max' => $this->
__format($this->
max(), $returnErrorObject),
377 'sum' => $this->
__format($this->
sum(), $returnErrorObject),
378 'sum2' => $this->
__format($this->
sum2(), $returnErrorObject),
379 'count' => $this->
__format($this->
count(), $returnErrorObject),
380 'mean' => $this->
__format($this->
mean(), $returnErrorObject),
382 'mode' => $this->
__format($this->
mode(), $returnErrorObject),
386 'stdev' => $this->
__format($this->
stDev(), $returnErrorObject),
389 'range' => $this->
__format($this->
range(), $returnErrorObject),
394 'sample_central_moments' => array (
401 'sample_raw_moments' => array (
428 if ($this->_data == null) {
431 if (!array_key_exists(
'min', $this->_calculatedValues)) {
433 $min =
min(array_keys($this->_data));
435 $min =
min($this->_data);
437 $this->_calculatedValues[
'min'] = $min;
439 return $this->_calculatedValues[
'min'];
452 if ($this->_data == null) {
455 if (!array_key_exists(
'max', $this->_calculatedValues)) {
457 $max =
max(array_keys($this->_data));
459 $max =
max($this->_data);
461 $this->_calculatedValues[
'max'] = $max;
463 return $this->_calculatedValues[
'max'];
477 if (!array_key_exists(
'sum', $this->_calculatedValues)) {
478 $sum = $this->
sumN(1);
482 $this->_calculatedValues[
'sum'] = $sum;
485 return $this->_calculatedValues[
'sum'];
499 if (!array_key_exists(
'sum2', $this->_calculatedValues)) {
500 $sum2 = $this->
sumN(2);
504 $this->_calculatedValues[
'sum2'] = $sum2;
507 return $this->_calculatedValues[
'sum2'];
522 if ($this->_data == null) {
527 foreach($this->_data as $val=>$freq) {
528 $sumN += $freq * pow((
double)$val, (
double)$n);
531 foreach($this->_data as $val) {
532 $sumN += pow((
double)$val, (
double)$n);
547 if (!array_key_exists(
'product', $this->_calculatedValues)) {
552 $this->_calculatedValues[
'product'] = $product;
555 return $this->_calculatedValues[
'product'];
568 if ($this->_data == null) {
573 foreach($this->_data as $val=>$freq) {
577 $prodN *= $freq * pow((
double)$val, (
double)$n);
580 foreach($this->_data as $val) {
584 $prodN *= pow((
double)$val, (
double)$n);
600 if ($this->_data == null) {
603 if (!array_key_exists(
'count', $this->_calculatedValues)) {
605 $count =
count($this->_dataExpanded);
607 $count =
count($this->_data);
609 $this->_calculatedValues[
'count'] = $count;
611 return $this->_calculatedValues[
'count'];
625 if (!array_key_exists(
'mean', $this->_calculatedValues)) {
630 $count = $this->
count();
634 $this->_calculatedValues[
'mean'] = $sum / $count;
636 return $this->_calculatedValues[
'mean'];
646 if (!array_key_exists(
'range', $this->_calculatedValues)) {
655 $this->_calculatedValues[
'range'] = $max - $min;
657 return $this->_calculatedValues[
'range'];
672 if (!array_key_exists(
'variance', $this->_calculatedValues)) {
677 $this->_calculatedValues[
'variance'] = $variance;
679 return $this->_calculatedValues[
'variance'];
692 if (!array_key_exists(
'stDev', $this->_calculatedValues)) {
697 $this->_calculatedValues[
'stDev'] = sqrt($variance);
699 return $this->_calculatedValues[
'stDev'];
736 return sqrt($varianceWM);
751 if (!array_key_exists(
'absDev', $this->_calculatedValues)) {
756 $this->_calculatedValues[
'absDev'] = $absDev;
758 return $this->_calculatedValues[
'absDev'];
796 if (!array_key_exists(
'skewness', $this->_calculatedValues)) {
797 $count = $this->
count();
801 $stDev = $this->
stDev();
809 $this->_calculatedValues[
'skewness'] = ($sumdiff3 / ($count * pow($stDev, 3)));
811 return $this->_calculatedValues[
'skewness'];
833 if (!array_key_exists(
'kurtosis', $this->_calculatedValues)) {
834 $count = $this->
count();
838 $stDev = $this->
stDev();
846 $this->_calculatedValues[
'kurtosis'] = ($sumdiff4 / ($count * pow($stDev, 4))) - 3;
848 return $this->_calculatedValues[
'kurtosis'];
865 if ($this->_data == null) {
868 if (!array_key_exists(
'median', $this->_calculatedValues)) {
880 $median = ($arr[$h] + $arr[$h - 1]) / 2;
882 $median = $arr[$h + 1];
884 $this->_calculatedValues[
'median'] = $median;
886 return $this->_calculatedValues[
'median'];
901 if ($this->_data == null) {
904 if (!array_key_exists(
'mode', $this->_calculatedValues)) {
912 foreach ($arr as $val=>$freq) {
924 $this->_calculatedValues[
'mode'] = $mode;
926 return $this->_calculatedValues[
'mode'];
941 if (!array_key_exists(
'midrange', $this->_calculatedValues)) {
950 $this->_calculatedValues[
'midrange'] = (($max + $min) / 2);
952 return $this->_calculatedValues[
'midrange'];
966 if (!array_key_exists(
'geometricMean', $this->_calculatedValues)) {
967 $count = $this->
count();
979 return PEAR::raiseError(
'The product of the data set is negative, geometric mean undefined.');
981 $this->_calculatedValues[
'geometricMean'] = pow($prod , 1 / $count);
983 return $this->_calculatedValues[
'geometricMean'];
996 if ($this->_data == null) {
999 if (!array_key_exists(
'harmonicMean', $this->_calculatedValues)) {
1000 $count = $this->
count();
1006 foreach($this->_data as $val=>$freq) {
1009 'harmonic mean with data values of zero.');
1011 $invsum += $freq / $val;
1014 foreach($this->_data as $val) {
1017 'harmonic mean with data values of zero.');
1019 $invsum += 1 / $val;
1022 $this->_calculatedValues[
'harmonicMean'] = $count / $invsum;
1024 return $this->_calculatedValues[
'harmonicMean'];
1041 if (!is_int($n) || $n < 1) {
1042 return PEAR::isError(
'moment must be a positive integer >= 1.');
1048 $count = $this->
count();
1054 'there are zero data entries');
1060 return ($sum / $count);
1077 if (!is_int($n) || $n < 1) {
1078 return PEAR::isError(
'moment must be a positive integer >= 1.');
1081 $count = $this->
count();
1087 'there are zero data entries.');
1089 $sum = $this->
sumN($n);
1093 return ($sum / $count);
1110 if (!array_key_exists(
'coeffOfVariation', $this->_calculatedValues)) {
1111 $mean = $this->
mean();
1117 'of variation, mean of sample is zero');
1119 $stDev = $this->
stDev();
1124 $this->_calculatedValues[
'coeffOfVariation'] = $stDev / $mean;
1126 return $this->_calculatedValues[
'coeffOfVariation'];
1147 if (!array_key_exists(
'stdErrorOfMean', $this->_calculatedValues)) {
1148 $count = $this->
count();
1152 $stDev = $this->
stDev();
1156 $this->_calculatedValues[
'stdErrorOfMean'] = $stDev / sqrt($count);
1158 return $this->_calculatedValues[
'stdErrorOfMean'];
1172 if ($this->_data == null) {
1175 if (!array_key_exists(
'frequency', $this->_calculatedValues)) {
1180 foreach ($this->_data as $val) {
1185 $this->_calculatedValues[
'frequency'] = $freq;
1187 return $this->_calculatedValues[
'frequency'];
1200 if (!array_key_exists(
'quartiles', $this->_calculatedValues)) {
1213 $this->_calculatedValues[
'quartiles'] = array (
1219 return $this->_calculatedValues[
'quartiles'];
1236 if (!array_key_exists(
'interquartileMean', $this->_calculatedValues)) {
1245 foreach ($this->
getData(
true) as $val) {
1246 if ($val >= $q1 && $val <= $q3) {
1253 'empty interquartile range of values.');
1255 $this->_calculatedValues[
'interquartileMean'] = $sum / $n;
1257 return $this->_calculatedValues[
'interquartileMean'];
1274 if (!array_key_exists(
'interquartileRange', $this->_calculatedValues)) {
1281 $this->_calculatedValues[
'interquartileRange'] = $q3 - $q1;
1283 return $this->_calculatedValues[
'interquartileRange'];
1299 if (!array_key_exists(
'quartileDeviation', $this->_calculatedValues)) {
1304 $this->_calculatedValues[
'quartileDeviation'] = $iqr / 2;
1306 return $this->_calculatedValues[
'quartileDeviation'];
1322 if (!array_key_exists(
'quartileVariationCoefficient', $this->_calculatedValues)) {
1331 $this->_calculatedValues[
'quartileVariationCoefficient'] = 100 *
$d / $s;
1333 return $this->_calculatedValues[
'quartileVariationCoefficient'];
1350 if (!array_key_exists(
'quartileSkewnessCoefficient', $this->_calculatedValues)) {
1358 $d = $q3 - 2*$q2 + $q1;
1360 $this->_calculatedValues[
'quartileSkewnessCoefficient'] =
$d / $s;
1362 return $this->_calculatedValues[
'quartileSkewnessCoefficient'];
1390 $count = $this->
count();
1399 $obsidx = $p * ($count + 1) / 100;
1400 if (intval($obsidx) == $obsidx) {
1401 return $data[($obsidx - 1)];
1402 } elseif ($obsidx < 1) {
1404 } elseif ($obsidx > $count) {
1405 return $data[($count - 1)];
1407 $left = floor($obsidx - 1);
1408 $right = ceil($obsidx - 1);
1429 if ($this->_data == null) {
1432 if (is_null($mean)) {
1433 $mean = $this->
mean();
1440 foreach ($this->_data as $val=>$freq) {
1441 $sdiff += $freq * pow((
double)($val - $mean), (
double)$power);
1444 foreach ($this->_data as $val)
1445 $sdiff += pow((
double)($val - $mean), (
double)$power);
1461 if ($this->_data == null) {
1468 $count = $this->
count();
1473 return PEAR::raiseError(
'cannot calculate variance of a singe data point');
1475 return ($sumdiff2 / ($count - 1));
1489 if ($this->_data == null) {
1492 $count = $this->
count();
1500 return $sumabsdev / $count;
1514 if ($this->_data == null) {
1517 if (is_null($mean)) {
1518 $mean = $this->
mean();
1522 foreach ($this->_data as $val=>$freq) {
1523 $sdev += $freq * abs($val - $mean);
1526 foreach ($this->_data as $val) {
1527 $sdev += abs($val - $mean);
1547 return $v->getMessage();
1564 foreach ($this->_data as $key=>$value) {
1565 $d = ($flag) ? $key : $value;
1566 $v = ($flag) ? $value : $key;
1567 if (!is_numeric(
$d)) {
1568 switch ($this->_nullOption) {
1570 unset($this->_data[
"$key"]);
1574 unset($this->_data[
"$key"]);
1575 $this->_data[0] += $v;
1577 $this->_data[$key] = 0;
1588 ksort($this->_data);
1589 $this->_dataExpanded = array();
1590 foreach ($this->_data as $val=>$freq) {
1591 $this->_dataExpanded = array_pad($this->_dataExpanded,
count($this->_dataExpanded) + $freq, $val);
1593 sort($this->_dataExpanded);