Matlab的FOR循环迭代时间增加

sha*_*red 2 matlab loops for-loop

我试图跨越某个多变量函数f(nu,delta,Omega,kappa,Gamma)的值.代码如下:

% PREALLOCATE RESULT MATRIX

N = 10;
d = 0.1;

M = zeros(4*N/d+(2*N+1)/d,6);

% SET UP LOOP INDICES

i=1;
increm=1;

% LOOP OVER MULTIPLE VARIABLE

for nu=d:d:N
    for delta=-N:d:N
        for Omega=d:d:N
            for kappa=d:d:N
                tic
                for Gamma=d:d:N

                % CALCULATE THE FUNCTION 

                mss = ((Gamma+kappa).*((Gamma+kappa).^2+4.*(delta+(-1).*nu).^2).^(-1)+( ...
                  -1).*(Gamma+kappa).*((Gamma+kappa).^2+4.*(delta+nu).^2).^(-1)+( ...
                  kappa.^2+4.*(delta+(-1).*nu).^2).^(-1).*(((2.*Gamma+kappa).^2+4.*( ...
                  delta+(-1).*nu).^2).*(kappa.*(Gamma+kappa).*(2.*Gamma+kappa)+4.*(( ...
                  -1).*Gamma+kappa).*(delta+(-1).*nu).^2)+4.*(kappa.*(2.*Gamma+ ...
                  kappa).^2+4.*(4.*Gamma+kappa).*(delta+(-1).*nu).^2).*Omega.^2).*( ...
                  16.*(delta+(-1).*nu).^4+4.*(delta+(-1).*nu).^2.*((Gamma+kappa).^2+ ...
                  (2.*Gamma+kappa).^2+(-8).*Omega.^2)+((Gamma+kappa).*(2.*Gamma+ ...
                  kappa)+4.*Omega.^2).^2).^(-1)+(-1).*(kappa.^2+4.*(delta+nu).^2).^( ...
                  -1).*(((2.*Gamma+kappa).^2+4.*(delta+nu).^2).*(kappa.*(Gamma+ ...
                  kappa).*(2.*Gamma+kappa)+4.*((-1).*Gamma+kappa).*(delta+nu).^2)+ ...
                  4.*(kappa.*(2.*Gamma+kappa).^2+4.*(4.*Gamma+kappa).*(delta+nu).^2) ...
                  .*Omega.^2).*(16.*(delta+nu).^4+4.*(delta+nu).^2.*((Gamma+kappa) ...
                  .^2+(2.*Gamma+kappa).^2+(-8).*Omega.^2)+((Gamma+kappa).*(2.*Gamma+ ...
                  kappa)+4.*Omega.^2).^2).^(-1)).^(-1).*((Gamma+kappa).*((Gamma+ ...
                  kappa).^2+4.*(delta+nu).^2).^(-1)+(kappa.^2+4.*(delta+nu).^2).^( ...
                  -1).*(((2.*Gamma+kappa).^2+4.*(delta+nu).^2).*(kappa.*(Gamma+ ...
                  kappa).*(2.*Gamma+kappa)+4.*((-1).*Gamma+kappa).*(delta+nu).^2)+ ...
                  4.*(kappa.*(2.*Gamma+kappa).^2+4.*(4.*Gamma+kappa).*(delta+nu).^2) ...
                  .*Omega.^2).*(16.*(delta+nu).^4+4.*(delta+nu).^2.*((Gamma+kappa) ...
                  .^2+(2.*Gamma+kappa).^2+(-8).*Omega.^2)+((Gamma+kappa).*(2.*Gamma+ ...
                  kappa)+4.*Omega.^2).^2).^(-1));

                % STORE THE RESULT

                M(i,:) = [mss nu delta Omega kappa Gamma];

                i = i+increm;

                end
            end
            toc
        end
    end
end

save M
Run Code Online (Sandbox Code Playgroud)

但是,预分配并不能帮助每次迭代花费更长的时间.当我运行代码并过早地中断它时,迭代需要

Elapsed time is 0.003354 seconds.
Elapsed time is 0.006374 seconds.
Elapsed time is 0.009043 seconds.
Elapsed time is 0.012092 seconds.
Elapsed time is 0.015287 seconds.
Elapsed time is 0.019239 seconds.
Elapsed time is 0.023898 seconds.
Elapsed time is 0.035345 seconds.
Elapsed time is 0.046675 seconds.
Elapsed time is 0.056000 seconds.
Elapsed time is 0.066323 seconds.
Elapsed time is 0.072178 seconds.
Elapsed time is 0.075174 seconds.
Elapsed time is 0.081095 seconds.
Elapsed time is 0.095016 seconds.
Elapsed time is 0.095214 seconds.
Elapsed time is 0.100089 seconds.
Elapsed time is 0.104286 seconds.
Elapsed time is 0.109454 seconds.
Elapsed time is 0.115368 seconds.
Elapsed time is 0.124278 seconds.
Elapsed time is 0.131521 seconds.
Elapsed time is 0.135023 seconds.
Elapsed time is 0.137370 seconds.
Elapsed time is 0.145331 seconds.
Elapsed time is 0.163449 seconds.
Elapsed time is 0.162654 seconds.
Elapsed time is 0.159628 seconds.
Elapsed time is 0.166585 seconds.
Run Code Online (Sandbox Code Playgroud)

我没有看到变量本身的变化是如何导致这种情况的,因为它只会随着数量d的变化而变化,这不应该使得计算mss的新值比在之前的交互中更难.

Jon*_*nas 8

你没有预先分配一个足够大的阵列!

如果您执行以下嵌套循环

for ii=1:3
   for jj = 1:4
       doSomething()
   end
end
Run Code Online (Sandbox Code Playgroud)

doSomething执行3*4 = 12次.使用您的分配方案,您将分配3 + 4 = 7次.

换句话说,将预分配更改为

M = zeros((N/d)^4*(2*N+1)/d,6);
Run Code Online (Sandbox Code Playgroud)

一切都会好的.

  • 只是想添加Jonas的答案:迭代开始花费更多时间的原因是你的输出数组不足以保存结果.因此,当您开始添加更多结果时,在每次迭代中,MATLAB会分配一个更大的新数组来保存结果,并释放前一个结果.数组大小随着每次迭代而增长,因此分配新数组需要更长和更长时间.如果你在开始时预先分配整个事情,你只需要分配一次. (3认同)