1
function derivative(fun,xi,hi,idiri,xmini,xmaxi,erroro)
2
c returns the derivative of f
4
c fun (INPUT)= function to differentiate
5
c xi (INPUT)= point where to compute the derivative
6
c hi (INPUT)= initial stepsize
7
c idiri (INPUT)= type of derivative (see below)
8
c xmini (INPUT)= lower bound in x
9
c xmaxi (INPUT)= upper bound in x
10
c error (OUTPUT)= estimated error
12
c idiri =-1 --> right derivative
13
c idiri = 0 --> both-sides derivative
14
c idiri = 1 --> left derivative
15
c idiri = 2 --> higher-order both-sides left derivative
17
real*8 derivative,fun,xi,hi,xmini,xmaxi,erroro
20
integer idir,i,j,itn,jmax
21
parameter(itn=2,jmax=2)
22
c itn = 2 guarantees a fast code. itns >> 2 gives more precise
23
c results in extreme configurations, but slows the code down
25
real*8 x,h,hh,error,con,big,dd,
26
&xmin,xmax,tiny,res(0:itn,jmax),er(0:itn)
27
parameter(con=3d0,big=1d40)
37
write(*,*)'Error #1 in function derivative'
40
if(idir.lt.-1.or.idir.gt.2)then
41
write(*,*)'Error #2 in function derivative',idir
45
write(*,*)'Error #3 in function derivative',x,xmin,xmax
48
c Set the derivative equal to zero and error equal to one if outside range
49
if(x.lt.xmin.or.x.gt.xmax)then
54
c If close to borders of range, use left or right first-order derivative;
55
c may include higher orders if implemented from the left or right only
56
if(x.le.(xmin+tiny))then
59
elseif(x.ge.(xmax-tiny))then
64
h=min(h,min(xmax-x,x-xmin))
71
res(i,j)=(fun(x+hh)-fun(x-hh))/(2d0*hh)
72
elseif(idir.eq.-1)then
73
res(i,j)=(fun(x+hh)-fun(x))/hh
75
res(i,j)=(fun(x)-fun(x-hh))/hh
77
c second-order formula: yet higher-order formulae exist
78
c but they require too many evaluations of f, which slows
79
c the code down quite significantly
80
res(i,j)=(fun(x-2*hh)-8*fun(x-hh)
81
& -fun(x+2*hh)+8*fun(x+hh))/(12d0*hh)
83
if(j.lt.jmax)hh=hh/con
85
er(i)=abs(abs(res(i,1))-abs(res(i,2)))/
86
& max(abs(res(i,1)),abs(res(i,2)))
87
if(er(i).lt.error.and.er(i).ne.0d0)then
89
dd=(res(i,1)+res(i,2))/2d0
93
erroro=error*2*abs(dd)