任何人都可以帮助矢量化这个Matlab代码吗?具体问题是带向量输入的sum和bessel函数。 谢谢!
N = 3;
rho_g = linspace(1e-3,1,N);
phi_g = linspace(0,2*pi,N);
n = 1:3;
tau = [1 2.*ones(1,length(n)-1)];
for ii = 1:length(rho_g)
for jj = 1:length(phi_g)
% Coordinates
rho_o = rho_g(ii);
phi_o = phi_g(jj);
% factors
fc = cos(n.*(phi_o-phi_s));
fs = sin(n.*(phi_o-phi_s));
Ez_t(ii,jj) = sum(tau.*besselj(n,k(3)*rho_s).*besselh(n,2,k(3)*rho_o).*fc);
end
end
答案 0 :(得分:1)
您可以尝试对这些代码进行矢量化,这可能会使用某些bsxfun
左右,但是很难理解代码,并且问题是它是否会运行得更快,因为您的代码已经在内循环中使用向量数学(即使您的向量只有长度3)。由此产生的代码将变得非常难以阅读,因此当您在2年内查看它时,您或您的同事将不知道它的作用。
在浪费时间进行矢量化之前,了解loop invariant code motion更为重要,这很容易应用于您的代码。一些观察:
fs
,因此请将其删除。tau.*besselj(n,k(3)*rho_s)
不依赖于任何循环变量ii
和jj
,因此它是常量。在循环之前计算一次。Ez_t
。fc
,取决于jj
,besselh(n,2,k(3)*rho_o)
取决于ii
。我猜后者花费的时间要多得多,所以最好不要在内循环中计算N*N
次,而在外循环中只计算N
次。如果基于jj
的计算花费更多时间,您可以将for循环交换为ii
和jj
,但这似乎不是这种情况。结果代码看起来像这样(未经测试):
N = 3;
rho_g = linspace(1e-3,1,N);
phi_g = linspace(0,2*pi,N);
n = 1:3;
tau = [1 2.*ones(1,length(n)-1)];
% constant part, does not depend on ii and jj, so calculate only once!
temp1 = tau.*besselj(n,k(3)*rho_s);
Ez_t = nan(length(rho_g), length(phi_g)); % preallocate space
for ii = 1:length(rho_g)
% calculate stuff that depends on ii only
rho_o = rho_g(ii);
temp2 = besselh(n,2,k(3)*rho_o);
for jj = 1:length(phi_g)
phi_o = phi_g(jj);
fc = cos(n.*(phi_o-phi_s));
Ez_t(ii,jj) = sum(temp1.*temp2.*fc);
end
end
答案 1 :(得分:0)
为了给出一个独立的答案,我将复制原始初始化
N = 3;
rho_g = linspace(1e-3,1,N);
phi_g = linspace(0,2*pi,N);
n = 1:3;
tau = [1 2.*ones(1,length(n)-1)];
并生成一些缺失数据(k(3)和rho_s和phi_s在n维)
rho_s = rand(size(n));
phi_s = rand(size(n));
k(3) = rand(1);
然后你可以用多维数组计算相同的Ez_t:
[RHO_G, PHI_G, N] = meshgrid(rho_g, phi_g, n);
[~, ~, TAU] = meshgrid(rho_g, phi_g, tau);
[~, ~, RHO_S] = meshgrid(rho_g, phi_g, rho_s);
[~, ~, PHI_S] = meshgrid(rho_g, phi_g, phi_s);
FC = cos(N.*(PHI_G - PHI_S));
FS = sin(N.*(PHI_G - PHI_S)); % not used
EZ_T = sum(TAU.*besselj(N, k(3)*RHO_S).*besselh(N, 2, k(3)*RHO_G).*FC, 3).';
您可以事后检查两个矩阵是否相同
norm(Ez_t - EZ_T)
答案 2 :(得分:0)
初始化 -
N = 3;
rho_g = linspace(1e-3,1,N);
phi_g = linspace(0,2*pi,N);
n = 1:3;
tau = [1 2.*ones(1,length(n)-1)];
嵌套循环表单(从代码中复制并在此处显示仅供比较) -
for ii = 1:length(rho_g)
for jj = 1:length(phi_g)
% Coordinates
rho_o = rho_g(ii);
phi_o = phi_g(jj);
% factors
fc = cos(n.*(phi_o-phi_s));
fs = sin(n.*(phi_o-phi_s));
Ez_t(ii,jj) = sum(tau.*besselj(n,k(3)*rho_s).*besselh(n,2,k(3)*rho_o).*fc);
end
end
矢量化解决方案 -
%%// Term - 1
term1 = repmat(tau.*besselj(n,k(3)*rho_s),[N*N 1]);
%%// Term - 2
[n1,rho_g1] = meshgrid(n,rho_g);
term2_intm = besselh(n1,2,k(3)*rho_g1);
term2 = transpose(reshape(repmat(transpose(term2_intm),[N 1]),N,N*N));
%%// Term -3
angle1 = repmat(bsxfun(@times,bsxfun(@minus,phi_g,phi_s')',n),[N 1]);
fc = cos(angle1);
%%// Output
Ez_t = sum(term1.*term2.*fc,2);
Ez_t = transpose(reshape(Ez_t,N,N));
关于此向量化或代码简化的注意事项 -