HELP! Bisection method fails to found zero
Mostra commenti meno recenti
I tried to calculate the zero for the function
, but the zero isn't found in
. I have the same problem for other function like
.
I paste here my code (part of my function) :
TOLF = eps;
nit= 0; % number of iterations
m = xo(1)+0.5*diff(xo); % midpoint
while(abs(diff(xo))> p.Results.TOL*max(abs(xo)) && ...
abs(fun(m))>TOLF && nit<p.Results.NMAX) % stopping condition
if(fun(m)*fun(xo(1))<0)
xo(2)= m;
else
xo(1)= m;
end
nit=nit+1;
m = xo(1)+0.5*diff(xo);
end
3 Commenti
Walter Roberson
il 2 Apr 2019
Your second case, x^4, has the problem that it has no zero crossing. Bisection methods can only be used if you have the endpoints of an interval in which there is at least one zero crossing.
Jan
il 2 Apr 2019
@Agostino Dorano: Please post code, which we can run. What are the initial values of xo? What is p.Results.TOL and p.Results.NMAX? How do you define fun? What exactly do you observe? "zero isn't found" does not reveal the details.
Stephen23
il 4 Apr 2019
Agostino Dorano's "Answer" moved here:
% Function that calculates the zero of functions.
% This function implements the bisection algorithm to found zero of a function.
function [x, output] = fzer0(fun,xo,varargin)
% CONTROLLO NUMERI DI PARAMETRI
narginchk(2, 5);
% CREO L'INPUT PARSER
p = inputParser;
% CONTROLLO SUI TIPI DEI VALORI DI INGRESSO
addRequired (p, 'fun', @(x) assert(isa(x,'function_handle'),'First argoument must be a function handle of a in R function'));
addRequired (p, 'xo' , @(x) assert( isreal(x) && isnumeric(x) && isvector(x) && (length(x)==2) && all(isfinite(x)) ,'xo must be a vector of 2 real numbers')); % minore di zero perche deve avere proprio uno zero crossing
% SOSTITUIRE ADDPARAMETER CON ADDOPTIONAL PER RENDERE POSIZIONALE
addParameter(p,'TOL',eps,@(x) assert(isreal(x) && isnumeric(x) && all(isfinite(x)) && x>0 && x>=eps, 'TOL value must be a real value greather than 0 and eps and lower than inf'));
addParameter(p, 'NMAX', 500, @(x) assert(isreal(x) && isnumeric(x) && isfinite(x) && x>0 && floor(x)==x,'NMAX value must be a integer number greather than 0'));
addParameter(p, 'g','N', @(x) assert(ismember(x, {'Y','N'}),'g charater must be Y or N. See doc fzer0') );
parse (p, fun,xo, varargin{:});
xo = p.Results.xo; % array of two elemens that rapresents the interval extreme
% CONTROLLO DI APPLICABILITA'
if (fun(xo(1))*fun(xo(2))>=0)
error("zero or more zero in xo");
end
TOLF = eps;
nit= 0;
m = xo(1)+0.5*diff(xo);
%TOLX = p.Results.TOL*max(abs(xo)); sostituisco la sera del due aprile col
% codice riportato sotto===> dubbio: possiamo evitarlo? anzi, per il
% momento lascio tolx definito come : TOLX = p.Results.TOL*max(abs(xo));
% SET TOLX IN MANIERA SICURA
if(max(abs(xo))>realmin/p.Results.TOL)
TOLX = p.Results.TOL * max(abs(xo));
else
TOLX = realmin;
end
%%%%%%%% BISOGNA CONTROLLARE SE UNO DEI DUE ESTREMI è UNO ZERO => SE TALE
%%%%%%%% CONDIZIONE è VERA DEVO SETTARE LA VARIABILE DI RITORNO E TERMINARE
%%%%%%%% => ma tutto cio non è corretto
while(abs(diff(xo))>= TOLX && abs(fun(m))>=TOLF && nit<p.Results.NMAX)
if(fun(m)*fun(xo(1))<0)
xo(2)= m;
else
xo(1)= m;
end
nit=nit+1;
m = xo(1)+0.5*diff(xo);
% CONTROLLO DI ROBUSTEZZA PER IL SET DI TOLX
if(max(abs(xo))>realmin/p.Results.TOL)
TOLX = p.Results.TOL * max(abs(xo));
else
TOLX = realmin;
end
end
if(abs(diff(xo))> p.Results.TOL*max(abs(xo)) && abs(fun(m))>TOLF && nit==p.Results.NMAX)
warning("limit reached... calculation stopped!");
end
% return var
nargoutchk(0,2);
x = m;
if (nargout ==2 )
output.fx = fun(x);
output.niter = nit;
end
end
sorry for the late reply. I paste my complete code here. I want ask you also if to utilize InputParser is a good method to validate inputs for my function (better in performance(execution time) than nargin + if/ switch or exist) .
For "zero not found " i paste you the result of mine program comparated with fzero of matlab. them looks like pretty different . Thanks a lot.
>> fzer0(@(x) x^3, [-2 1]) % this is my function
ans =
3.814697265625000e-06
>> fzero(@(x) x^3, [-2 1]) % default matlab fzero
ans =
1.001465536366818e-16
% both functions were calculted with tolerance equal to eps
Risposta accettata
Più risposte (1)
Agostino Dorano
il 4 Apr 2019
1 Commento
Walter Roberson
il 4 Apr 2019
If your code must be as efficient as possible, then No, using addRequired and related routines is not as efficient as you could possibly get. They involve multiple function calls. The calls do not take long, but it is more efficient at execution time to "hard code" the work to be done rather than to call a function to do the work. You can probably save a good third of a microsecond of execution time by doing the checks yourself.
Categorie
Scopri di più su Live Scripts and Functions in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!