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.
>> 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 .
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:
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 Exchange에서 Creating 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