DSPRelated.com
Forums

long rolling average

Started by BobGardner November 10, 2003
How do I get a long rolling average? Keep a long record of samples and a
running total (subtract off the old sample, add in the new)? Is there something
equivalent that doesnt need so much sample storage? Like the average of a bunch
of shorter averages? Thanks...
BobGardner wrote:
> How do I get a long rolling average? Keep a long record of samples and a > running total (subtract off the old sample, add in the new)? Is there something > equivalent that doesnt need so much sample storage? Like the average of a bunch > of shorter averages? Thanks...
average = 0; count = 0; for each new input sample average = ( average * count + newsample) / ( count + 1) count = count + 1; end
"kyle" <kyle_miller24@hotmail.com> wrote in message
news:grXrb.17853$In3.12809@lakeread01...
> BobGardner wrote: > > How do I get a long rolling average? Keep a long record of samples and a > > running total (subtract off the old sample, add in the new)? Is there
something
> > equivalent that doesnt need so much sample storage? Like the average of
a bunch
> > of shorter averages? Thanks... > average = 0; > count = 0; > > for each new input sample > average = ( average * count + newsample) / ( count + 1) > count = count + 1; > end
I think that the poster is looking for some finite filter, ie it doesn't retain information collected from anything outside a particular filter window. The previous reply has infinite impulse reponse, if the data starts at 0 and then jumps to 1 and stays at 1 from that point onwards the filter output will never actually completely reach 1 (apart from due to quantisation). A much simpler way of performing a similar filter would have been average = weighting1*average + weighting2*new_sample / (weighting1+weighting2) which in the simplest case gives average = (average + new_sample) / 2 I can't see anyway of having a finite response without keeping around all the windowed data items. There is perhaps some more efficient way to do such a filter that I don't know about (which is extrememely likely) so perhaps looking into finite impulse response filters, FIR filters, (for such a method) would be a good idea.
"BobGardner" <bobgardner@aol.com> wrote in message
news:20031110204155.28980.00000440@mb-m23.aol.com...
> How do I get a long rolling average? Keep a long record of samples and a > running total (subtract off the old sample, add in the new)? Is there
something
> equivalent that doesnt need so much sample storage?
No. Imagine you are calculating a 5-second moving average of a signal that drops to zero at time t and stays there. The 5 seconds of signal occurring before time t can then be completely reconstructed from the output of the averager by a simple differencing operation. The averager, therefore, must store those 5 seconds of singal, or equivalent information, in its internal state. If you don't necessarily need that kind of averager, though, then you can use a low-pass filter instead, which will require a good deal more processing, but will let you decimate the signal to reduce storage requirements.
On Mon, 10 Nov 2003 21:02:52 -0500, kyle wrote:
> BobGardner wrote: >> How do I get a long rolling average? Keep a long record of samples and a >> running total (subtract off the old sample, add in the new)? Is there something >> equivalent that doesnt need so much sample storage? Like the average of a bunch >> of shorter averages? Thanks... > average = 0; > count = 0; > > for each new input sample > average = ( average * count + newsample) / ( count + 1) > count = count + 1; > end
The trouble with that sort of approach is that you run into numerical precision issues as count * average approaches your word size. Eventually, average * count + newsample = average * count, for floating point systems, or average * count overflows, for fixed point systems, or the re-arrangement to avoid that overflow (average = average * (count/(count + 1)) + newsample/(count + 1)) results in the second term going to zero, which is the same thing that happens in floating point. The running-average approach can be finessed by using double (or multi-) precision for the "average" accumulator and the associated arithmetic. There should be a fair bit of literature on the net (and certainly in books) about the tribulations of building "IIR filters with low-frequency poles". Worth a read. -- Andrew
A simple single pole recursive filter works nicely.  You can adjust the
effective number in the average by adjusting the time constant:

tau = .01;                            /* time constant in seconds */
inv_tau_fs = 1.0/(tau*fs);     /* filter coef */

At each sample do:
{
     theAvg = theAvg + inv_tau_fs*(new_input - theAvg);
}
-Shawn

www.appliedsignalprocessing.com


