Bisection While Loop Not Working

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 件のコメント

per isakson
per isakson 2018 年 4 月 8 日
編集済み: per isakson 2018 年 4 月 8 日
"(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

サインインしてコメントする。

回答 (1 件)

Walter Roberson
Walter Roberson 2018 年 4 月 8 日

0 投票

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 件のコメント

Farrah Rinehart
Farrah Rinehart 2018 年 4 月 8 日
The upper limit is -1.5 so I don't think f(x) can be on one side of 0 and f(x*1+eps) can be on the other side of zero? The upper limit is based on a graph that shows three discontinuous lines and one continuous line is between -5 and -1.5. I'm trying to find the root of that line. Secant and false position were successful.
Walter Roberson
Walter Roberson 2018 年 4 月 9 日
>> 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
Farrah Rinehart 2018 年 4 月 9 日
The upper limit is -1.5 and the lower limit is -5. When I try
r=fsolve(f,-1.5)
I get that answer you've provided, but I know the's a root because of the graph:
Walter Roberson
Walter Roberson 2018 年 4 月 9 日
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.

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeCreating and Concatenating Matrices についてさらに検索

タグ

質問済み:

2018 年 4 月 8 日

コメント済み:

2018 年 4 月 9 日

Community Treasure Hunt

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

Start Hunting!

Translated by