The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Message from discussion Incremental Averaging

From:
To:
Cc:
Followup To:
Subject:
 Validation: For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon.

More options May 9 2012, 7:57 am
Newsgroups: comp.lang.forth
From: Andrew Haley <andre...@littlepinkcloud.invalid>
Date: Wed, 09 May 2012 06:57:47 -0500
Local: Wed, May 9 2012 7:57 am
Subject: Re: Incremental Averaging

Arnold Doray <inva...@invalid.com> wrote:
> Dear Forthers,

> I need to do incremental averaging. I came up with this:

> : (average) ( n An Xn+1 -- n+1 An+1 )
>        swap dup >R
>        - >R
>        1 + dup
>        R> swap /
>        R> + ;

> : average ( seq -- d )
>          0 0 ['] (average) 2 reduce swap drop ;

> REDUCE is a higher order function that takes a stream/"seq", a set of
> accumulators, an XT that updates the accumulators and the arity of the
> XT. It reads the stream to its end.

> Note that in this Forth / also handles floating point division.

> My problem is that (AVERAGE) looks really ugly. Any suggestions for
> improvement?

It needs a bit of factoring, and I think you're doing too much on the
stack.  It's easy if you make the accumulator a structure in memory
with count and average, like so:

0
field: .count
field: .ave
constant /accum

and then:

\ Increment a counter, return its value
: +counter ( a - n)   dup @  1+ tuck ! ;

\ Incremental average
: (average) ( x accum)
dup >r .ave @ -
r@ .count +counter /
r> .ave +! ;

This will also mean less stack thrashing in the word that calls
(AVERAGE) .

Andrew.