0

次の変数を使用します。

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>;

のmnS_mn*exp(1i*(m*theta + n*phi))合計を計算するにはどうすればよいですか。

$\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(:));

しかし、それにはthetaandがandphiと同じ数の要素を持つ必要があり、見返りに 1 つの要素しか得られません。 andのサイズに関係なく、 のサイズの行列が必要です (つまり、合計を評価できるようにしたい)との関数として)。mnmeshgrid(theta,phi)thetaphithetaphi

matlabでこの計算を行うにはどうすればよいですか?

4

3 に答える 3

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 の大きなセットに対してこれを実行したい場合は、一対のループが簡単な解決策になります。または、配列が大きくなりますが、すべてを 1 回の計算で行うこともできます。まだ難しくない。浄水場?

meshgrid と ndgrid の両方が 2 つ以上の引数を取ることに気付きましたか? それでは、bsxfun の使用方法を学習してから、squeeze を実行します。

[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));

または、これを行うと、少し速くなります。前回の計算では、私のマシンは 0.07 秒かかりました。この最後のものは 0.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 秒かかります。浄水場? コーヒーを飲んでリラックス。

于 2012-05-19T16:58:57.363 に答える
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 つの次元 (変数ごとに 1 つ: theta、phi、m、n) の配列が得られます。これで次のように計算できます。

m.*theta + n.*phi

次のように、S_mn に size_theta、size_phi、size_m、size_n の 4 つの次元を持たせる必要があります。

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) を合計して、サイズが size_theta による size_phi の 2 次元の配列を取得できます。

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

注: 現在、Matlab にアクセスできないため、これが実際に機能するかどうかをテストできません。

于 2012-05-19T16:58:58.507 に答える
0

これにはいくつかの方法があります。

1 つの方法は、合計を theta と phi の関数として返す関数 (-handle) を作成し、それを使用arrayfunして合計を計算することです。もう 1 つの方法は、計算を完全にベクトル化することです。ただし、これはより多くのメモリを使用します。

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);
于 2012-05-19T17:00:10.840 に答える