使用以下变量:
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 之和,即
我想过像
这样的事情[m, n] = meshgrid(m,n);
[theta, phi] = meshgrid(theta,phi);
r_mn = S_mn.*exp(1i*(m.*theta + n.*phi));
thesum = sum(r_mn(:));
但这需要theta
和phi
与m
和n
具有相同数量的元素,并且它只给我一个元素作为回报 - 我想要一个矩阵meshgrid(theta,phi)
的大小,无论theta
和phi
的大小如何(即我希望能够将总和作为theta
和{{的函数进行求值1}})。
如何在matlab中进行此计算?
答案 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);