我有下面的代码需要计算3D矩阵的指数。它工作正常,但我不知道是否有反正使它更快。 (目前需要2秒以上,如果可能,我试图让它在半秒内运行)。在Matlab中更快的指数计算
Result = zeros(200,50,300);
for i=1:30
delta = i*randn(200,50,300);
X = exp(1i*2*pi*delta);
Result = Result + X;
end
任何帮助,将不胜感激。 在此先感谢。
我有下面的代码需要计算3D矩阵的指数。它工作正常,但我不知道是否有反正使它更快。 (目前需要2秒以上,如果可能,我试图让它在半秒内运行)。在Matlab中更快的指数计算
Result = zeros(200,50,300);
for i=1:30
delta = i*randn(200,50,300);
X = exp(1i*2*pi*delta);
Result = Result + X;
end
任何帮助,将不胜感激。 在此先感谢。
首先,我不认为这个计算顺序可以做得更快。下面可能是一个很小的有点快,但肯定不是由量你正在寻找:
dim = [200,50,300]; % given
N = prod(dim); % total number of samples
M = 30; % number of iterations in for-loop
phase = bsxfun(@times, randn(N,M), [1:M]); % scaled phases
Result = reshape(sum(exp(1i*2*pi*phase),2), dim); % sum of exp and reshape
编辑1开始:
正如@horchler在下面的评论中指出,这种方法实际上比R2016b上的原始方法慢。他还建议使用更快的随机生成方案,我尝试并观察到显着的改进。通过消除一些临时变量也可以获得类似的改进。
s = RandStream('dsfmt19937','Seed',1);
for i=1:30
Result = Result + exp(1i*2*pi*i*randn(s,200,50,300));
end
我对优化的各个阶段,在R2016b的时序结果,如下:
也可以尝试其他随机数生成方案,例如shr3cong
以努力加速进一步加速。
编辑1:结束
一种不同的方法: 让我提出一个不同的方法,会产生不同的方式所需要的输出,但是这样它会具有相同的统计特性 为你的输出。
Result = sqrt(15) * (randn(200,50,300) + 1i*randn(200,50,300));
现在我们试着证明这一点。首先,我们可以认为,由于输出是30个随机过程的和,所以通过中心极限定理(CLT),输出将是高斯分布的。 CLT只适用于这里的松散意义,因为30并不是无限的,并且过程不是完全分布的。但正如我们很快会看到的那样,它仍然是一个非常好的近似值。此外,实数和虚数项也是独立的,由于总和超过30个独立的复数。我不打算在这里证明这一点,但我们会做一些统计检查。
一旦我们确定了独立的高斯分布,分析变得更加简单。高斯分布可以由两个参数定义:均值和方差。让我们估计其个人:
平均:由于相位随机分布并覆盖比2*pi
更大的区域,对于实部和虚方面的手段是0。
方差:大随机相位分布的正弦/余弦方差为0.5。所以30个正弦/余弦之和的方差应为15.这就是公式中sqrt(15)
项的原因。
统计分析: 要验证所有上述假设和近似值是否合理,我们进行一些统计分析。
首先,让我们检查分布:
figure;
xGrid = (-15 : 0.1 : 15);
histogram(real(Result(:)), xGrid, 'Normalization','pdf', 'EdgeColor', 'None');
hold on;
plot(xGrid, normpdf(xGrid, 0, sqrt(15)), 'r', 'LineWidth', 2);
legend({'Simulated histogram', 'Gaussian pdf'});
title('Distribution of the real term');
虚数项(这里没有显示)的直方图看起来也相同。该测试验证具有零均值和15个方差的高斯分布的假设。
最后,让我们检查一下真实和虚拟术语之间的独立性。
covar = cov(real(Result(:)), imag(Result(:)));
disp(covar);
% 14.9968 0.0036
% 0.0036 14.9936
两件事情可以注意到:(1)如前所述,每个的实数和虚数项的方差为约15。(2)相比,该实数和虚数项之间的协方差是小得多个体差异。这支持了他们独立的论点。
+1有趣的答案。在R2016b中,摆脱'for'循环的第一种方法比较慢了20%左右。矢量化并不总是赢。 – horchler
也可考虑使用不同的[基数随机数生成方案](https://www.mathworks.com/help/matlab/ref/randstream.list.html),以获得更快的速度,例如''dsfmt19937''或' 'shr3cong'':'s = RandStream('dsfmt19937','Seed',1);''randn(s,200,50,300)'。 – horchler
@horchler:我已将您的建议纳入我的答案。谢谢! – aksadv
你是否介绍了该代码?在那种情况下,'exp'与其他行相比有多少时间?也许问题不在'exp'中。 – mpaskov
我怀疑这将是更快的矢量化。内存消耗本身就会很大。对于涉及大内存的计算,'for'循环更好。 – rayryeng
在你的代码中,'i'与'1i'不一样。我希望你已经知道了! –