MediaWiki  REL1_24
RunningStat.php
Go to the documentation of this file.
00001 <?php
00024 // Needed due to PHP non-bug <https://bugs.php.net/bug.php?id=49828>.
00025 define( 'NEGATIVE_INF', -INF );
00026 
00052 class RunningStat implements Countable {
00053 
00055     public $n = 0;
00056 
00058     public $m1 = 0.0;
00059 
00061     public $m2 = 0.0;
00062 
00064     public $min = INF;
00065 
00067     public $max = NEGATIVE_INF;
00068 
00073     public function count() {
00074         return $this->n;
00075     }
00076 
00081     public function push( $x ) {
00082         $x = (float) $x;
00083 
00084         $this->min = min( $this->min, $x );
00085         $this->max = max( $this->max, $x );
00086 
00087         $n1 = $this->n;
00088         $this->n += 1;
00089         $delta = $x - $this->m1;
00090         $delta_n = $delta / $this->n;
00091         $this->m1 += $delta_n;
00092         $this->m2 += $delta * $delta_n * $n1;
00093     }
00094 
00103     public function getMean() {
00104         return $this->m1;
00105     }
00106 
00117     public function getVariance() {
00118         if ( $this->n === 0 ) {
00119             // The variance of the empty set is undefined.
00120             return NAN;
00121         } elseif ( $this->n === 1 ) {
00122             return 0.0;
00123         } else {
00124             return $this->m2 / ( $this->n - 1.0 );
00125         }
00126     }
00127 
00138     public function getStdDev() {
00139         return sqrt( $this->getVariance() );
00140     }
00141 
00150     public function merge( RunningStat $other ) {
00151         // If the other RunningStat is empty, there's nothing to do.
00152         if ( $other->n === 0 ) {
00153             return;
00154         }
00155 
00156         // If this RunningStat is empty, copy values from other RunningStat.
00157         if ( $this->n === 0 ) {
00158             $this->n = $other->n;
00159             $this->m1 = $other->m1;
00160             $this->m2 = $other->m2;
00161             $this->min = $other->min;
00162             $this->max = $other->max;
00163             return;
00164         }
00165 
00166         $n = $this->n + $other->n;
00167         $delta = $other->m1 - $this->m1;
00168         $delta2 = $delta * $delta;
00169 
00170         $this->m1 = ( ( $this->n * $this->m1 ) + ( $other->n * $other->m1 ) ) / $n;
00171         $this->m2 = $this->m2 + $other->m2 + ( $delta2 * $this->n * $other->n / $n );
00172         $this->min = min( $this->min, $other->min );
00173         $this->max = max( $this->max, $other->max );
00174         $this->n = $n;
00175     }
00176 }