2

座標rhophizを持つ極点に対して、 m = 1: Mおよびn = 1: Nの二重合計があります。

m と n の二重和

私はそれのベクトル化された表記法を書きました:

N = 10;
M = 10;
n = 1:N;
m = 1:M;

rho = 1;
phi = 1;
z = 1;

summ =  cos (n*z)  * besselj(m'-1, n*rho) * cos(m*phi)';

ここで、座標rhophizのベクトル (列) を受け入れるように、この関数を書き直す必要があります。arrayfun、cellfun、simple for loop を試してみましたが、動作が遅すぎます。「MATLAB 配列操作のヒントとコツ」については知っていますが、MATLAB 初心者の私には repmat やその他の関数が理解できません。

ベクトル化されたソリューションを提案できる人はいますか?

4

2 に答える 2

1

あなたのコードはすでに十分にベクトル化されていると思います (nとの場合m)。この関数が // 値の配列も受け入れるようにしたい場合はrhophizを for ループで処理することをお勧めします。これ以上のベクトル化によって大幅な改善がもたらされるとは思えないためです (さらに、コードが読みにくくなります)。

そうは言っても、以下のコードでは、乗算{row N} * { matrix N*M } * {col M} = {scalar}されるさまざまなコンポーネントを計算する部分をベクトル化しようとしました。これは、BESSELJ および COS 関数を 1 回呼び出すことによって行われました (行/行列/列のそれぞれを 3 次元に配置します)。 )。それらの乗算はまだループで行われます(正確には ARRAYFUN):

%# parameters
N = 10; M = 10;
n = 1:N; m = 1:M;

num = 50;
rho = 1:num; phi = 1:num; z = 1:num;

%# straightforward FOR-loop
tic
result1 = zeros(1,num);
for i=1:num
    result1(i) = cos(n*z(i)) * besselj(m'-1, n*rho(i)) * cos(m*phi(i))';
end
toc

%# vectorized computation of the components
tic
a = cos( bsxfun(@times, n, permute(z(:),[3 2 1])) );
b = besselj(m'-1, reshape(bsxfun(@times,n,rho(:))',[],1)');             %'
b = permute(reshape(b',[length(m) length(n) length(rho)]), [2 1 3]);    %'
c = cos( bsxfun(@times, m, permute(phi(:),[3 2 1])) );
result2 = arrayfun(@(i) a(:,:,i)*b(:,:,i)*c(:,:,i)', 1:num);            %'
toc

%# make sure the two results are the same
assert( isequal(result1,result2) )

TIMEIT関数を使用して別のベンチマーク テストを行いました(より公平なタイミングが得られます)。結果は前のものと一致します。

0.0062407    # elapsed time (seconds) for the my solution
0.015677     # elapsed time (seconds) for the FOR-loop solution

入力ベクトルのサイズを大きくすると、2 つの方法のタイミングが似てくることに注意してください (場合によっては FOR ループが勝つこともあります)。

于 2011-09-10T02:28:59.393 に答える
0

m_たとえば、との2つの行列を作成する必要があります。n_これにより、各行列の要素を選択することで、との両方にi,j必要なインデックスを取得できます。mn

ほとんどのMATLAB関数は行列とベクトルを受け入れ、それらの結果を要素ごとに計算します。したがって、二重の合計を生成するには、合計のすべての要素をで並列に計算し、 f(m_, n_)それらを合計します。

.*あなたの場合(演算子は行列の要素ごとの乗算を実行することに注意してください)

N = 10;
M = 10;
n = 1:N;
m = 1:M;

rho = 1;
phi = 1;
z = 1;

% N rows x M columns for each matrix
% n_ - all columns are identical
% m_ - all rows are identical
n_ = repmat(n', 1,  M);
m_ = repmat(m , N,  1);

element_nm =  cos (n_*z) .* besselj(m_-1, n_*rho) .* cos(m_*phi);
sum_all = sum( element_nm(:) );
于 2011-09-09T18:26:31.577 に答える