MATLAB Answers

Recursive vector operation without for loops

58 views (last 30 days)
Sometimes one want to create a vector from some recursive expression, for example when we have fibonacci:
x(0)=0, x(1)=1, x(i)=x(i-1)+x(i-2)
Is there a function in matlab which creates arrays recursively, for example:
fib = recursivevector(start=[0,1], expr=@(i,x) x(1)+x(2), len=20)
Or, a bit more complicated, we already have some vector and want to change it recursively, as is done in a exponential smoothing filter:
x2(1) = x(1), x2(i) = a*x(i) + (1-a)*x2(i-1)
Which we could then execute as:
denoised = recursivevector(start=[noised(1)], expr=@(i,x) a*x(1)+(1-a)*noised(2), len=length(noised))
In for-loops this would go like this:
function y = exponentialdenoise(x,a)
y=zeros(size(x));
y(1)=x(1);
for i=2:length(x)
y(i)=a*x(i)+(1-a)*y(i-1);
end
end
I strongly dislike the for-loops ;) of course and prefer a version without them.

  0 Comments

Sign in to comment.

Accepted Answer

Azzi Abdelmalek
Azzi Abdelmalek on 11 Jul 2013
Edited: Azzi Abdelmalek on 11 Jul 2013
Your equation can be written as:
%x(i)-x(i-1)-x(i-2)=u(i) with u(i)=0
D=[1 -1 -1];
N=1
y=filter(N,D,zeros(1,10),[0 1])

  4 Comments

Show 1 older comment
Azzi Abdelmalek
Azzi Abdelmalek on 11 Jul 2013
%-y(i)+(1-a)*y(i-1) = -a*x(i)+0*x(i-1)
N=[-a 0]
D=[-1 1-a]
y0=[1] %initial conditions
y=filter(N,D,x,y0)
Herbert
Herbert on 11 Jul 2013
I resolved it as:
exponentialdenoise = @(x, a) filter([a 0], [1, -(1-a)], x, 0)
Which is equivalent to what you say (with a factor -1), only my initial condition (which I determined empirically) needs to be 0 to set y(1)=x(1).
Jan
Jan on 11 Jul 2013
And if run-time matters, you can try: FEX: FilterM.

Sign in to comment.

More Answers (1)

Jan
Jan on 11 Jul 2013
Why do you dislike loops? They solve problems efficiently. And yes, sometimes there are even faster methods.
function y = exponentialdenoise(x,a)
y = zeros(size(x));
y(1) = x(1);
n = length(x);
y(2:n) = a * x(2:n) - (1-a) * x(1:n-1);
end

  1 Comment

Herbert
Herbert on 11 Jul 2013
I made a mistake in my maltab code, sorry, this is not what I am looking for. I want y(i-1) at the right side of the =.

Sign in to comment.

Sign in to answer this question.