In this post are two methods for calculating the average of a dataset. The standard method proves to be problematic for some cases, where the element values are large or the range is large. These two algorithms agree UNTIL n becomes large, then the truncation errors start creeping in for the standard method, using a running sum of all the elements in the range. The numerically stable method avoids this error quite well. In this particular instance, the numerically stable version lags the standard method by 50% or so, but the fact that overflow is completely avoided may be of benefit in some cases when dealing with large datasets or numbers that are large or perhaps even both.
ntest& = 0
ntest& = ntest& + 1
a(q&) = ntest& / 2 + .125
AverageArrayNS a
(), LBOUND(a
), ntest&
, average#
PRINT "numerically stable "; ntest&; average#; f0!
- s0!
AverageStandardX a
(), LBOUND(a
), ntest&
, averagx#
PRINT "standard not stable"; ntest&; averagx#; f1!
- s1!
ntest& = ntest& * 2
'****************
'* this method is subject to truncation/overflow errors -- fails at large N.
'****************
sum# = 0
sum# = sum# + a(c&)
a# = sum# / (finish - start + 1)
'****************
'* a numerically stable way to calculate the average of elements in an array without the dreaded overflow.
'****************
DIM StatN
AS LONG: StatN
= finish
- start
+ 1
aa_temp = a(c&) + aa_temp
aa_int = aa_int + 1
aa_temp = aa_temp - StatN
average = aa_int + aa_temp / StatN
Just another perhaps boring but useful algo to add to your code arsenal if overflow is to be avoided at all costs and results MUST be accurate.