After a condition of X amount of iterations, if fail then do another function?

조회 수: 1 (최근 30일)
How would I go about implementing that:
Given an interval (a,b) and iterating it through multiple functions:
If the 5th successive iteration had not reduced the interval then a different function is used for the next iteration.
Overall how do I make a conditional statement that if the original interval given hasn't been reduced through an X amount of iterations, then another function would be done?
I understand this may be vague.
I am trying to implement this into the brent's method:
function brent( a, b, f, tol)
FA=f(a);
FB=f(b);
if FA*FB >= 0
error('the root is not bracketed.')
end
% Compare the |f(a)| and |f(b)| to see which...
% is closer to the x-axis by swapping
if abs(FA) < abs(FB)
temp = a;
a = b;
b = temp;
end
% For first iteration
% Need 3 values so we will set c = a, to provide ...
% a, b ,c (technically a, b, a) but this will fail ...
% the conditional statements for interpolation...
% where f(a)~=f(b)~=f(c) (aka they cannot all be equal)...
% or else the denominator goes to 0, hence bisection...
% is forced.
c = a;
FC=f(c);
mflag = 1;
i=0;
delta = tol;
while abs(b - a)>= tol
i = i+1;
if (f(a) ~= f(c)) && (f(c) ~= f(b))
s = a*((f(b)*f(c))/((f(a)-f(b))*(f(a)-f(c))))...
+b*((f(a)*f(c))/((f(b)-f(a))*(f(b)-f(c))))...
+c*((f(a)*f(b)/((f(c)-f(a)))*(f(c)-f(b))));
else
s = b - f(b)*((b-a)/(f(b)-f(a)));
end
% Conditional statements for bisection step
% Do the opposite of inequality statements ...
% to force bisection.
%%%% This is where I believe I should put the iteration condition but I'm unsure %%%%
if s > b && s < (3*a+b)/4 ||...
(mflag == 1 && abs(s-b)>0.5*abs(b-c))||...
(mflag == 1 && abs(delta)>abs(b-c))||...
(mflag == 0 && abs(s-b)>0.5*abs(c-d))||...
(mflag == 0 && abs(delta)>abs(c-d))||...
(mflag == 1 && abs(f(s))/2 >= abs(f(b)))
s = (a+b)/2;
mflag = 1;
% when true, then bisection ^
else
mflag = 0;
% otherwise, do interpolation ^
end
% Calculate f(s)
% Handling ill-behaved functions by adding another...
% variable d, which is the pervious value of c.
d = c; c = b;
if f(a)*f(s) < 0
b = s;
else
a = s;
end
if abs(f(a)) < abs(f(b))
temp = a;
a = b;
b = temp;
end
end
fprintf('Root is = %d, ending at the %d iteration', s, i)
end
  댓글 수: 3
Don
Don 2019년 10월 31일
how would I be able to paste the code to make it easier to read?
Rik
Rik 2019년 10월 31일
You can use the tools explained on this page to make your question more readable. But in short, hit ctrl-e on an empty line to switch to the code mode, and then paste it.

댓글을 달려면 로그인하십시오.

채택된 답변

John D'Errico
John D'Errico 2019년 10월 30일
편집: John D'Errico 2019년 10월 30일
I'd echo the point made by Rik, that a variable named true, that may in fact be false is a really, really bad idea. It is asking for a bug to happen, one that you will never figure out.
As far as the question goes, that part is trivial.
Maintain a counter, that is updated each iteration ONLY if the interval has not been reduced in size. On any iteration where the size does get reduced, then set the counter to 0.
If that counter ever reaches 5, then you perform a bisection step (or whatever). After the bisection step, reset the counter to 0.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Characters and Strings에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by