あなたのコードはすでに十分にベクトル化されていると思います (n
との場合m
)。この関数が // 値の配列も受け入れるようにしたい場合はrho
、phi
値z
を 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 ループが勝つこともあります)。