Rev 808 | Blame | Last modification | View Log | Download | RSS feed
cc a zero of the function f(x) is computed in the interval ax,bx .cc input..cc ax left endpoint of initial intervalc bx right endpoint of initial intervalc f function subprogram which evaluates f(x) for any x inc the interval ax,bxc tol desired length of the interval of uncertainty of thec final result ( .ge. 0.0d0)ccc output..cc zeroin abcissa approximating a zero of f in the interval ax,bxccc it is assumed that f(ax) and f(bx) have opposite signsc without a check. zeroin returns a zero x in the given intervalc ax,bx to within a tolerance 4*macheps*abs(x) + tol, where machepsc is the relative machine precision.cc this function subprogram is a slightly modified translation ofc the algol 60 procedure zero given in richard brent, algorithms forc minimization without derivatives, prentice - hall, inc. (1973).double precision function zeroin(ax,bx,f,tol,maxiter)implicit nonec argumentsdouble precision ax,bx,f,tolinteger maxiterc variablesinteger iterdouble precision a,b,c,d,e,eps,fa,fb,fc,tol1,xm,p,q,r,sc functionsdouble precision dabs,dsigncc compute eps, the relative machine precisionceps = 1.0d010 eps = eps/2.0d0tol1 = 1.0d0 + epsif (tol1 .gt. 1.0d0) go to 10cc initializationciter = 0a = axb = bxfa = f(a)fb = f(b)cc begin iteration stepc20 c = afc = fad = b - ae = d30 if (dabs(fc) .lt. dabs(fb)) thena = bb = cc = afa = fbfb = fcfc = faendifcc convergence testctol1 = 2.0d0*eps*dabs(b) + 0.5d0*tolxm = .5d0*(c - b)if (dabs(xm) .le. tol1) go to 90if (fb .eq. 0.0d0) go to 90if (iter .gt. maxiter) thenc non-convergence in 'maxiter' steps: "-" signalsiter = -itergo to 90endifcc is bisection necessarycif (dabs(e) .lt. tol1) go to 70if (dabs(fa) .le. dabs(fb)) go to 70cc is quadratic interpolation possiblecif (a .eq. c) thencc linear interpolationcs = fb/fap = 2.0d0*xm*sq = 1.0d0 - selsecc inverse quadratic interpolationcq = fa/fcr = fb/fcs = fb/fap = s*(2.0d0*xm*q*(q - r) - (b - a)*(r - 1.0d0))q = (q - 1.0d0)*(r - 1.0d0)*(s - 1.0d0)endifcc adjust signscif (p .gt. 0.0d0) q = -qp = dabs(p)cc is interpolation acceptablecif ((2.0d0*p) .ge. (3.0d0*xm*q - dabs(tol1*q))) go to 70if (p .ge. dabs(0.5d0*e*q)) go to 70e = dd = p/qgo to 80cc bisectionc70 d = xme = dcc complete iteration stepc80 a = bfa = fbif (dabs(d) .gt. tol1) thenb = b + delseb = b + dsign(tol1, xm)endiffb = f(b)iter = iter + 1if ((fb*(fc/dabs(fc))) .gt. 0.0d0) go to 20go to 30cc donec90 zeroin = bc further return tol = reached precision; maxiter = #{iterations}tol = dabs(xm+xm)maxiter = iterreturnend