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

2 vues (au cours des 30 derniers jours)
Iris
Iris le 23 Fév 2025
Modifié(e) : Torsten le 24 Fév 2025
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

Réponses (2)

Walter Roberson
Walter Roberson le 24 Fév 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 le 24 Fév 2025
Déplacé(e) : Torsten le 24 Fév 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 commentaire
Torsten
Torsten le 24 Fév 2025
Modifié(e) : Torsten le 24 Fév 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.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by