【问题标题】:Using vectorization to reduce for loops, how to use conditional if?使用向量化减少for循环,如何使用条件if?
【发布时间】:2019-05-26 20:56:34
【问题描述】:

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

【问题讨论】:

    标签: arrays matlab vector


    【解决方案1】:

    目前n 是一个向量,k 是一个标量,n&lt;k 返回一个逻辑向量。如果你直接使用if,它会和if all(n)一样,只有当向量中的所有内容都为真时才会返回真!这是出乎意料的行为。

    我不知道是否有一种通用的方法可以使用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))
    

    我建议你阅读所有三个方法并理解这个想法,这样你下次可以自己做。

    【讨论】:

      猜你喜欢
      • 2021-11-13
      • 2018-08-28
      • 1970-01-01
      • 2016-10-17
      • 1970-01-01
      • 1970-01-01
      • 2015-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多