我正在Matlab项目中工作,并且有一个正在运行的函数,但是我想对其进行优化,以减少代码中的for循环次数。 我读过vectorization的书,我可以使用它,但是如果必须一次测试每个值,该如何包含if条件语句?
function [y, zf] = MyFunction(x, b, zi)
y = zeros([length(x) 1]);
for n = 1:length(x)
for k=1:length(zi)
if n<k
y(n) = y(n) + b(k)*zi(length(zi)+(n-k)+1);
else
y(n) = y(n) + b(k)*x(n-k+1);
end
end
end
zf = x(length(x)-length(zi)+1:length(x));
我设法进行矢量化,但是我不知道如何进行条件转换,我得到警告:
变量“ n”可能由非标量运算符设置
function [y, zf] = MyFunction(x, b, zi)
y = zeros([length(x) 1]);
n=1:1:length(x); % use of vectorization
for k=1:length(zi)
if n<k % problem with if
y = y + b(k)*zi(length(zi)+(n-k)+1);
else
y = y + b(k)*x(n-k+1);
end
end
zf = x(length(x)-length(zi)+1:length(x));
答案 0 :(得分:3)
当前n
是一个向量,k
是一个标量,而n<k
返回一个逻辑向量。如果您直接使用if
,它将与if all(n)
相同,只有在该向量中的所有内容均为true时,它才会返回true!这是意想不到的行为。
我不知道是否存在使用if
向量化代码的一般方法。但就您而言,我可以这样做。
% use indice to deal with if
for k=1:length(zi)
y(1:k-1)=y(1:k-1)+b(k)*zi(length(zi)+2-k:end);
y(k:end)=y(k:end)+b(k)*x(1:length(x)-k+1);
end
我还注意到,实际上,如果您cat
zi
和x
,则无需使用2条单独的语句。
% assume both zi & x to be column vector
ziandx=[zi;x];
for k=1:length(zi)
y=y+b(k)*ziandx(length(zi)+2-k:length(zi)+length(x)-k+1);
end
最后,如果使用conv
,甚至不需要这个for循环。 (有关详细信息,请参阅文档)
ziandx=[zi;x];
s=conv(b(1:length(zi)),ziandx);
y=s(length(zi)+1:length(zi)+length(x))
我建议您阅读所有三种方法并理解其思想,以便下次可以自己做。