【问题标题】:Matlab matrix operations without loops没有循环的Matlab矩阵运算
【发布时间】:2013-01-11 23:23:11
【问题描述】:

我对执行某些数组操作的代码有疑问。它变得太慢了,因为我正在使用循环。我正在尝试一段时间来优化这段代码,并用更少或没有循环来重写它。直到现在都没有成功。你能帮我解决这个问题吗:

YVal = 1:1:100000;
M_MAX = 1000;
N_MAX = 2000;
clear YTemp
tic
for M=1:1:M_MAX 
    for N = 1:1:N_MAX 
       YTemp(M,N) = sum(YVal (N+1:N+M)  ) - sum(YVal   (1:M)  );  
    end
end

对于大的N_MAXM_MAX,这两个循环的执行时间非常长。我该如何优化它?

谢谢!

【问题讨论】:

  • 最耗时的部分是在循环内增长YTemp。将clear YTemp 替换为YTemp = zeros(M_MAX,N_MAX),您会看到已经非常不错的速度提升了。
  • @Jonas - 说得好!您能否详细说明一下 Matlab 中预分配的重要性,并将其作为另一个答案发布在这里 - 我会为此 +1 !

标签: matlab loops optimization for-loop matrix


【解决方案1】:

假设YVal大于N_MAX+M_MAX

sum1 = cumsum( YVal(1:(M_MAX+N_MAX)) ); % sum1(M) = sum(YVal(1:M))

如果我没记错的话

sum( YVal( N+1:N+M ) ) = sum1( N + M ) - sum1( N )

因此

YTemp( M, N ) = sum1( N + M ) - sum1( N ) - sum1( M )

使用ndgrid

[M N] = ndgrid( 1:M_MAX, 1:N_MAX );
YTemp = sum1( N + M ) - sum1( N ) - sum1( M );

我说对了吗?

编辑:
另一个没有ndgrid

sum1 = cumsum( YVal( 1 : (N_MAX+M_MAX) ) );
YTemp = bsxfun( @minus, ...
            bsxfun( @minus, ...
                sum1( bsxfun( @plus, 1:N_MAX, (1:M_MAX)' ) ) , sum1 ),...
                    sum1' );

【讨论】:

    【解决方案2】:

    您应该能够通过将不变项从内部循环中提升一点来加快速度,例如

    for M=1:1:M_MAX 
        sum2 = sum(YVal(1:M));
        for N = 1:1:N_MAX 
           YTemp(M,N) = sum(YVal(N+1:N+M)) - sum2;  
        end
    end
    

    【讨论】:

    • 您好!谢谢你的回答。不过,我想知道如何在没有循环的情况下进行这些操作。我应该也可以计算向量,例如: YVal = rand (100000, 1)
    • 我没有看到任何简单的方法来矢量化这个循环,但是比我更熟悉 MATLAB 的人可能会在适当的时候提供帮助。同时,您可以使用上述提升优化来潜在地为自己节省一些执行时间,直到您获得更好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 2017-08-06
    • 2013-12-21
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    相关资源
    最近更新 更多