0
votes

I'm trying to vectorize one function in Matlab, but I have a problem with assigning values.

function [val] = clenshaw(coeffs,x)


b=zeros(1,length(coeffs)+2);

for k=length(coeffs):-1:2
   b(k)=coeffs(k)-b(k+2)+2*b(k+1).*x;
end

val=coeffs(1)-b(3)+b(2).*x;

The purpose of this function is to use Clenshaw's algorithm to compute a value of one polynomial with coefficients "coeffs" at point x. It work fine when x is a single value, but I'd like it to work with vector of arguments too. When I try to pass a vector I get an error:

Unable to perform assignment because the left
and right sides have a different number of
elements.

Error in clenshaw (line 7)
   b(k)=coeffs(k)-b(k+2)+2*b(k+1).*x;

I understand that there is a problem, because I'm trying to assign vector to a scalar variable b(k). I tried making b a matrix instead of a vector, however I still cannot get the return output I'd like to have which would be a vector of values of this function at points from vector x.

Thank you for helping and sorry if something isn't entirely clear, because English is not my native language.

1
If you use the .* operator with x being a vector your result is a vector too, as you said yourself. So you need a matrix on the left-hand side. However, you need to tell Matlab the rows and cols were the results should be written. Can't test it right now, have to reinstall matlab, but it should work like this b(k,:) = ... - wychmaster
I just added a complete answer. Unfortunately, I was too late and you already solved your problem :p. However, if it is the correct solution, you can mark it as the accepted answer. - wychmaster

1 Answers

1
votes

The vectorized version of your function looks like this:

function [val] = clenshaw(coeffs,x)

b=zeros(length(x),length(coeffs)+2);

for k=length(coeffs):-1:2
   b(:,k)=coeffs(k)-b(:,k+2)+2*b(:,k+1).*transpose(x);
end

val=coeffs(1)-b(:,3)+b(:,2).*transpose(x);

end

b needs to be a matrix. In your loop, you have to perform every operation per row of b. So you need to write b(:,k) instead of b(k). Since b(:,k) is a vector and not a scalar, you also have to be careful with the dimensions when using the .* operator. To get the correct results, you need to transpose x. The same goes for the calculation of val. If you don't like the transposition, just swap the rows and cols of b and you get this:

function [val] = clenshaw(coeffs,x)


b=zeros(length(coeffs)+2, length(x));

for k=length(coeffs):-1:2
   b(k,:)=coeffs(k)-b(k+2,:)+2*b(k+1,:).*x;
end

val=coeffs(1)-b(3,:)+b(2,:).*x;

end

However, the first version returns a column vector and the second a row vector. So you might need to transpose the result if the vector type is important.