我想将这个double for循环向量化,因为它是我代码中的瓶颈。由于Matlab是一种基于索引的语言,我必须为M = 0创建一个附加项。
R,r,lambda是常数
Slm(L,M),Clm(L,M)是基质70×70
pm(L,M)是基质70x71Cl(L),P1(L)是载体70x1
% function dU_r
s1 = 0;
for L = 2:70
s1 = s1 + ((R/r)^L)*(L+1)*Pl(L)*Cl(L);
for m = 1:L
s1 = s1 + ((R/r)^L)*(L+1)*Plm(L,M)*(Clm(L,M)*...
cos(M*lambda) + Slm(L,M)*sin(M*lambda));
end
end
dU_r = -(mu_p/(r^2))*s1;
% function dU_phi
s2=0;
for L = 2:70
s2 = s2 + ((R/r)^L))*Plm(L,1)*Cl(L);
for m = 1:l
s2 = s2 + ((R/r)^L)*(Plm(L,M+1)-M*tan(phi)*Plm(L,M))*...
(Clm(L,M)*cos(M*lambda) + Slm(L,M)*sin(M*lambda));
end;
end;
dU_phi = (mu_p/r)*s2;
% function dU_lambda
s3=0;
for L=2:70
for m=1:L
s3 = s3 + ((R/r)^L)*M*Plm(L,M)*(Slm(L,M)*cos(M*lambda)...
- Clm(L,M)*sin(M*lambda));
end;
dU_lambda = (mu_p/r)*s3;
答案 0 :(得分:1)
我认为以下代码可能是解决方案的一部分(仅部分矢量化),对于完整的矢量化,您可能希望查看meshgrid
,ndgrid
,bsxfun
和/或者repmat
,我想。
s2 = 0;
L = 2:70;
PlCl = Pl.*Cl;
PlmClm = Plm.*Clm;
Rrl = (R/r).^(L).*(L+1);
COS = cos((1:70)*lambda);
SIN = sin((1:70)*lambda);
for l=L
M = 1:l;
s1 = sum(Rrl(l-1)*PlmClm(l,M).*(COS(M) + Slm(l,M).*SIN(M)));
s2 = s2 + s1;
end;
s2 = s2 + sum(Rrl(L).*PlCl(L));
我没有尝试过运行此代码,因此如果它可能会抱怨某些维度。你应该能够弄明白(这里或那里只有一些转置)。
只是旁边的一个注释:尽量远离短变量名称(当然还有像l
这样含糊不清的名称(对于1,I或者l可能会被误读)。此外,它可能是如果您有实际(即未编码)表达式,则更容易对代码进行矢量化。
修改:gnovice
建议的应用核心功能答案 1 :(得分:1)
对于这种特殊情况,不完全向量化您的解决方案可能会更有效率。 As Egon illustrates,可以通过矢量化替换内部循环,但是替换外部for循环也可能减慢您的解决方案。
原因?如果您注意循环中的矩阵Plm
,Clm
和Slm
的索引方式,则只能使用lower triangular parts中的值。主对角线上方的所有值都将被忽略。通过完全向您的解决方案进行矢量化,使得它使用矩阵运算而不是循环,您最终将使用矩阵的零上部三角形部分执行不必要的乘法运算。这是for循环可能是更好选择的情况之一。
因此,这里是Egon's answer的精炼和修正版本,在执行的数学运算次数方面应该接近最优:
index = 2:70;
coeff = ((R/r).^index).*(index+1);
lambda = lambda.*(1:70).'; %'
cosVector = cos(lambda);
sinVector = sin(lambda);
s2 = coeff*(Pl(index).*Cl(index));
for L = index
M = 1:L;
s2 = s2 + coeff(L-1)*((Plm(L,M).*Clm(L,M))*cosVector(M) + ...
(Plm(L,M).*Slm(L,M))*sinVector(M));
end
答案 2 :(得分:0)
参考Jan Simon 1给出的解决方案,我已经为我的问题编写了以下代码
Rr = R/r;
RrL = Rr;
cosLambda = cos((1:70)* lambda);
sinLambda = sin((1:70)* lambda);
u1 = uint8(1);
s1 = 0;
s2 = 0;
s3 = 0;
for j = uint8(2):uint8(70)
RrL = RrL * Rr;
q1 = RrL * (double(j) + 1);
t1 = Pl(j) * datos.Cl(j);
q2 = RrL;
t2 = Plm(j,1) * Cl(j);
t3 = 0;
for m = u1:j
t1 = t1 + Plm(j,m) * ...
(Clm(j, m) * cosLambda(m) + ...
Slm(j, m) * sinLambda(m));
t2 = t2 + (Plm(j,m+1)-double(m)*tan_phi*Plm(j,m))*...
(Clm(j,m)*cosLambda(m) + Slm(j,m)*sinLambda(m));
t3 = t3 + double(m)*Plm(j,m)*(Slm(j,m)*cosLambda(m)...
- Clm(j,m)*sinLambda(m));
end
s1 = s1 + q1 * t1;
s2 = s2 + q2 * t2;
s3 = s3 + q2 * t3;
end
dU_r = -(mu_p/(r^2))*s1;
dU_phi = (mu_p/r)*s2;
dU_lambda = (mu_p/r)*s3