Bisection While Loop Not Working
Show older comments
I'm trying to get a while loop with a tolerance of machine epsilon to produce a root of -3.4256, according to fzero(f,-3.5). My while loop doesn't stop and I think it's because f(x3) never gets close enough to zero. What's incorrect about my code? (Ignore the "if true" I can't seem to get rid of that when I put my code in) Thanks!
f = @(x) x*tan(x)-1;
x1 =-1.5;
x2=-5;
x3=(x1+x2)/2;
tol = eps;
count = 1;
while abs(f(x3))>tol
if f(x3) == 0
break
elseif f(x1)> f(x3)
x1=x3;
else
x2=x3;
end
x3=(x1+x2)/2;
%
if (count >=0 && count <=5)
fprintf('Interation %g',count);
fprintf(' with x3 Results %.15f\n',x3);
end
count = count+1;
end
fprintf('the root is %g\n', x3);
1 Comment
per isakson
on 8 Apr 2018
Edited: per isakson
on 8 Apr 2018
"(Ignore the "if true" I can't seem to get rid of that when I put my code in)" To avoid "if true", select the text (blue background) and then click {}Code
Answers (1)
Walter Roberson
on 8 Apr 2018
0 votes
Because of limited precision and round-off problems, it is entirely possible that f(x) is one side of 0 and f(x*(1+eps)) is on the other side of zero, but that neither of them is 0. The scale of the error can be indefinitely large in cases of catastrophic cancellation or if the scale of values is large enough -- remember that near realmax, adjacent representable values can be over 1E290 apart.
You need to put in safeguards of some kind.
4 Comments
Farrah Rinehart
on 8 Apr 2018
Walter Roberson
on 9 Apr 2018
>> r = fsolve(f, -1.3)
Equation solved.
fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.
<stopping criteria details>
r =
-0.860333589019425
>> f(r)
ans =
1.44106948596345e-13
>> f(r*(1-eps))
ans =
1.4344081478157e-13
When r is positive then the next more positive number is r*(1+eps) . When r is negative then the next less negative number is r*(1-eps) .
You can see that the two adjacent values never evaluate exactly to 0. The root is between them, near -0.86033358901937976248389342413766233341188436323765 .
Farrah Rinehart
on 9 Apr 2018
Walter Roberson
on 9 Apr 2018
fsolve() has a built in tolerance. If we continue with the above with
>> r1 = fzero(f,r)
r1 =
-0.86033358901938
>> f(r1)
ans =
-1.11022302462516e-16
>> f(r1*(1+eps))
ans =
6.66133814775094e-16
we can see two adjacent representable numbers where the function has different signs.
When you plot a graph, it samples at a number of places and draws straight lines between the results. When it does that on a fine enough scale, the result looks curved to you. The straight line passes through the zero -- but that does not mean that there is a particular representable value at which f will be exactly zero.
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!