How do I make this bisection function recognize a bounce on a graph?

2 views (last 30 days)
I tried not including the error mesage of no sign change, but then it produces a root that was incorrect.
function [root,fx,eq,iter] = bisect(func,xl,xu,es,maxit,varargin)
% bisect: root location zeros; uses bisection method to find the root of
% the function
% input:
% func = name of function
% xl, xu = lower and upper guesses
% es = desired relative error (default = 0.0001%)
% maxit = maximum allowable iterations (default = 50)
% p1,p2,... = additional parameters used by func
% output:
% root= root estimate
% fx = function value at root estimate
% ea = approximate relative error(%)
% iter = number of iterations
if nargin >3
error('at least 3 input arguments required')
end
test = func(xl)*func(xu);
if test > 0
error('no sign change')
end
if nargin < 4 || isempty(es)
es = 0.0001;
end
if nargin < 5 || isempty(maxit)
maxit = 50;
end
iter = 0;
xr = xl;
ea = 100;
while(1)
xrold = xr;
xr = (xl+xu)/2;
iter = iter + 1;
if xr ~=0
ea = abs((xr -xrold)/xr)*100;
end
test = func(xl)*func(xr);
if test < 0
xu = xr;
elseif test > 0
xl = xr;
else ea = 0;
end
if ea <=es || iter >= maxit
fprintf('Root found at %10.7f with %4.7f iterations',xr, iter )
break
end
root = xr;
fx = func(xr);
end

Answers (2)

Walter Roberson
Walter Roberson on 24 Feb 2025
Suppose you have something like
syms x
f = x^3 - 2 * x + 5;
tiledlayout
nexttile
fplot(f, [-5 5])
nexttile
fplot(f, [-2 3])
and suppose you want to detect the minima that is between 0 and 2. Note that this minima is not at y = 0 -- it is somewhere near y = 5.
Then:
The way to detect this situation using the bisection method...
Is to give up on using the bisection method for this situation.
The bisection method is strictly for finding locations that cross y = 0.
Now, you could
df = diff(f)
df = 
and use the bisection method on df
location_of_critical_points = solve(df, x)
location_of_critical_points = 
value_at_critical_points = subs(f, x, location_of_critical_points)
value_at_critical_points = 
vpa(value_at_critical_points)
ans = 

Torsten
Torsten on 24 Feb 2025
Moved: Torsten on 24 Feb 2025
func = @(x)x.^2 - 3;
xl = 0;
xu = 3;
es = 1e-6;
maxit = 30;
[root,fx,ea,iter] = bisect(func,xl,xu,es,maxit)
Root found at 1.7320508 with 28.0000000 iterations
root = 1.7321
fx = 8.4537e-09
ea = 6.4524e-07
iter = 28
function [root,fx,ea,iter] = bisect(func,xl,xu,es,maxit,varargin)
% bisect: root location zeros; uses bisection method to find the root of
% the function
% input:
% func = name of function
% xl, xu = lower and upper guesses
% es = desired relative error (default = 0.0001%)
% maxit = maximum allowable iterations (default = 50)
% p1,p2,... = additional parameters used by func
% output:
% root= root estimate
% fx = function value at root estimate
% ea = approximate relative error(%)
% iter = number of iterations
if nargin < 3
error('at least 3 input arguments required')
end
fxl = func(xl);
fxu = func(xu);
test = fxl*fxu;
if test > 0
error('no sign change')
end
if nargin < 4 || isempty(es)
es = 0.0001;
end
if nargin < 5 || isempty(maxit)
maxit = 50;
end
iter = 0;
ea = 100;
while ea > es && iter < maxit
iter = iter + 1;
xm = (xl + xu)/2;
ea = abs(xu-xm)/max(abs(xu),1)*100;
fxm = func(xm);
test = fxl*fxm;
if test < 0
xu = xm;
fxu = fxm;
else
xl = xm;
fxl = fxm;
end
end
fprintf('Root found at %10.7f with %4.7f iterations',xm, iter )
root = xm;
fx = fxm;
end
  1 Comment
Torsten
Torsten on 24 Feb 2025
Edited: Torsten on 24 Feb 2025
It might also be a good idea not only to check the error in x, but also whether abs(f(x)) is small.
Your code iterates until the error in x is small - but maybe a solution with abs(f(x)) < tol is found much earlier.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!