【问题标题】:MATLAB How to vectorize these for loops?MATLAB 如何对这些 for 循环进行矢量化?
【发布时间】:2012-12-26 17:37:16
【问题描述】:

我进行了很多搜索,但没有找到任何解决我的问题的方法,请您帮我对这些循环进行矢量化(或者只是一种使其更快的方法)?

% n is the size of C
h = 1/(n-1)
dt = 1e-6;
a = 1e-2;

F=zeros(n,n);
F2=zeros(n,n);
C2=zeros(n,n);


t = 0.0;

for iter=1:12000

    F2=F.^3-F;
    for i=1:n
        for j=1:n
             F2(i,j)=F2(i,j)-(C(ij(i-1),j)+C(ij(i+1),j)+C(i,ij(j-1))+C(i,ij(j+1))-4*C(i,j)).*(a.^2)./(h.^2);
        end
    end
    F=F2;
    for i=1:n
        for j=1:n
            C2(i,j)=C(i,j)+(F(ij(i-1),j)+F(ij(i+1),j)+F(i,ij(j-1))+F(i,ij(j+1))-4*F(i,j)).*dt./(h^2);
        end
    end
    C=C2;
    t = t + dt;


end

function i=ij(i) %Just to have a matrix as loop (the n+1 th cases are the 1 th and 0 the 0th are nth)
if i==0
    i=n;
    return 
elseif i==n+1
    i=1;
end 
return 
end

非常感谢

编辑:找到答案,这太荒谬了,我搜索得太远了

%n is still the size of C
h = 1/((n-1))
dt = 1e-6;
a = 1e-2;

F=zeros(n,n);
var1=(a^2)/(h^2); %to make a bit less calculus
var2=dt/(h^2); % the same


t = 0.0;

for iter=1:12000

    F=C.^3-C-var1*(C([n 1:n-1],1:n) + C([2:n 1], 1:n) + C(1:n, [n 1:n-1]) + C(1:n, [2:n 1]) - 4*C);
    C = C + var2*(F([n 1:n-1], 1:n) + F([2:n 1], 1:n) + F(1:n, [n 1:n-1]) + F(1:n,[2:n 1]) - 4*F);
    t = t + dt;

end

【问题讨论】:

    标签: matlab vectorization


    【解决方案1】:

    找到了答案,这太荒谬了,我搜索得太远了

    %n is still the size of C
    h = 1/((n-1))
    dt = 1e-6;
    a = 1e-2;
    
    F=zeros(n,n);
    var1=(a^2)/(h^2); %to make a bit less calculus
    var2=dt/(h^2); % the same
    
    prev = [n 1:n-1];
    next = [2:n 1];
    
    t = 0.0;
    
    for iter=1:12000
    
        F = C.*C.*C - C - var1*(C(:,next)+C(:,prev)+C(next,:)+C(prev,:)-4*C);
        C = C + var2*(F(:,next)+F(:,prev)+F(next,:)+F(prev,:)-4*F);
        t = t + dt;
    
    end
    

    【讨论】:

    • 我认为你可以通过只说: 而不是1:n 来缩短它,当你抓住整行或整列而不移动时。
    • 并给自己打上绿色复选标记(如果可以的话)。我的回答对公式中的C.^3 没有帮助。
    • 好的,已编辑谢谢,我只能在 2 天内接受我自己的答案
    • 其实我还有一个问题,我通常用一个 128*128 随机矩阵来测试它,但是当我超过 130*130 时,最终的矩阵是由 NaN 组成的,这并不重要,但做你知道为什么会这样吗?
    • 第一次迭代后它已经是 NaN 了吗?如果不是,需要多少次迭代?
    【解决方案2】:

    内循环的行为看起来像一个二维循环卷积。这与 FFT 域中的乘法相同。减法在 FFT 等线性运算中是不变的。

    您需要使用fft2ifft2 函数。

    一旦你这样做了,我想你会发现重复卷积可以通过将卷积核(按元素)提高到幂 iter 来消除。如果该优化是正确的,我预测速度会提高 5 个数量级。

    【讨论】:

    • 谢谢你的回答,但我终于找到了一个非常简单的解决方案,甚至可以让我删除我的 ij 函数,它只是在 main for 的 2 行中
    • @user1930360:我想你当时不明白我的建议。我的方法将摆脱您的 ij 函数和所有循环。
    • 我第一次尝试回答你是说我不明白你在说什么;)但后来我找到了答案,所以我改变了它。但我真的很想理解并感谢您的帮助。
    • 再看一遍,因为F2=F.^3-F; 是非线性的,你无法摆脱那个或最外层的循环。
    • 终于找到了你完全正确的地方,你的解决方案效率更高,但我仍然不明白,即使有现成的解决方案。
    【解决方案3】:

    您可以使用circshift(C,[1,0])circshift(C,[1,0]) 替换例如C(ij(i-1),j)(我无法确定两者之一是否正确)

    http://www.mathworks.com/help/matlab/ref/circshift.htm

    【讨论】:

    • 谢谢你的回答,但我终于找到了一个非常简单的解决方案,甚至可以让我删除我的 ij 函数,它只是在 main for 的 2 行中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多