Fixed update_average() function to do the right thing when the time

between successive calls is small (zero seconds):

Consider the limit
as diff->0, using the first-order Taylor expansion of
exp(x)=1+x+O(x^2).
So to the lowest order in diff:
weight = 1 - diff ln(2) / half_life
so one has
avg += (1-weight)*(work/diff_days)
avg += [diff*ln(2)/half_life] * (work*SECONDS_PER_DAY/diff)
notice that diff cancels out, leaving
avg += [ln(2)/half_life] * work*SECONDS_PER_DAY

svn path=/trunk/boinc/; revision=5978
This commit is contained in:
Bruce Allen 2005-04-29 19:22:43 +00:00
parent 2c917cd32d
commit f8de417987
2 changed files with 11 additions and 2 deletions

View File

@ -5870,4 +5870,7 @@ Bruce 29 April 2005
lib/ lib/
util.C util.C
html/
inc/
credit.inc

View File

@ -8,11 +8,17 @@ define("CREDIT_HALF_LIFE", 86400*7);
function update_average($now, $work_start_time, $work, &$avg, &$avg_time) { function update_average($now, $work_start_time, $work, &$avg, &$avg_time) {
if ($avg_time) { if ($avg_time) {
$diff = $now - $avg_time; $diff = $now - $avg_time;
if ($diff <=0) $diff = 3600; if ($diff <0) $diff = 0;
$diff_days = $diff/86400; $diff_days = $diff/86400;
$weight = exp(-$diff*M_LN2/CREDIT_HALF_LIFE); $weight = exp(-$diff*M_LN2/CREDIT_HALF_LIFE);
$avg *= $weight; $avg *= $weight;
$avg += (1-$weight)*($work/$diff_days);
if ((1.0-$weight)>0.000001) {
$avg += (1.0-$weight)*($work/$diff_days);
}
else {
$avg += M_LN2*work*86400/CREDIT_HALF_LIFE;
}
} else if ($work) { } else if ($work) {
$dd = ($now - $work_start_time)/86400; $dd = ($now - $work_start_time)/86400;
$avg = $work/$dd; $avg = $work/$dd;