MATLAB Answers


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

Don 님이 질문을 제출함. 29 Oct 2019
최근 활동 Don 님이 편집함. 2 Nov 2019
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)
if FA*FB >= 0
error('the root is not bracketed.')
% 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;
% 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;
mflag = 1;
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))))...
s = b - f(b)*((b-a)/(f(b)-f(a)));
% 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 ^
mflag = 0;
% otherwise, do interpolation ^
% 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;
a = s;
if abs(f(a)) < abs(f(b))
temp = a;
a = b;
b = temp;
fprintf('Root is = %d, ending at the %d iteration', s, i)

  댓글 수: 3

It is a bad idea to have a variable with the name true. That way even cause an error on some releases.
Also, unformatted code is hard to read. You seem to have the right idea of where to modify your code, but it is not readable enough to be sure.
how would I be able to paste the code to make it easier to read?
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.

로그인 to comment.

답변 수: 1

John D'Errico 님의 답변 30 Oct 2019
John D'Errico 님이 편집함. 30 Oct 2019
 채택된 답변

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

로그인 to comment.

Translated by