commit 046e695924a7f12912966391906a0115ac166f91 parent 37e13093a9e295b05a943037ccc4d2aef10c1d92 Author: Michael Savage <mikejsavage@gmail.com> Date: Sun Jan 17 16:58:31 +0000 Add quartile estimation to stats.cc Diffstat:
stats.cc | | | 35 | ++++++++++++++++++++++++++--------- |
stats.h | | | 11 | ++++++++--- |
diff --git a/stats.cc b/stats.cc @@ -1,19 +1,21 @@ #include <stdio.h> #include <math.h> +#include <algorithm> #include "intrinsics.h" #include "stats.h" void stats_init( Stats * stats ) { *stats = { }; + rng_well512_init( &stats->rng ); } double stats_mean( const Stats * stats ) { - return stats->sum / stats->num_samples; + return stats->sum / stats->num_records; } double stats_stddev( const Stats * stats ) { - double variance = ( stats->sum_of_squares - ( stats->sum * stats->sum / stats->num_samples ) ); + double variance = ( stats->sum_of_squares - ( stats->sum * stats->sum / stats->num_records ) ); return sqrt( variance ); } @@ -21,7 +23,7 @@ void stats_record( Stats * stats, double x ) { stats->sum += x; stats->sum_of_squares += x * x; - if( stats->num_samples == 0 ) { + if( stats->num_records == 0 ) { stats->min = stats->max = x; } else { @@ -29,14 +31,29 @@ void stats_record( Stats * stats, double x ) { if( x > stats->max ) stats->max = x; } - stats->num_samples++; + if( stats->num_records < STATS_NUM_QUART_SAMPLES ) { + stats->samples[ stats->num_records ] = x; + } + else { + double p = ( double ) STATS_NUM_QUART_SAMPLES / ( stats->num_records + 1.0 ); + + if( rng_p( &stats->rng, p ) ) { + u32 i = rng_uniform( &stats->rng, STATS_NUM_QUART_SAMPLES ); + stats->samples[ i ] = x; + } + } + + stats->num_records++; } -void stats_print( const Stats * stats, const char * name ) { - printf( "[%s]\n\tn: %llu\n\tmean: %f\n\tstddev: %f\n\trange: %f to %f\n", - name, stats->num_samples, +void stats_print( Stats * stats, const char * name ) { + u32 num_samples = min( stats->num_records, ( u64 ) STATS_NUM_QUART_SAMPLES ); + std::sort( stats->samples, stats->samples + num_samples ); + + printf( "[%s]\n\tn: %llu\n\tmean: %f\n\tstddev: %f\n\trange: %f to %f\n\t25%%: %f 75%%: %f", + name, stats->num_records, stats_mean( stats ), stats_stddev( stats ), - stats->min, stats->max + stats->min, stats->max, + stats->samples[ num_samples / 4 ], stats->samples[ num_samples * 3 / 4 ] ); } - diff --git a/stats.h b/stats.h @@ -2,20 +2,25 @@ #define _STATS_H_ #include "intrinsics.h" +#include "rng/well512.h" + +const u32 STATS_NUM_QUART_SAMPLES = 1024; struct Stats { double sum; double sum_of_squares; double min; double max; - u64 num_samples; -}; + u64 num_records; + RNGWell512 rng; + double samples[ STATS_NUM_QUART_SAMPLES ]; +}; void stats_init( Stats * stats ); double stats_mean( const Stats * stats ); double stats_stddev( const Stats * stats ); void stats_record( Stats * stats, double x ); -void stats_print( const Stats * stats, const char * name ); +void stats_print( Stats * stats, const char * name = "stats" ); #endif // _STATS_H_