"BobGardner" <bobgardner@aol.com> wrote in message
news:20031110204155.28980.00000440@mb-m23.aol.com...
> How do I get a long rolling average? Keep a long record of samples and a > running total (subtract off the old sample, add in the new)? Is there
something
> equivalent that doesnt need so much sample storage? Like the average of a
bunch
> of shorter averages? Thanks...
"Shawn Steenhagen" <shawn.steenhagen@NOSPAMappliedsignalprocessing.com>
wrote in message news:bor28i$2kk$1@grandcanyon.binc.net...
> A simple single pole recursive filter works nicely. You can adjust the > effective number in the average by adjusting the time constant: > > tau = .01; /* time constant in seconds */ > inv_tau_fs = 1.0/(tau*fs); /* filter coef */ > > At each sample do: > { > theAvg = theAvg + inv_tau_fs*(new_input - theAvg); > }
I think that is usually called decaying average, everywhere except in the DSP world. That would be my choice to answer the OP question. -- glen
Glen Herrmannsfeldt wrote:

> "Shawn Steenhagen" <shawn.steenhagen@NOSPAMappliedsignalprocessing.com> > wrote in message news:bor28i$2kk$1@grandcanyon.binc.net... > >>A simple single pole recursive filter works nicely. You can adjust the >>effective number in the average by adjusting the time constant: >> >>tau = .01; /* time constant in seconds */ >>inv_tau_fs = 1.0/(tau*fs); /* filter coef */ >> >>At each sample do: >>{ >> theAvg = theAvg + inv_tau_fs*(new_input - theAvg); >>} > > > I think that is usually called decaying average, everywhere except in the > DSP world. > > That would be my choice to answer the OP question. > > -- glen
It may be the answer to his problem, but it's not the answer to the question he asked. In analog circuits, we call it a leaky integrator. Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;
On Tue, 11 Nov 2003 14:47:47 -0500, Jerry Avins <jya@ieee.org> wrote:

>Glen Herrmannsfeldt wrote: > >> "Shawn Steenhagen" <shawn.steenhagen@NOSPAMappliedsignalprocessing.com> >> wrote in message news:bor28i$2kk$1@grandcanyon.binc.net... >> >>>A simple single pole recursive filter works nicely. You can adjust the >>>effective number in the average by adjusting the time constant: >>> >>>tau = .01; /* time constant in seconds */ >>>inv_tau_fs = 1.0/(tau*fs); /* filter coef */ >>> >>>At each sample do: >>>{ >>> theAvg = theAvg + inv_tau_fs*(new_input - theAvg); >>>} >> >> >> I think that is usually called decaying average, everywhere except in the >> DSP world. >> >> That would be my choice to answer the OP question. >> >> -- glen > >It may be the answer to his problem, but it's not the answer to the >question he asked. In analog circuits, we call it a leaky integrator. > >Jerry
Humm, ... there's something "cockeyed" about Shawn's equation. It's of the form: theAvg = theAvg + x. That can't be right (unless x is zero). I don't know if Shawn's talking about a leaky integrator (what I like to call an "exponential averager") or is he describing a "recursive running sum". See Ya', [-Rick-]
"Rick Lyons" <ricklyon@REMOVE.onemain.com> wrote in message
news:3fb3f587.44782968@news.west.earthlink.net...
> On Tue, 11 Nov 2003 14:47:47 -0500, Jerry Avins <jya@ieee.org> wrote: > > >Glen Herrmannsfeldt wrote: > > > >> "Shawn Steenhagen" <shawn.steenhagen@NOSPAMappliedsignalprocessing.com> > >> wrote in message news:bor28i$2kk$1@grandcanyon.binc.net... > >> > >>>A simple single pole recursive filter works nicely. You can adjust the > >>>effective number in the average by adjusting the time constant: > >>> > >>>tau = .01; /* time constant in seconds */ > >>>inv_tau_fs = 1.0/(tau*fs); /* filter coef */ > >>> > >>>At each sample do: > >>>{ > >>> theAvg = theAvg + inv_tau_fs*(new_input - theAvg); > >>>} > >> > >> > >> I think that is usually called decaying average, everywhere except in
the
> >> DSP world. > >> > >> That would be my choice to answer the OP question. > >> > >> -- glen > > > >It may be the answer to his problem, but it's not the answer to the > >question he asked. In analog circuits, we call it a leaky integrator. > > > >Jerry > > Humm, ... there's something "cockeyed" about > Shawn's equation. > > It's of the form: > > theAvg = theAvg + x. > > That can't be right (unless x is zero).
I think he means something like: theAvg = theAvgPrevious + x or in terms of the original equation: theAvg = theAvgPrevious + inv_tau_fs*(new_input - theAvgPrevious); In C, the "Previous" is implied.