我认为您的代码已经很好地矢量化了(对于n
和m
)。rho
如果您希望此函数也接受/ phi
/值的数组z
,我建议您只需在 for 循环中处理值,因为我怀疑任何进一步的矢量化都会带来显着的改进(加上代码将更难阅读)。
话虽如此,在下面的代码中,我尝试{row N} * { matrix N*M } * {col M} = {scalar}
通过对 BESSELJ 和 COS 函数的一次调用(我将每个行/矩阵/列放在第三维)。它们的乘法仍然在循环中完成(准确地说是 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
请注意,随着您增加输入向量的大小,这两种方法将开始具有相似的时序(在某些情况下,FOR 循环甚至会获胜)