Seeks the root of a function F(X) in an interval [A,B].
The interval [A,B] must be a change of sign interval for F.
That is, F(A) and F(B) must be of opposite signs. Then
assuming that F is continuous implies the existence of at least
one value C between A and B for which F(C) = 0.
The location of the zero is determined to within an accuracy
of 6 * MACHEPS * abs ( C ) + 2 * T.
Thanks to Thomas Secretin for pointing out a transcription error in the
setting of the value of P, 11 February 2013.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed
arrows point from an interface to procedures which implement that interface.
This could include the module procedures in a generic interface or the
implementation in a submodule of an interface in a parent module.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed
arrows point from an interface to procedures which implement that interface.
This could include the module procedures in a generic interface or the
implementation in a submodule of an interface in a parent module.
Source Code
function zero(obj,a,b,machep,t)!! Seeks the root of a function F(X) in an interval [A,B].!!!! The interval [A,B] must be a change of sign interval for F.!! That is, F(A) and F(B) must be of opposite signs. Then!! assuming that F is continuous implies the existence of at least!! one value C between A and B for which F(C) = 0.!!!! The location of the zero is determined to within an accuracy!! of 6 * MACHEPS * abs ( C ) + 2 * T.!!!! Thanks to Thomas Secretin for pointing out a transcription error in the!! setting of the value of P, 11 February 2013.!!!! Modified: 11 February 2013!!!! Author:!!!! - Original FORTRAN77 version by Richard Brent.!! - FORTRAN90 version by John Burkardt.!!!! Reference:!!!! - Richard Brent,!! - Algorithms for Minimization Without Derivatives,!! - Dover, 2002,!! - ISBN: 0-486-41998-3,!! - LC: QA402.5.B74.class(brent_t),intent(in)::obj!! external object with the user-supplied !! subroutine which calculates the functions.real(dp),intent(in)::a,b!! the endpoints of the change of sign intervalreal(dp),intent(in)::machep!! an estimate for the relative machine precision.real(dp),intent(in)::t!! a positive error tolerancereal(dp)::zero!! the estimated value of a zero of the function Freal(dp)::creal(dp)::dreal(dp)::ereal(dp)::fareal(dp)::fbreal(dp)::fcreal(dp)::mreal(dp)::preal(dp)::qreal(dp)::rreal(dp)::sreal(dp)::sareal(dp)::sbreal(dp)::tol! Make local copies of A and B.sa=asb=bfa=obj%f(sa)fb=obj%f(sb)c=safc=fae=sb-sad=edo if(abs(fc)<abs(fb))then sa=sbsb=cc=safa=fbfb=fcfc=faendiftol=2.0_dp*machep*abs(sb)+tm=0.5_dp*(c-sb)if(abs(m)<=tol.or.fb==0.0_dp)then exit endif if(abs(e)<tol.or.abs(fa)<=abs(fb))then e=md=eelse s=fb/faif(sa==c)then p=2.0_dp*m*sq=1.0_dp-selse q=fa/fcr=fb/fcp=s*(2.0_dp*m*q*(q-r)-(sb-sa)*(r-1.0_dp))q=(q-1.0_dp)*(r-1.0_dp)*(s-1.0_dp)endif if(0.0_dp<p)thenq=-qelsep=-pendifs=ee=dif(2.0_dp*p<3.0_dp*m*q-abs(tol*q).and.&p<abs(0.5_dp*s*q))thend=p/qelsee=md=eendif endifsa=sbfa=fbif(tol<abs(d))thensb=sb+delse if(0.0_dp<m)thensb=sb+tolelsesb=sb-tolendiffb=obj%f(sb)if((0.0_dp<fb.and.0.0_dp<fc).or.&(fb<=0.0_dp.and.fc<=0.0_dp))thenc=safc=fae=sb-sad=eendif enddozero=sbend function zero