Performance 如何使用3个for循环提高matlab操作的性能?

Performance 如何使用3个for循环提高matlab操作的性能?,performance,matlab,for-loop,vectorization,Performance,Matlab,For Loop,Vectorization,我正在尝试提高以下代码计算的速度: for i=1:5440 for j=1:46 for k= 1:2 pol(i,j,k)= kr0*exp(0.8*k*0.1)*(abs((I(i)*exp(-0.1*j*2.5))^0.9)+0.0); end end end 其中,I是一个具有5440个值的向量 有没有办法避免三个for循环并提高此操作的速度?。我找不到正确的解决办法 感谢使用bsxfun进行矢量化 f1 = @(a,b) (abs((a.*exp(-0.1*

我正在尝试提高以下代码计算的速度:

for i=1:5440
 for j=1:46
  for k= 1:2
    pol(i,j,k)= kr0*exp(0.8*k*0.1)*(abs((I(i)*exp(-0.1*j*2.5))^0.9)+0.0);
   end
  end
end
其中,
I
是一个具有5440个值的向量

有没有办法避免三个for循环并提高此操作的速度?。我找不到正确的解决办法


感谢使用
bsxfun
进行矢量化

f1 = @(a,b) (abs((a.*exp(-0.1*b*2.5)).^0.9)+0.0);
f2 = @(c,d) kr0*exp(0.8*c*0.1).*d;
pol = bsxfun(f2, permute(1:2, [3 1 2]), bsxfun(f1, I(:), 1:46));
请注意,由于数组
1:2
位于三维,我们需要
permute
将大小为
1x2
的矩阵转换为大小为
1x1x2
的矩阵

这里有一个比较基准

kr0=1;
I=rand(5440,1);
[pol0, pol] = deal(zeros(5440, 46, 2));

tic
for mm = 1:10,
for i=1:5440
 for j=1:46
  for k= 1:2
    pol0(i,j,k)= kr0*exp(0.8*k*0.1)*(abs((I(i)*exp(-0.1*j*2.5))^0.9)+0.0);
   end
  end
end
end
toc

tic
for mm=1:10
f1 = @(a,b) (abs((a.*exp(-0.1*b*2.5)).^0.9)+0.0);
f2 = @(c,d) kr0*exp(0.8*c*0.1).*d;
pol = bsxfun(f2, permute(1:2, [3 1 2]), bsxfun(f1, I(:), 1:46));
end
toc

isequal(pol0,pol)
返回

Elapsed time is 1.665443 seconds.
Elapsed time is 0.306089 seconds.

ans =

     1

速度快5倍以上,结果相同。

使用
bsxfun
进行矢量化

f1 = @(a,b) (abs((a.*exp(-0.1*b*2.5)).^0.9)+0.0);
f2 = @(c,d) kr0*exp(0.8*c*0.1).*d;
pol = bsxfun(f2, permute(1:2, [3 1 2]), bsxfun(f1, I(:), 1:46));
请注意,由于数组
1:2
位于三维,我们需要
permute
将大小为
1x2
的矩阵转换为大小为
1x1x2
的矩阵

这里有一个比较基准

kr0=1;
I=rand(5440,1);
[pol0, pol] = deal(zeros(5440, 46, 2));

tic
for mm = 1:10,
for i=1:5440
 for j=1:46
  for k= 1:2
    pol0(i,j,k)= kr0*exp(0.8*k*0.1)*(abs((I(i)*exp(-0.1*j*2.5))^0.9)+0.0);
   end
  end
end
end
toc

tic
for mm=1:10
f1 = @(a,b) (abs((a.*exp(-0.1*b*2.5)).^0.9)+0.0);
f2 = @(c,d) kr0*exp(0.8*c*0.1).*d;
pol = bsxfun(f2, permute(1:2, [3 1 2]), bsxfun(f1, I(:), 1:46));
end
toc

isequal(pol0,pol)
返回

Elapsed time is 1.665443 seconds.
Elapsed time is 0.306089 seconds.

ans =

     1
速度快5倍以上,结果相同。

怎么样:

[i,j,k] = ndgrid(1:5440,1:46,1:2);
pol = kr0*exp(0.8*k*0.1) .* ( abs((I(i).*exp(-0.1*j*2.5)).^0.9) + 0.0);
那么:

[i,j,k] = ndgrid(1:5440,1:46,1:2);
pol = kr0*exp(0.8*k*0.1) .* ( abs((I(i).*exp(-0.1*j*2.5)).^0.9) + 0.0);

MATLAB是以列为主的,所以如果你想保持循环,你应该能够通过以k,j,i顺序而不是i,j,k循环你的变量来获得一些速度

MATLAB是以列为主的,因此如果您想保持循环,您应该能够通过将变量按k,j,i顺序而不是i,j,k顺序循环来提高速度

如果您还没有这样做,初始化3D阵列
pol
将有所帮助<代码>pol=零(5440,46,2)如果尚未执行此操作,则初始化3D阵列
pol
将有所帮助<代码>pol=零(5440,46,2)比原始方法可读性强,速度快,但比
bsxfun
慢。确实,您的方法比我的机器上的上述方法快3倍左右。我得到:
0.1181、0.0151、0.0382
秒(对应于三重循环、bsxfun、ndgrid方法):这是可以理解的,因为您的方法需要填充三个大矩阵
I
j
k
,并在进行计算时对它们的所有元素进行索引。但是,由于
bsxfun
需要分离维度,因此它仍然不太容易出错。我已经尝试了两种解决方案,我将使用这一种。我发现这对我来说比较容易,而且计算速度的提高也足够了。这些天,我将更改所有程序,并发布更改前后的总计算时间报告(超过30分钟)。我几乎更改了所有循环,新的计算时间约为200秒。我将尝试更改所有其他循环以进一步缩短时间。比原始方法可读性更强、速度更快,但比
bsxfun
慢。确实,您的方法比我机器上的上述方法快约3倍。我得到:
0.1181、0.0151、0.0382
秒(对应于三重循环、bsxfun、ndgrid方法):这是可以理解的,因为您的方法需要填充三个大矩阵
I
j
k
,并在进行计算时对它们的所有元素进行索引。但是,由于
bsxfun
需要分离维度,因此它仍然不太容易出错。我已经尝试了两种解决方案,我将使用这一种。我发现这对我来说比较容易,而且计算速度的提高也足够了。这些天,我将更改所有程序,并发布更改前后的总计算时间报告(超过30分钟)。我几乎更改了所有循环,新的计算时间约为200秒。我将尝试更改所有其他循环以进一步缩短时间。