【问题标题】:MATLAB: Check for while loop divergenceMATLAB:检查while循环分歧
【发布时间】:2016-07-23 02:22:23
【问题描述】:

我有一段带有 while 循环的代码。这个循环在某些情况下会发散,因此会产生一个无限循环。

我想检查循环是否发散,并以优雅高效的过程打破循环。

对此的解决方案是检查循环的每个输出,将其保存,并将其与之前计算的循环输出进行比较。

这是代码:

ai = 0; 
ai_old = 100;   
iteration = 0;
CDeff  = 0;

while abs(ai - ai_old)>2*10^-1                                               % Get induced angle of attack

    iteration  = iteration +1;
    ai_old = ai;

    Cleff = (Clp * cosd(ai)^2 + CDeff * sind(ai) )/cosd(ai);
    Veff = Vp/cosd(ai); 
    Re_eff = Reinf * Veff/Vinf * cp/c;
    Meff = Mp/cosd(ai);

if iteration ==1
    AFdata(:,2) = AFdata(:,2)/cosd(SweepQC);
end

        [~,a_eff,CDeff]  = obj.ConstantVortex(AFdata,[],Cleff,Meff);
        ai = -a_eff + (AOA + Twists(zz))/cosd(SweepQC);

end

这里,ai 是用函数obj.ConstantVortex 计算的,并与之前计算的ai 进行比较。当差值足够小时终止while循环。

但是,初始ai 和计算出的ai 之间的差异可能会随着每次迭代而增加。

我该如何检查?并相应地打破循环?

谢谢

【问题讨论】:

    标签: matlab loops while-loop


    【解决方案1】:

    这种情况的典型解决方案是存储更多以前的值,并随着时间的推移监控行为。因此,您可以使用:

    而不是 ai_old
    ai = 0;
    num_prev = 5;  % how many previous results to check
    ai_prev = zeros(1,num_prev);
    iteration = 0;
    
    while abs(ai - ai_prev(end))>2*10^-1
    
        iteration = iteration+1;
        % your loop code goes here
    
        % now update the array of previous values
        ai_prev = circshift(ai_prev,[0 -1]);
        ai_prev(end) = ai;
    
        if iteration > num_prev && all(sign(diff(ai_prev)))
            % the slope of the previous five results is positive, so exit
            break
        end
    end
    

    您可以更改先前结果的数量并使用任何适合的函数来检查 ai_prev 中数据的中断条件以进行计算。例如,您可能想要对之前的结果进行一些平均,或者使用与diff() 不同的函数。

    【讨论】:

    • 嘿,ai_prev = zeros[1 num_prev];这是一个无效的 Matlab 命令。此外,&& all(sign(diff(ai_prev))) 不是 if 语句的正确定义,因为它只会产生一个数字而不是条件。
    • @BalrajBoyal 谢谢你;编辑以使用 zeros() 修复错字。 all 语句确实返回真/假条件,因此该语句计算正确。
    • @Mhopeng,哦,对不起,我不知道。谢谢!
    【解决方案2】:

    一种解决方案是保留最后的差异或最小差异,并将当前差异与该差异进行比较。例如,您可以拥有变量 ai_older 并使用它。你可以添加

    ai_older = 1000;
    

    在你的while循环之前,然后有

    ai_older = ai_old;
    ai_old = ai;
    

    并将while 条件更改为

    while abs(ai - ai_old)>2*10^-1 && abs(ai - ai_old) < abs(ai_old - ai_older)
    

    现在您可以避免分歧。但是,我并不完全了解您的问题,也不确定是否需要使用 abs

    正如我之前提到的,根据您的问题,您可能希望在此之前保持最小差异并将当前的差异与该差异进行比较。

    【讨论】:

    • 你好,你不应该在循环之前定义ai_old吗?
    • 绝对需要在循环之前定义它。虽然,它在每次迭代中都在变化,但第一次进入循环你需要它。
    猜你喜欢
    • 1970-01-01
    • 2017-04-03
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 2019-11-23
    • 2012-10-05
    相关资源
    最近更新 更多