我有以下代码需要计算 3D 矩阵的指数。它工作得很好,但我想知道是否有办法让它更快。(它目前需要超过 2 秒。如果可能的话,我试图让它在半秒内运行。)
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 秒。如果可能的话,我试图让它在半秒内运行。)
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)实部和虚部之间的协方差与单个方差相比要小得多。这支持了他们独立的论点。