矢量化MATLAB函数

时间:2011-09-09 15:45:21

标签: matlab sum vectorization bessel-functions

我对 m = 1: M n = 1: N 的极点进行双重求和坐标 rho phi z

Double summ over m and 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)';

现在我需要重写此函数以接受坐标 rho phi z 的向量(列)。我试过arrayfun,cellfun,简单的循环 - 它们对我来说太慢了。我知道“MATLAB数组操作提示和技巧”,但作为MATLAB初学者,我无法理解repmat和其他函数。

有人可以提出矢量化解决方案吗?

2 个答案:

答案 0 :(得分:1)

我认为您的代码已经很好地进行了矢量化(适用于nm)。如果您希望此函数也接受rho / phi / z值的数组,我建议您只需处理for循环中的值,因为我怀疑任何进一步的矢量化将会带来重大改进(加上代码将更难阅读)。

话虽如此,在下面的代码中,我尝试通过单次调用BESSELJ和COS函数来向量化计算各个组件乘以{row N} * { matrix N*M } * {col M} = {scalar}的部分(我放置每一行第三维中的/ matrix / column)。它们的乘法仍为done in a loop(确切地说是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循环甚至在某些情况下获胜)

答案 1 :(得分:0)

您需要创建两个矩阵,例如m_n_,以便通过选择每个矩阵的元素i,j,您可以获得m和{{的所需索引1}}。

大多数MATLAB函数接受矩阵和向量,并逐个元素地计算它们的结果。因此,要生成一个双和,您可以n并行计算和的所有元素并将它们相加。

在你的情况下(注意f(m_, n_)运算符执行矩阵的逐元素乘法)

.*