[Top][All Lists]

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

RE: filter() not giving me correct answers for first n-1 days

From: Tim Rueth
Subject: RE: filter() not giving me correct answers for first n-1 days
Date: Fri, 17 Sep 2010 00:34:27 -0700

I implemented your suggestions below, and, at least for my few test cases so far, it works great, and I'm now starting to understand the filter() arguments.  It doesn't match movavg() from the financial package perfectly for the first n days but I think that's because I assume the negative time values of the asset are all equal to asset(1).  The reason why I like filter() better than movavg() is because filter() is vectorized (movavg() has a for loop).  Plus, movavg() is broken for exponential cases.  Thanks James!
FWIW, here's my moving average function (with no for loops):
function [ma] = mafilter(asset, ma_alphatype, ma_days, ma_alpha)
     if ma_alphatype == "e"                               # calculate exponential moving averages (don't use movavg() here cuz it's broken)
          alpha = 2 / (ma_days+1);
          ma = filter(alpha, [1 alpha-1], asset, asset(1)*(1-alpha));
          coef_v = (ma_days:-1:1).^ma_alpha;        # determine vector coefficients
          coef_v = coef_v/sum(coef_v);                   # sum vector coefficients to equal 1
          si = repmat(asset(1), 1, ma_days-1);       # begin building initial cond by repeating first value
          si = conv(si,coef_v);                               # convolve initial cond with coefficients
          si = si(ma_days : end);                          # keep only the last part as the true initial condition
          ma = filter(coef_v, 1, asset, si);               # run the filter

From: address@hidden [mailto:address@hidden On Behalf Of James Sherman Jr.
Sent: Thursday, September 16, 2010 9:08 PM
To: address@hidden
Cc: address@hidden
Subject: Re: filter() not giving me correct answers for first n-1 days

Hi Tim,

Someone a few months ago had a similar problem with the filter function.  The problem is that the 4th argument to the filter function (the initial conditions of the filter, SI it is called) don't specify x(n) for n < 0, like you would intuitively think so.  They represent the internal states of the filter, which are less than intuitive to say the least. (And isn't documented in the help text of the filter function).

Anyway, the essence is that to make a "more" efficient filter you can implement a filter where there are these internal states.  And you need to do a precomputing step if you want to find the initial states.  These are just back of the envelope calculations, so I provide no guarantees.  I also assume that a = 1 (i.e. no feedback) which is true for a moving average filter as you have in your example.

Let, b be the vectors of coefficients in your filter be of length n and initial_x be a vector of the values from t = -n+1 to t=-1.  Then, I did

tmp_var = conv(initial_x, b);
si = tmp_var(n:end);

z = filter(b, 1, x, si);

I think should give you want you want.  I just tested this in the corner case where I set all the initial_x variables were constant (so I'd know that the moving average of them should be that constant) and it behaved as expected.  But like I said before, I'd use with caution till you try it out a bit.  I make no guarantees.

It should be possible (and probably pretty easy, but I'm just not seeing it now) to allow an a coefficient vector thats not equal to 1 and still solve for the si variable, but it just hit midnight here and I need some sleep.

I hope this helps.

On Thu, Sep 16, 2010 at 2:41 PM, Tim Rueth <address@hidden> wrote:
Octave experts:
I have been using filter() to compute a weighted moving average, ma1, of a vector, cls_v, with a weighting factor, alpha.  I just found out that the first num_days-1 of the moving average are not correct.  I'm assuming I don't have a filter coefficient quite correct or something, but I'm stuck.  I tried to understand the formula in help, but got lost.  Any takers?
Here's my current code:
    coef_v = (num_days : -1 : 1).^alpha;
    coef_v = coef_v/sum(coef_v);               # sum vector coefficients to equal 1
    si = repmat(cls_v(1), 1, num_days - 1);
    ma1 = filter(coef_v, 1, cls_v, si);

Help-octave mailing list

reply via email to

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