points as $point ) { $rstat->push( $point ); } $mean = array_sum( $this->points ) / count( $this->points ); $variance = array_sum( array_map( function ( $x ) use ( $mean ) { return pow( $mean - $x, 2 ); }, $this->points ) ) / ( count( $rstat ) - 1 ); $stddev = sqrt( $variance ); $this->assertEquals( count( $rstat ), count( $this->points ) ); $this->assertEquals( $rstat->min, min( $this->points ) ); $this->assertEquals( $rstat->max, max( $this->points ) ); $this->assertEquals( $rstat->getMean(), $mean ); $this->assertEquals( $rstat->getVariance(), $variance ); $this->assertEquals( $rstat->getStdDev(), $stddev ); } /** * When one RunningStat instance is merged into another, the state of the * target RunningInstance should have the state that it would have had if * all the data had been accumulated by it alone. * @covers RunningStat::merge * @covers RunningStat::count */ public function testRunningStatMerge() { $expected = new RunningStat(); foreach( $this->points as $point ) { $expected->push( $point ); } // Split the data into two sets $sets = array_chunk( $this->points, floor( count( $this->points ) / 2 ) ); // Accumulate the first half into one RunningStat object $first = new RunningStat(); foreach( $sets[0] as $point ) { $first->push( $point ); } // Accumulate the second half into another RunningStat object $second = new RunningStat(); foreach( $sets[1] as $point ) { $second->push( $point ); } // Merge the second RunningStat object into the first $first->merge( $second ); $this->assertEquals( count( $first ), count( $this->points ) ); $this->assertEquals( $first, $expected ); } }