Matlab - 消除循环

时间:2015-02-13 15:58:21

标签: matlab for-loop

所以,我知道有很多关于消除for循环的帖子,但我仍然无法解决这个问题。

我希望重写我的代码,以便它的for循环更少,运行速度更快一些。该代码描述了在光通过介质传播之后计算不同颜色强度的光学问题。我已经为这项任务赢得了赞誉,但我想学习更好的方法,而不仅仅是在各处投入循环。我尝试使用递归来重写最里面的循环,这种循环起作用并且看起来不错,但速度稍慢。

欢迎任何其他意见/改进。

谢谢!

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

2 个答案:

答案 0 :(得分:1)

通常,如果您正在进行依赖于先前答案的计算,则无法摆脱for循环,这似乎是J_last变量的情况。

但是我看到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);

这将按原样运行,尽管您还应该删除变量" theta"在for循环中。即只需更改

n_eo_theta(theta)

n_eo_theta(j) 

使用"。"的方式计算中的前缀是摆脱for循环的最远工具(即使用逐元素计算)。例如;见element-wise multiplication

答案 1 :(得分:0)

你可以使用矩阵!!!!

例如,您有声明:

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的功能执行行的计算而不是循环。