svn path=/trunk/boinc/; revision=19464

This commit is contained in:
David Anderson 2009-11-04 23:23:19 +00:00
parent a83b3fa3ba
commit 2f636a6f62
1 changed files with 40 additions and 19 deletions

View File

@ -18,41 +18,62 @@
struct AVERAGE { struct AVERAGE {
double n; // double to avoid integer overflow double n; // double to avoid integer overflow
double weight;
// if n < MIN_SAMPLES, sum of weights
// else recent average weight
double mean; double mean;
double sum_var; // if n < MIN_SAMPLES, weighted sum of samples
// sample variance is this divided by (n-1) // else recent average
double recent_mean; double var;
double recent_var; // if n < MIN_SAMPLES, weighted sum of vars
// else recent var
void update(double sample) { void update(double sample, double w) {
double delta;
if (sample < 0) return; if (sample < 0) return;
if (n > MIN_SAMPLES) { if (n > MIN_SAMPLES) {
if (sample > recent_mean*SAMPLE_LIMIT) { if (sample > mean*SAMPLE_LIMIT) {
sample = recent_mean*SAMPLE_LIMIT; sample = mean*SAMPLE_LIMIT;
} }
} }
n++; n++;
double delta = sample - mean;
mean += delta/n;
sum_var += delta*(sample-mean);
if (n < MIN_SAMPLES) { if (n < MIN_SAMPLES) {
recent_mean = mean; weight += w;
recent_var = sum_var/n; mean += w*sample;
delta = (sample - mean/weight);
var += delta*delta*w;
} else if (n == MIN_SAMPLES) {
mean /= weight;
var /= weight;
weight /= n;
} else { } else {
// update recent averages // update recent averages
delta = sample - recent_mean; if (w > weight*10) w = weight*10;
recent_mean += SAMPLE_WEIGHT*delta; double rel_weight = w/weight;
double d2 = delta*delta - recent_var; double sample_weight = SAMPLE_WEIGHT * rel_weight;
recent_var += SAMPLE_WEIGHT*d2;
delta = sample - mean;
mean += sample_weight*delta;
double d2 = delta*delta - var;
var += sample_weight*d2;
weight += SAMPLE_WEIGHT*(w - weight);
}
}
double get_mean() {
if (n < MIN_SAMPLES) {
return mean/weight;
} else {
return mean;
} }
} }
void clear() { void clear() {
n = 0; n = 0;
weight = 0;
mean = 0; mean = 0;
sum_var = 0; var = 0;
recent_mean = 0;
recent_var = 0;
} }
}; };