使用向量化来减少for循环,如何使用条件if?

时间:2019-05-26 20:56:35

标签: arrays matlab vector

我正在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));

1 个答案:

答案 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 zix,则无需使用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))

我建议您阅读所有三种方法并理解其思想,以便下次可以自己做。