medfall

A super great game engine
Log | Files | Refs

stats.cc (1670B)


      1 #include <stdio.h>
      2 #include <math.h>
      3 #include <algorithm>
      4 
      5 #include "intrinsics.h"
      6 #include "stats.h"
      7 #include "ggformat.h"
      8 #include "rng/pcg.h"
      9 
     10 void stats_init( Stats * stats ) {
     11 	*stats = { };
     12 	stats->rng = new_pcg();
     13 }
     14 
     15 double stats_mean( const Stats * stats ) {
     16 	return stats->sum / stats->num_records;
     17 }
     18 
     19 double stats_stddev( const Stats * stats ) {
     20 	double variance = ( stats->sum_of_squares - ( stats->sum * stats->sum / stats->num_records ) );
     21 	return sqrt( variance );
     22 }
     23 
     24 void stats_record( Stats * stats, double x ) {
     25 	stats->sum += x;
     26 	stats->sum_of_squares += x * x;
     27 
     28 	// update min/max
     29 	if( stats->num_records == 0 ) {
     30 		stats->min = stats->max = x;
     31 	}
     32 	else {
     33 		stats->min = min( x, stats->min );
     34 		stats->max = max( x, stats->max );
     35 	}
     36 
     37 	// see if we should keep this sample
     38 	if( stats->num_records < STATS_NUM_QUART_SAMPLES ) {
     39 		stats->samples[ stats->num_records ] = x;
     40 	}
     41 	else {
     42 		double p = ( double ) STATS_NUM_QUART_SAMPLES / ( stats->num_records + 1.0 );
     43 
     44 		if( rng_p( &stats->rng, p ) ) {
     45 			u32 i = rng_mod( &stats->rng, STATS_NUM_QUART_SAMPLES );
     46 			stats->samples[ i ] = x;
     47 		}
     48 	}
     49 
     50 	stats->num_records++;
     51 }
     52 
     53 void format( FormatBuffer * fb, const Stats & stats, const FormatOpts & opts ) {
     54 	u32 num_samples = checked_cast< u32 >( min( stats.num_records, u64( STATS_NUM_QUART_SAMPLES ) ) );
     55 	std::sort( stats.samples, stats.samples + num_samples );
     56 
     57 	ggformat_impl( fb, "total = {}, n = {}, mean = {}, stddev = {}, min = {}, 25% = {}, 75% = {}, max = {}",
     58 		stats.sum, stats.num_records,
     59 		stats_mean( &stats ), stats_stddev( &stats ),
     60 		stats.min,
     61 		stats.samples[ num_samples / 4 ],
     62 		stats.samples[ num_samples * 3 / 4 ],
     63 		stats.max
     64 	);
     65 }