我有一段带有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这里,使用函数obj.ConstantVortex计算ai,并将其与先前计算的ai进行比较。当差异足够小时,while循环就会终止。
然而,可能会发生初始ai和计算的ai之间的差异随着每次迭代而增加。
我怎样才能检查这个?并相应地打破循环?
谢谢
发布于 2016-07-23 01:20:02
这种情况的典型解决方案是存储更多以前的值,并随着时间的推移监控行为。因此,您可以使用以下命令来代替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()不同的函数。
发布于 2016-07-23 01:01:37
一种解决方案是保留最后的差异或最小差异,并将当前差异与之进行比较。例如,您可以拥有变量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。
正如我之前提到的,根据您的问题,您可能希望将最小差异保留到现在,并将当前差异与当前差异进行比较。
https://stackoverflow.com/questions/38530733
复制相似问题