-4

我有以下代码需要计算 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

任何帮助,将不胜感激。提前致谢。

4

1 回答 1

2

首先,我不认为这个计算序列可以做得更快。以下可能会快一点,但肯定不是您要查找的数量:

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 的各个优化阶段的时序结果如下:

  • 原码:4.3s
  • 我最初的建议:4.5 s
  • 具有更简单随机数生成的原始代码:3.8 s
  • 上面删除了临时变量:3.2 s

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)实部和虚部之间的协方差与单个方差相比要小得多。这支持了他们独立的论点。

于 2017-02-07T01:13:28.073 回答