| (16) |
| (17) |
。
function rtsafe(funcd,x1,x2,xacc)
implicit NONE
Integer MAXIT
Real rtsafe,x1,x2,xacc
external funcd
Parameter (MAXIT=100) !Maximum allowed number of iterations.
! Using a combination of Newton-Raphson and bisection, find the root of a
! function bracketed between x1 and x2. The root, returned as the
! function value 'rtsafe', will be refined until its accuracy is known
! within +-'xacc'. 'funcd' is a user-supplied subroutine which returns
! both the function value and the first derivative of the function.
Integer j
Real df,dx,dxold,f,fh,fl,temp,xh,xl
call funcd(x1,fl,df)
call funcd(x2,fh,df)
if((fl.gt.0..and.fh.gt.0.).or.(fl.lt.0..and.fh.lt.0.))
* pause 'root must be bracketed in rtsafe'
if(fl.eq.0.)then
rtsafe=x1
return
else if(fh.eq.0.)then
rtsafe=x2
return
else if(fl.lt.0.)then !Orient the search so that f(x1)<0.
xl=x1
xh=x2
else
xh=x1
xl=x2
endif
rtsafe=.5*(x1+x2) !Initialize the guess for root,
dxold=abs(x2-x1) !the "stepsize before last,"
dx=dxold !and the last step.
call funcd(rtsafe,f,df)
do j=1,MAXIT !Loop over allowed iterations.
if(((rtsafe-xh)*df-f)*((rtsafe-xl)*df-f).ge.0. !Bisect if Newton out of
* .or. abs(2.*f).gt.abs(dxold*df) ) then !range, or not decreasing
dxold=dx !fast enough.
dx=0.5*(xh-xl)
rtsafe=xl+dx
if(xl.eq.rtsafe)return !Change in root is negligible.
else !Newton step acceptable. Take it.
dxold=dx
dx=f/df
temp=rtsafe
rtsafe=rtsafe-dx
if(temp.eq.rtsafe)return
endif
if(abs(dx).lt.xacc) return !Convergence criterion.
call funcd(rtsafe,f,df) !The one new function evaluation per
if(f.lt.0.) then !iteration.
xl=rtsafe !Maintain the bracket on the root.
else
xh=rtsafe
endif
end do
pause 'rtsafe exceeding maximum iterations'
return
END
Chapter 7 初期値問題