253 lines
7.8 KiB
FortranFixed
253 lines
7.8 KiB
FortranFixed
subroutine surffunc(nyvars,yvars,nxvars,
|
|
& xvars,ndim,beta,dydxp,idowhat)
|
|
implicit none
|
|
!idowhat=0, value of the function only
|
|
!idowhat=1, derivative with respect to the independent variable x
|
|
!idowhat=2, derivative with respect to the parameters
|
|
integer nyvars,nxvars,ndim,idowhat
|
|
double precision yvars(nyvars),xvars(nxvars),
|
|
&beta(5),dydxp(nyvars,(nxvars+5))
|
|
!-------------------------------------------------------
|
|
double precision y0,a,b,c,x0,x,term,crit
|
|
parameter(crit=300.0d0)
|
|
a=beta(1)
|
|
b=beta(2)
|
|
c=beta(3)
|
|
x=xvars(1)
|
|
if(ndim.eq.3)then
|
|
term=dexp(-b*x)
|
|
if(idowhat.eq.0)yvars(1)=c+a*(1.0d0-term)
|
|
if(idowhat.eq.1)then
|
|
dydxp(1,1)=a*b*term
|
|
endif
|
|
if(idowhat.eq.2)then
|
|
dydxp(1,1)=1.0d0-term
|
|
dydxp(1,2)=a*x*term
|
|
dydxp(1,3)=1.0d0
|
|
endif
|
|
return
|
|
endif
|
|
if(ndim.eq.4)then
|
|
x0=beta(4)
|
|
if(idowhat.eq.0)yvars(1)=a*(1.0d0-b*x)*(x-x0)/(1.0d0+c*x)
|
|
if(idowhat.eq.1)then
|
|
dydxp(1,1)=a*(1.0d0-2.0d0*b*x-b*c*x*x+(b+c)*x0)/
|
|
&((1.0d0+c*x)*(1.0d0+c*x))
|
|
endif
|
|
if(idowhat.eq.2)then
|
|
dydxp(1,1)=(1.0d0-b*x)*(x-x0)/(1.0d0+c*x)
|
|
dydxp(1,2)=a*(1.0d0-x)*(x-x0)/(1.0d0+c*x)
|
|
dydxp(1,3)=-a*(1.0d0-b*x)*(x-x0)*x/((1.0d0+c*x)*(1.0d0+c*x))
|
|
dydxp(1,4)=-a*(1.0d0-b*x)/(1.0d0+c*x)
|
|
endif
|
|
return
|
|
endif
|
|
! if(ndim.eq.3)then
|
|
! yvars(1)=(1.0d0+a*x)/(b+c*x)
|
|
! if(idowhat.eq.0)return
|
|
! if(idowhat.eq.1)then
|
|
! dydxp(1,1)=(a-yvars(1)*c)/(b+c*x)
|
|
! return
|
|
! endif
|
|
! if(idowhat.eq.2)then
|
|
! dydxp(1,1)=x/(b+c*x)
|
|
! dydxp(1,2)=-yvars(1)/(b+c*x)
|
|
! dydxp(1,3)=-yvars(1)*dydxp(1,1)
|
|
! return
|
|
! endif
|
|
! endif
|
|
|
|
!A/Ci or A/PAR curves
|
|
x0=beta(4)
|
|
y0=beta(5)
|
|
if(idowhat.eq.0)then
|
|
if((-(x-x0)/b).lt.crit)then
|
|
term=dexp(-(x-x0)/b)
|
|
yvars(1)=y0+a*(1.0d0/(1.0d0+term))**c
|
|
else
|
|
term=dexp((x-x0)/b)
|
|
yvars(1)=y0+a*(term/(1.0d0+term))**c
|
|
endif
|
|
endif
|
|
if(idowhat.eq.1)then
|
|
if((-(x-x0)/b).lt.crit)then
|
|
term=dexp(-(x-x0)/b)
|
|
dydxp(1,1)=(a*c*term/b)*
|
|
& (1.0d0/(1.0d0+term))**(1.0d0+c)
|
|
else
|
|
term=(x-x0)/b
|
|
dydxp(1,1)=(a*c/b)*(dexp(term*c/(c+1.0d0))/
|
|
& (1.0d0+dexp(term)))**(c+1.0d0)
|
|
endif
|
|
endif
|
|
if(idowhat.eq.2)then
|
|
dydxp(1,5)=1.0d0
|
|
if((-(x-x0)/b).lt.crit)then
|
|
term=dexp(-(x-x0)/b)
|
|
dydxp(1,1)=(1.0d0/(1.0d0+term))**c
|
|
dydxp(1,4)=-(a*c*term/b)*
|
|
& (1.0d0/(1.0d0+term))**(1.0d0+c)
|
|
dydxp(1,2)=-(a*c*term*(x-x0)/(b*b))*
|
|
& (1.0d0/(1.0d0+term))**(1.0d0+c)
|
|
dydxp(1,3)=-(a*dlog(1.0d0+term))*
|
|
& (1.0d0/(1.0d0+term))**c
|
|
else
|
|
term=(x-x0)/b
|
|
dydxp(1,1)=(dexp(term)/(1.0d0+dexp(term)))**c
|
|
dydxp(1,4)=-(a*c/b)*(dexp(term*c/(c+1))/
|
|
& (1.0d0+dexp(term)))**(c+1.0d0)
|
|
dydxp(1,2)=-(a*c*(x-x0)/(b*b))*(dexp(term*c/
|
|
& (c+1.0d0))/(1.0d0+dexp(term)))**(1.0d0+c)
|
|
dydxp(1,3)=-a*(dlog(1.0d0+dexp(term))-term)*
|
|
& (dexp(term)/(1.0d0+dexp(term)))**c
|
|
endif
|
|
endif
|
|
return
|
|
end
|
|
!==========================================================
|
|
subroutine properties_surffunc(ndim,beta,root,der_root,fmax,
|
|
&yinter,der_yinter,agivenx,der_agivenx,funcval_agivenx,
|
|
&xmin,xmax,curvatmax,xcurvatmax)
|
|
implicit none
|
|
integer ndim
|
|
double precision beta(5),root,der_root,fmax,yinter,der_yinter,
|
|
&agivenx,der_agivenx,funcval_agivenx,xmin,xmax,curvatmax,xcurvatmax
|
|
double precision a,b,c,x0,y0,term,term1,term2,term3,step,
|
|
&deratx,der2atx,yvector(5),xvector(5),zvector(5)
|
|
|
|
a=beta(1)
|
|
b=beta(2)
|
|
c=beta(3)
|
|
|
|
if(ndim.eq.3)then
|
|
!y=c+a(1-exp(-bx))
|
|
root=-dlog(1.0d0+c/a)/b
|
|
der_root=a*b*dexp(-b*root)
|
|
fmax=c+a
|
|
yinter=c
|
|
der_yinter=a*b
|
|
funcval_agivenx=c+a*(1.0d0-dexp(-b*agivenx))
|
|
der_agivenx=a*b*dexp(-b*agivenx)
|
|
xcurvatmax=dlog(2*a*a*b*b)/(2.0d0*b)
|
|
! curvatmax=-a*b*b*dexp(-b*xcurvatmax)/
|
|
! &((1.0d0+a*a*b*b*dexp(-2.0d0*b*xcurvatmax))**1.5d0)
|
|
curvatmax=-b*0.3849d0
|
|
curvatmax=dabs(curvatmax)*1000.0d0
|
|
return
|
|
endif
|
|
|
|
if(ndim.eq.4)then
|
|
!y=a*(1-bx)*(x-x0)/(1+c*x)
|
|
!we ignore the other root
|
|
!dydxp(1,1)=a*(1.0d0-2.0d0*b*x-b*c*x*x+(b+c)*x0)/((1.0d0+c*x)*(1.0d0+c*x))
|
|
x0=beta(4)
|
|
root=x0
|
|
der_root=a*(1.0d0-2.0d0*b*root-b*c*root*root+(b+c)*x0)/
|
|
&((1.0d0+c*root)*(1.0d0+c*root))
|
|
term=(dsqrt((b+c)*(1.0d0+c*x0)/b)-1.0d0)/c
|
|
fmax=a*(1.0d0-b*term)*(term-x0)/(1.0d0+c*term)
|
|
yinter=-a*x0
|
|
der_yinter=a*(1.0d0+(b+c)*x0)
|
|
funcval_agivenx=a*(1.0d0-b*agivenx)*(agivenx-x0)/
|
|
&(1.0d0+c*agivenx)
|
|
der_agivenx=
|
|
&a*(1.0d0-2.0d0*b*agivenx-b*c*agivenx*agivenx+(b+c)*x0)/
|
|
&((1.0d0+c*agivenx)*(1.0d0+c*agivenx))
|
|
xcurvatmax=-9999.0d0
|
|
curvatmax=-9999.0d0
|
|
return
|
|
endif
|
|
! if(ndim.eq.3)then
|
|
!y=(1+a*x)/(b+c*x)
|
|
! root=-1.0d0/a
|
|
! der_root=a/(b-c/a)
|
|
! fmax=a/c
|
|
! yinter=1.0d0/b
|
|
! der_yinter=(a*b-c)/(b*b)
|
|
! return
|
|
! endif
|
|
x0=beta(4)
|
|
y0=beta(5)
|
|
if((-a/y0).gt.0.0d0)then
|
|
term=(-a/y0)**(1.0d0/c)-1.0d0
|
|
root=x0-b*dlog(term)
|
|
term=dexp(-(root-x0)/b)
|
|
der_root=(a*c*term/b)*(1.0d0/(1.0d0+term))**(1.0d0+c)
|
|
else
|
|
root=-9999.0d0
|
|
der_root=-9999.0d0
|
|
endif
|
|
fmax=a+y0
|
|
xvector(1)=0.0d0
|
|
call surffunc(1,yvector(1),1,xvector(1),ndim,beta,zvector(1),0)
|
|
yinter=yvector(1)
|
|
call surffunc(1,yvector(1),1,xvector(1),ndim,beta,zvector(1),1)
|
|
der_yinter=zvector(1)
|
|
xvector(1)=agivenx
|
|
call surffunc(1,yvector(1),1,xvector(1),ndim,beta,zvector(1),1)
|
|
der_agivenx=zvector(1)
|
|
call surffunc(1,yvector(1),1,xvector(1),ndim,beta,zvector(1),0)
|
|
funcval_agivenx=yvector(1)
|
|
|
|
curvatmax=-9999.0d0
|
|
xcurvatmax=-9999.0d0
|
|
step=(xmax-xmin)/1000.0d0
|
|
if(step.le.0.0d0)return
|
|
! do term=xmin,xmax,step
|
|
! call surffunc(1,term1,1,term,ndim,beta,deratx,1)
|
|
! term2=dexp(-(term-x0)/b)
|
|
! der2atx=-deratx/b+
|
|
! &(1.0d0+c)*deratx*deratx*((1.0d0+term2)**c)/(a*c)
|
|
! term3=dabs(der2atx/((1.0d0+deratx*deratx)**1.5d0))
|
|
! if(term3.gt.curvatmax)then
|
|
! curvatmax=term3
|
|
! xcurvatmax=term
|
|
! endif
|
|
! enddo
|
|
|
|
term=xmin
|
|
do while (term.le.xmax)
|
|
xvector(1)=term
|
|
call surffunc(1,yvector(1),1,xvector(1),ndim,beta,zvector(1),1)
|
|
term1=yvector(1)
|
|
deratx=zvector(1)
|
|
term2=dexp(-(term-x0)/b)
|
|
der2atx=-deratx/b+
|
|
&(1.0d0+c)*deratx*deratx*((1.0d0+term2)**c)/(a*c)
|
|
term3=dabs(der2atx/((1.0d0+deratx*deratx)**1.5d0))
|
|
if(term3.gt.curvatmax)then
|
|
curvatmax=term3
|
|
xcurvatmax=term
|
|
endif
|
|
term=term+step
|
|
enddo
|
|
|
|
if(dabs(xcurvatmax-xmin).le.step.or.
|
|
&dabs(xcurvatmax-xmax).le.step)then
|
|
curvatmax=-9999.0d0
|
|
xcurvatmax=-9999.0d0
|
|
else
|
|
curvatmax=dabs(curvatmax)*1000.0d0
|
|
endif
|
|
return
|
|
end
|
|
!==========================================================
|
|
subroutine indices_surffunc(ndim,beta,root,
|
|
& der_root,fmax)
|
|
implicit none
|
|
integer ndim
|
|
double precision beta(ndim),root,der_root,fmax
|
|
double precision a,b,c,x0,y0,term
|
|
a=beta(1)
|
|
b=beta(2)
|
|
c=beta(3)
|
|
x0=beta(4)
|
|
y0=beta(5)
|
|
term=(-a/y0)**(1.0d0/c)-1.0d0
|
|
root=x0-b*dlog(term)
|
|
term=dexp(-(root-x0)/b)
|
|
der_root=(a*c*term/b)*(1.0d0/(1.0d0+term))**(1.0d0+c)
|
|
fmax=a+y0
|
|
return
|
|
end
|