[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));
else
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
endif;
endfunction
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);
Then,
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);
Thanks,
--Tim
_______________________________________________
Help-octave
mailing list
address@hidden
https://www-old.cae.wisc.edu/mailman/listinfo/help-octave