help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: vectorized moving average?


From: James Sherman Jr.
Subject: Re: vectorized moving average?
Date: Tue, 11 May 2010 17:06:10 -0400

Well, if you want to use the formula found in Wikipedia exponential moving average, its not as you explain it, because an exponential moving average is fundamentally different than n-day weighted average because it has an infinite "memory" or from my EE background, it has an infinite impulse response.  (I don't know what your background is).

But don't fear!  The filter command can handle this as well (quite easily in fact).  You just need to use the equation found in in the wikipedia article that shows (let s_t be the sum at time t, and x_t be the value at time t), then

s_t = s_(t-1) + alpha*(x_t - s_(t-1))
or rearranged, it looks like
s_t = alpha*x_t - (alpha - 1)*s_(t-1)

so comparing those values to what filter expects, we get:
b = alpha;
a = [1, alpha-1];
s = filter(b, a, x);

I'm not 100% I haven't made a mistake here, but this is the general gist of things.

Hope this helps.

On Tue, May 11, 2010 at 4:28 PM, Tim Rueth <address@hidden> wrote:
> Yep, worked great, thanks!
>
> Now, I just have to figure out how to do an exponential MA using filter().
> (I think movavg() has a bug in it for the exponential case, where alpha =
> 'e'.)
>
> --Tim
>
>
>> -----Original Message-----
>> From: address@hidden [mailto:address@hidden] On
>> Behalf Of James Sherman Jr.
>> Sent: Tuesday, May 11, 2010 11:01 AM
>> To: address@hidden
>> Cc: Octave-ML
>> Subject: Re: vectorized moving average?
>>
>> I can't double-check right now, but I think it is that filter
>> is setup so that it does (in this simplified case), let b be
>> the coefficients and has length m,
>>
>> y(n) = b(1)*x(n) + b(2)*x(n-1) ... + b(m)*x(n-m+1)
>>
>> So, the first value of your coefficient vector (sweep as you
>> call it) should be the value you want to weigh the "current"
>> value of x (what you call a).  Thus, long story short, I
>> believe that your sweep value should be:
>>
>> sweep = (ma_days:-1:1).^alpha;
>> norm_sweep = sweep/sum(sweep);
>>
>> Just reversed of what you put in.  Also, as a side note, the
>> reason why there wasn't much difference between movavg and
>> filter for what you put in, is because you just gave it
>> uniform noise, so any average function is really just
>> approximating the average of the noise.
>>
>> On Tue, May 11, 2010 at 1:41 PM, Tim Rueth <address@hidden> wrote:
>> >
>> > Thanks for showing how to use filter() to do a simple
>> moving average.  I implemented your code, and it agrees with
>> movavg(x,10,10,0), which calculates a 10-day simple moving
>> average.  There's only a difference in the first 9 numbers
>> due to assumed values of negative time (movavg calculates a
>> "run-in" period).  As you might recall, I'm trying to use
>> filter() to avoid movavg()'s for-loop.
>> >
>> > Now, what I'm trying to do is a weighted moving average,
>> identical to the "alpha" parameter of movavg().  When
>> alpha=0, it's a simple moving average, and agrees with
>> filter().  If I change alpha to 1, I'm suppose to get a
>> linear MA.  Here's the code in movavg.m that does the
>> weighting (lead is the number of days to average, equal to 10
>> in the above case):
>> >
>> >   lead = (1:lead).^alpha;
>> >   ## Adjust the weights to equal 1
>> >   lead = lead / sum (lead);
>> >
>> >  So, for a 10-day linearly-weighted moving average (lead =
>> 10, alpha = 1), the previous 9 days and current day should be
>> weighted as follows: 1/55, 2/55, 3/55...10/55, with the 
>> greatest weight (10/55) applied to the current day.  So, I
>> tried a simple test case with just a 2-day MA on a 6-element vector:
>> >
>> > ma_days = 2;
>> > alpha = 1;
>> > len = 6;
>> > a = rand(1,len);
>> >
>> > # Calculate MA using movavg()
>> > ma = movavg(a,ma_days,ma_days,alpha);
>> >
>> > # Calculate MA using filter()
>> > sweep = (1:ma_days).^alpha;
>> > norm_sweep = sweep/sum(sweep);
>> > f = filter(norm_sweep,1,a);
>> >
>> > disp(ma);
>> > disp(f);
>> >
>> > The movavg() and filter() results are similar, but not
>> equal.  I'm guessing I don't have the arguments for filter()
>> correct, but I can't figure out what I did wrong. 
>> Particularly, I'm not sure what the second argument of
>> filter() is supposed to do.  Help?
>> >
>> > ________________________________
>> > From: address@hidden [mailto:address@hidden] On
>> Behalf Of James Sherman Jr.
>> > Sent: Friday, May 07, 2010 12:58 PM
>> > To: address@hidden
>> > Cc: Octave-ML
>> > Subject: Re: vectorized moving average?
>> >
>> > I'm not sure what you mean by weighting of 0.5, but to do a simple
>> > 10-day average, it'd be x = rand(1, 100); y =
>> filter(1/10*ones(1, 10),
>> > 1, x) This assumes that the values at negative time (x(0),
>> x(-1), etc)
>> > are all zero.  So, for example, the first value of y would
>> be x(1)/10.
>> > On Fri, May 7, 2010 at 3:33 PM, Tim Rueth
>> <address@hidden> wrote:
>> >>
>> >> I looked at both conv() and filter(), but can't figure out
>> how to do
>> >> a moving average with them.  Perhaps I'm not understanding the
>> >> functions of the input vars correctly.
>> >>
>> >> Let's say I have an array, a = rand(1,100).  Can you tell
>> me how I'd
>> >> use
>> >> conv() and filter() to take, say the 10-day moving average of it,
>> >> with a weighting of 0.5?
>> >>
>> >> Thanks!
>> >>
>> >>
>> >> > -----Original Message-----
>> >> > From: Andy Buckle [mailto:address@hidden]
>> >> > Sent: Thursday, May 06, 2010 12:06 AM
>> >> > To: address@hidden
>> >> > Cc: address@hidden
>> >> > Subject: Re: vectorized moving average?
>> >> >
>> >> > conv is also an m file, but it only has a few ifs in.
>> then it calls
>> >> > filter to get the job done. which is an oct file.
>> >> >
>> >> > Andy
>> >> >
>> >> > On Thu, May 6, 2010 at 6:28 AM, Tim Rueth
>> <address@hidden> wrote:
>> >> > > Does anyone know how to take an n-day weighted moving
>> average of
>> >> > > a vector without using a for-loop?  I looked at the M code
>> >> > for movavg()
>> >> > > and it uses a for-loop, so I'm guessing there probably isn't a
>> >> > > way, but I thought I'd check.  Thanks.
>> >> > >
>> >> > > --Tim
>> >> > > _______________________________________________
>> >> > > Help-octave mailing list
>> >> > > address@hidden
>> >> > > https://www-old.cae.wisc.edu/mailman/listinfo/help-octave
>> >> > >
>> >> > >
>> >> >
>> >> >
>> >> >
>> >> > --
>> >> > /* andy buckle */
>> >> >
>> >>
>> >>
>> >> _______________________________________________
>> >> Help-octave mailing list
>> >> address@hidden
>> >> https://www-old.cae.wisc.edu/mailman/listinfo/help-octave
>> >
>>
>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]