Matlab - 消除循环
Matlab - Eliminating for loops
所以,我知道还有许多其他帖子是关于消除 for 循环的,但我仍然无法弄明白。
我希望重写我的代码,以减少 for 循环并提高运行速度。该代码描述了一个光学问题,计算光在介质中传播后不同颜色的强度。我已经因为这项任务获得了荣誉,但我想学习更好的方法,而不是到处乱扔 for 循环。我尝试使用递归重写最内层的循环,它看起来不错,但速度有点慢。
也欢迎任何其他 comments/improvements。
谢谢!
n_o=1.50;
n_eo=1.60;
d=20e-6;
N_skiv=100;
lambda=[650e-9 510e-9 475e-9];
E_in=[1;1]./sqrt(2);
alfa=pi/2/N_skiv;
delta=d/N_skiv;
points=100;
int=linspace(0,pi/2,points);
I_ut=zeros(3,points);
n_eo_theta=@(theta)n_eo*n_o/sqrt(n_o^2*cos(theta)^2+n_eo^2*sin(theta)^2);
hold on
for i=1:3
for j=1:points
J_last=J_pol2(0);
theta=int(j);
for n=0:N_skiv
alfa_n=alfa*n;
J_last=J_ret_uppg2(alfa_n, delta , n_eo_theta(theta) , n_o , lambda(i) ) * J_last;
end
E_ut=J_pol2(pi/2)*J_last*E_in;
I_ut(i,j)=norm(E_ut)^2;
end
end
theta_grad=linspace(0,90,points);
plot(theta_grad,I_ut(1,:),'r')
plot(theta_grad,I_ut(2,:),'g')
plot(theta_grad,I_ut(3,:),'b')
以及函数:
function matris=J_proj(alfa)
matris(1,1)=cos(alfa);
matris(1,2)=sin(alfa);
matris(2,1)=-sin(alfa);
matris(2,2)=cos(alfa);
end
function matris=J_pol2(alfa)
J_p0=[1 0;0 0];
matris=J_proj(-alfa)*J_p0*J_proj(alfa);
end
function matris=J_ret_uppg2(alfa_n,delta,n_eo_theta,n_o,lambda)
k0=2*pi/lambda;
J_r0_u2(1,1)=exp(1i*k0*delta*n_eo_theta);
J_r0_u2(2,2)=exp(1i*k0*n_o*delta);
matris=J_proj(-alfa_n)*J_r0_u2*J_proj(alfa_n);
end
如果您正在进行的计算依赖于先前的答案,通常您无法摆脱 for 循环,J_last-variable 似乎就是这种情况。
然而,我至少看到了 n_eo_theta 内联函数的一项可能改进,而不是进行 100 次计算,您可以简单地更改这一行:
n_eo_theta=@(theta)n_eo*n_o/sqrt(n_o^2*cos(theta)^2+n_eo^2*sin(theta)^2);
进入:
theta_0 = 1:100;
n_eo_theta=n_eo*n_o./sqrt(n_o^2*cos(theta_0).^2+n_eo^2*sin(theta_0).^2);
这会 运行 原样,尽管您还应该删除 for 循环中的变量 "theta"。 IE。只需更改
n_eo_theta(theta)
进入
n_eo_theta(j)
“.”的使用方式计算中的前缀是摆脱 for 循环的最有效工具(即使用逐元素计算)。例如;参见 element-wise multiplication。
你可以使用矩阵!!!!
例如,您有以下语句:
theta=int(j)
在嵌套循环中。您可以将其替换为:
theta = [int(1:points);int(1:points);int(1:points)];
或:
theta = int(repmat((1:points), 3, 1));
那么,你有
alfa_n=alfa * n;
您可以将其替换为:
alfa_n = alfa .* (0:N_skiv);
并且像时尚一样连续完成所有计算。这意味着,您将获得连续的循环值,而不是循环。因此,您可以使用 MATLAB 的功能而不是循环在行上执行计算。
所以,我知道还有许多其他帖子是关于消除 for 循环的,但我仍然无法弄明白。
我希望重写我的代码,以减少 for 循环并提高运行速度。该代码描述了一个光学问题,计算光在介质中传播后不同颜色的强度。我已经因为这项任务获得了荣誉,但我想学习更好的方法,而不是到处乱扔 for 循环。我尝试使用递归重写最内层的循环,它看起来不错,但速度有点慢。
也欢迎任何其他 comments/improvements。
谢谢!
n_o=1.50;
n_eo=1.60;
d=20e-6;
N_skiv=100;
lambda=[650e-9 510e-9 475e-9];
E_in=[1;1]./sqrt(2);
alfa=pi/2/N_skiv;
delta=d/N_skiv;
points=100;
int=linspace(0,pi/2,points);
I_ut=zeros(3,points);
n_eo_theta=@(theta)n_eo*n_o/sqrt(n_o^2*cos(theta)^2+n_eo^2*sin(theta)^2);
hold on
for i=1:3
for j=1:points
J_last=J_pol2(0);
theta=int(j);
for n=0:N_skiv
alfa_n=alfa*n;
J_last=J_ret_uppg2(alfa_n, delta , n_eo_theta(theta) , n_o , lambda(i) ) * J_last;
end
E_ut=J_pol2(pi/2)*J_last*E_in;
I_ut(i,j)=norm(E_ut)^2;
end
end
theta_grad=linspace(0,90,points);
plot(theta_grad,I_ut(1,:),'r')
plot(theta_grad,I_ut(2,:),'g')
plot(theta_grad,I_ut(3,:),'b')
以及函数:
function matris=J_proj(alfa)
matris(1,1)=cos(alfa);
matris(1,2)=sin(alfa);
matris(2,1)=-sin(alfa);
matris(2,2)=cos(alfa);
end
function matris=J_pol2(alfa)
J_p0=[1 0;0 0];
matris=J_proj(-alfa)*J_p0*J_proj(alfa);
end
function matris=J_ret_uppg2(alfa_n,delta,n_eo_theta,n_o,lambda)
k0=2*pi/lambda;
J_r0_u2(1,1)=exp(1i*k0*delta*n_eo_theta);
J_r0_u2(2,2)=exp(1i*k0*n_o*delta);
matris=J_proj(-alfa_n)*J_r0_u2*J_proj(alfa_n);
end
如果您正在进行的计算依赖于先前的答案,通常您无法摆脱 for 循环,J_last-variable 似乎就是这种情况。
然而,我至少看到了 n_eo_theta 内联函数的一项可能改进,而不是进行 100 次计算,您可以简单地更改这一行:
n_eo_theta=@(theta)n_eo*n_o/sqrt(n_o^2*cos(theta)^2+n_eo^2*sin(theta)^2);
进入:
theta_0 = 1:100;
n_eo_theta=n_eo*n_o./sqrt(n_o^2*cos(theta_0).^2+n_eo^2*sin(theta_0).^2);
这会 运行 原样,尽管您还应该删除 for 循环中的变量 "theta"。 IE。只需更改
n_eo_theta(theta)
进入
n_eo_theta(j)
“.”的使用方式计算中的前缀是摆脱 for 循环的最有效工具(即使用逐元素计算)。例如;参见 element-wise multiplication。
你可以使用矩阵!!!!
例如,您有以下语句:
theta=int(j)
在嵌套循环中。您可以将其替换为:
theta = [int(1:points);int(1:points);int(1:points)];
或:
theta = int(repmat((1:points), 3, 1));
那么,你有
alfa_n=alfa * n;
您可以将其替换为:
alfa_n = alfa .* (0:N_skiv);
并且像时尚一样连续完成所有计算。这意味着,您将获得连续的循环值,而不是循环。因此,您可以使用 MATLAB 的功能而不是循环在行上执行计算。