在Matlab中计算一个棘手的总和

时间:2012-05-19 15:44:08

标签: matlab sum

使用以下变量:

m = 1:4; n = 1:32;
phi = linspace(0, 2*pi, 100);
theta = linspace(-pi, pi, 50);

S_mn = <a 4x32 coefficient matrix, corresponding to m and n>;

如何计算S_mn*exp(1i*(m*theta + n*phi)) m n 之和,即

$\sum_m \sum_n S_mn exp(i(m\theta+n\phi))

我想过像

这样的事情
[m, n] = meshgrid(m,n);
[theta, phi] = meshgrid(theta,phi);
r_mn = S_mn.*exp(1i*(m.*theta + n.*phi));
thesum = sum(r_mn(:));

但这需要thetaphimn具有相同数量的元素,并且它只给我一个元素作为回报 - 我想要一个矩阵meshgrid(theta,phi)的大小,无论thetaphi的大小如何(即我希望能够将总和作为theta和{{的函数进行求值1}})。

如何在matlab中进行此计算?

3 个答案:

答案 0 :(得分:1)

因为我不知道S是什么......

S = randn(4,32);

[m,n] = ndgrid(1:4,1:32);
fun = @(theta,phi) sum(sum(S.*exp(sqrt(-1)*(m*theta + n*phi))));

对我来说很好。

fun(pi,3*pi/2)
ans =
          -15.8643373238676 -      1.45785698818839i

如果您现在希望为大量值phi和theta执行此操作,那么现在一对循环就是一个简单的解决方案。或者,您可以在一次计算中完成所有操作,尽管数组会变大。还不难。 WTP?

您是否意识到meshgrid和ndgrid只需要两个参数?所以现在是时候学习如何使用bsxfun,然后挤压。

[m,n,theta,phi] = ndgrid(1:4,1:32,linspace(-pi, pi, 50),linspace(0, 2*pi, 100));
res = bsxfun(@times,S,exp(sqrt(-1)*(m.*theta + n.*phi)));
res = squeeze(sum(sum(res,1),2));

或者这样做,这会更快一些。之前的计算花了我的机器.07秒。最后一个花了.05,所以通过大量使用bsxfun节省了一些费用。

m = (1:4)';
n = 1:32;
[theta,phi] = ndgrid(linspace(-pi, pi, 50),linspace(0, 2*pi, 100));
theta = reshape(theta,[1,1,size(theta)]);
phi = reshape(phi,size(theta));
res = bsxfun(@plus,bsxfun(@times,m,theta*sqrt(-1)),bsxfun(@times,n,phi*sqrt(-1)));
res = bsxfun(@times,S,exp(res));
res = squeeze(sum(sum(res,1),2));

如果你需要做2000次以上,那么它应该需要100秒。 WTP?喝杯咖啡放松一下。

答案 1 :(得分:0)

首先保存每个变量的大小:

size_m = size(m);
size_n = size(n);
size_theta = size(theta);
size_phi = size(phi);

使用ngrid这样的功能:

[theta, phi, m, n] = ngrid(theta, phi, m, n)

这将为您提供一个包含4个维度的数组(每个变量一个:theta,phi,m,n)。现在你可以计算出来:

m.*theta + n.*phi

现在你需要让S_mn有4个尺寸,尺寸为size_theta,size_phi,size_m,size_n,如下所示:

S_tpmn = repmat(S_mn, [size_theta size_phi size_m size_n]);

现在你可以像这样计算你的总和:

aux_sum = S_tpmn.*exp(1i*(m.*theta + n.*phi));

最后,您可以沿最后2个维度(m和n)求和,得到一个2维的数组,其大小size_theta by size_phi:

final_sum = sum(sum(aux_sum, 4), 3);

注意:我现在无法访问Matlab,因此我无法测试这是否真的有效。

答案 2 :(得分:0)

有几种方法可以解决这个问题。

一种方法是创建一个函数(-handle),它将sum作为theta和phi的函数返回,然后使用arrayfun来进行求和。另一种方法是完全向量化计算,但这会占用更多内存。

arrayfun版本:

[m, n] = meshgrid(m,n);

sumHandle = @(theta,phi)sum(reshape(...
    S_mn.*exp(1i(m*theta + n*phi)),...
    [],1)) 

[theta, phi] = meshgrid(theta,phi);

sumAsFunOfThetaPhi = arrayfun(sumHandle,theta,phi);

矢量化版本:

[m, n] = meshgrid(m,n);
m = permute(m(:),[2 4 1 3]); %# vector along dim 3
n = permute(n(:),[2 3 4 1]); %# vector along dim 4

S_mn = repmat( permute(S_mn,[3 4 1 2]), length(theta),length(phi));

theta = theta(:); %# vector along dim 1 (phi is along dim 2 b/c of linspace)

fullSum = S_mn.* exp( 1i*(...
    bsxfun(@plus,...
       bsxfun(@times, m, theta),...
       bsxfun(@times, n, phi),...
    )));

sumAsFunOfThetaPhi = sum(sum( fullSum, 3),4);