Files
piscal/dataassim/math/optimization/phenofit.f
T
2016-02-03 18:52:05 +00:00

498 lines
17 KiB
FortranFixed

subroutine phenofit(nphenocycl0,iphenodowhat0,phenocyclmark,
&ntotpoints,phenoy,phenox,y0,a1,b1,c1,x01,a2,b2,c2,x02,amin,amax,
&bmin,bmax,cmin,cmax,y0min,y0max,x01min,x01max,x02min,x02max,ndim,
&beta,phenoy0,abcx,predphenoy,predphenox,sumsquare)
implicit none
integer nphenocycl0,iphenodowhat0(nphenocycl0),ntotpoints
double precision phenocyclmark(nphenocycl0),phenoy(ntotpoints),
&phenox(ntotpoints),y0,a1,b1,c1,x01,a2,b2,c2,x02,amin,amax,bmin,
&bmax,cmin,cmax,y0min,y0max,x01min,x01max,x02min,x02max,phenoy0,
&abcx(nphenocycl0,8),predphenoy(ntotpoints),predphenox(ntotpoints),
&sumsquare
!nphenocycl: the number of individual cycle units
!iphenodowhat: an index specifying what mathematical function to use for each individual cycle unit
!iphenodowhat= 1 - 4: double function cycle (paired sigmoid functions)
! =1: all parameters, 8 params
! =2: c1 and c2 set 1, 6 params
! =3: c1=c2=1, a1=a2, 5 params
! =4: a1=a2, 7 params
!iphenodowhat= 5 - 6: single function cycle (a2, b2, c2 and x02 are not used)
! =5: a1, b1, c1, x01. 4 parameters
! =6: a1, b1, x01. 3 parameters (c1 is set to be 1)
!
!ntotpoints: the total number of points in all cycle units
!phenoy: the y variable
!phenox: the x variable
!y0,a1,b1,c1,x01,a2,b2,c2,x02,amin,amax,bmin,bmax,cmin,cmax,y0min,y0max,x01min,x01max,x02min,x02max:
! - initial guesses and their bounds
!ndim: the total number of parameters estimated
!phenoy0: the estimated y0
!abcx: The parameters estimated for each cycle unit. (-0.9999 indicating not used)
! abcx(i,1)=a1
! abcx(i,2)=b1
! abcx(i,3)=c1
! abcx(i,4)=x01
! abcx(i,5)=a2
! abcx(i,6)=b2
! abcx(i,7)=c2
! abcx(i,8)=x02
!predphenoy: the predicted y variable for each phenox
!predphenox: the predicted x variable in case orthorgonal regression is used.
integer iderivative,INFO,j,ndim
double precision beta(nphenocycl0*8+1),betamin(nphenocycl0*8+1),
&betamax(nphenocycl0*8+1),weitphenox(ntotpoints),
&phenoxmin(ntotpoints),phenoxmax(ntotpoints),weitphenoy(ntotpoints)
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer nphenocycl,iphenodowhat(100)
COMMON /phenocom/nphenocycl,iphenodowhat
save /phenocom/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
nphenocycl=nphenocycl0
do j=1,nphenocycl
iphenodowhat(j)=iphenodowhat0(j)
enddo
call phenoparams_init(nphenocycl,iphenodowhat,phenocyclmark,
&y0,a1,b1,c1,x01,a2,b2,c2,x02,amin,amax,bmin,bmax,cmin,cmax,y0min,
&y0max,x01min,x01max,x02min,x02max,beta,betamin,betamax,ndim)
iderivative=1
INFO=0
!INFO =0, ordinary distance regression
!INFO =1, explicit orthogonal distance regression with shortest distance within iteration
!INFO =2, explicit orthogonal distance regression with x positions as parameters
do j=1,ntotpoints
weitphenox(j)=1.0d0
phenoxmin(j)=phenox(j)-20.0d0
phenoxmax(j)=phenox(j)+20.0d0
weitphenoy(j)=1.0d0
enddo
call GenericRegres(ntotpoints,1,phenoy,1,phenox,weitphenoy,
&weitphenox,ndim,beta,betamin,betamax,phenoxmin,phenoxmax,
&iderivative,INFO,predphenoy,predphenox,sumsquare)
phenoy0=beta(1)
call phenoparams_alloc(nphenocycl,iphenodowhat,beta,abcx)
return
end
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
subroutine surffunc(nyvars,yvars,nxvars,
& xvars,ndim,beta,dydxp,idowhat)
implicit none
!idowhat=0, value of the function only
! =1, derivative with respect to the independent variable x and value of the function
! =2, derivative with respect to the parameters and value of the function
integer nyvars,nxvars,ndim,idowhat
double precision yvars(nyvars),xvars(nxvars),
& beta(ndim),dydxp(nyvars,(nxvars+ndim))
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer nphenocycl,iphenodowhat(100)
COMMON /phenocom/nphenocycl,iphenodowhat
save /phenocom/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
integer j,NParam,i
double precision y0,a1,b1,c1,x01,a2,b2,c2,x02,
&abcx(1:nphenocycl,1:8),twoexpfunc,sigmoidfunc,grad(10)
y0=beta(1)
call phenoparams_alloc(nphenocycl,iphenodowhat,beta,
&abcx(1:nphenocycl,1:8))
! write(*,*)y0,ndim
! do j=1,nphenocycl
! write(*,330)(abcx(j,i),i=1,8)
! enddo
!330 format(8(f15.6))
! pause
yvars(1)=y0
do j=1,nphenocycl
a1=abcx(j,1)
b1=abcx(j,2)
c1=abcx(j,3)
x01=abcx(j,4)
if(iphenodowhat(j).le.4)then
a2=abcx(j,5)
b2=abcx(j,6)
c2=abcx(j,7)
x02=abcx(j,8)
yvars(1)=yvars(1)+
&twoexpfunc(0.0d0,a1,b1,c1,x01,a2,b2,c2,x02,xvars(1))
else
yvars(1)=yvars(1)+sigmoidfunc(0.0d0,a1,b1,c1,x01,xvars(1))
endif
enddo
if(idowhat.eq.1)then
dydxp(1,1)=0.0d0
do j=1,nphenocycl
a1=abcx(j,1)
b1=abcx(j,2)
c1=abcx(j,3)
x01=abcx(j,4)
if(iphenodowhat(j).le.4)then
a2=abcx(j,5)
b2=abcx(j,6)
c2=abcx(j,7)
x02=abcx(j,8)
call gradtwoexp(0.0d0,a1,b1,c1,x01,
&a2,b2,c2,x02,xvars(1),grad)
else
call gradsigmoidfunc(0.0d0,a1,b1,c1,x01,xvars(1),grad)
endif
dydxp(1,1)=dydxp(1,1)+grad(6)
enddo
endif
if(idowhat.eq.2)then
NParam=1
dydxp(1,1)=1.0d0
do j=1,nphenocycl
a1=abcx(j,1)
b1=abcx(j,2)
c1=abcx(j,3)
x01=abcx(j,4)
if(iphenodowhat(j).le.4)then
a2=abcx(j,5)
b2=abcx(j,6)
c2=abcx(j,7)
x02=abcx(j,8)
call gradtwoexp(0.0d0,a1,b1,c1,x01,
&a2,b2,c2,x02,xvars(1),grad)
else
call gradsigmoidfunc(0.0d0,a1,b1,c1,x01,xvars(1),grad)
endif
! a1<->grad(1)
! b1<->grad(2)
! c1<->grad(3)
! x01<->grad(4)
! y0<->grad(5)
! x<->grad(6)
! a2<->grad(7)
! b2<->grad(8)
! c2<->grad(9)
! x02<->grad(10)
if(iphenodowhat(j).eq.1)then
! all parameters in the two exp functions
dydxp(1,NParam+1)=grad(1)
dydxp(1,NParam+2)=grad(2)
dydxp(1,NParam+3)=grad(3)
dydxp(1,NParam+4)=grad(4)
dydxp(1,NParam+5)=grad(7)
dydxp(1,NParam+6)=grad(8)
dydxp(1,NParam+7)=grad(9)
dydxp(1,NParam+8)=grad(10)
NParam=NParam+8
endif
if(iphenodowhat(j).eq.2)then
! c1=c2=1.0
dydxp(1,NParam+1)=grad(1)
dydxp(1,NParam+2)=grad(2)
dydxp(1,NParam+3)=grad(4)
dydxp(1,NParam+4)=grad(7)
dydxp(1,NParam+5)=grad(8)
dydxp(1,NParam+6)=grad(10)
NParam=NParam+6
endif
if(iphenodowhat(j).eq.3)then
! c1=c2=1.0
! a1=a2
dydxp(1,NParam+1)=grad(1)+grad(7)
dydxp(1,NParam+2)=grad(2)
dydxp(1,NParam+3)=grad(4)
dydxp(1,NParam+4)=grad(8)
dydxp(1,NParam+5)=grad(10)
NParam=NParam+5
endif
if(iphenodowhat(j).eq.4)then
! a1=a2
dydxp(1,NParam+1)=grad(1)+grad(7)
dydxp(1,NParam+2)=grad(2)
dydxp(1,NParam+3)=grad(3)
dydxp(1,NParam+4)=grad(4)
dydxp(1,NParam+5)=grad(8)
dydxp(1,NParam+6)=grad(9)
dydxp(1,NParam+7)=grad(10)
NParam=NParam+7
endif
if(iphenodowhat(j).eq.5)then
! single function, 4 parameters
dydxp(1,NParam+1)=grad(1)
dydxp(1,NParam+2)=grad(2)
dydxp(1,NParam+3)=grad(3)
dydxp(1,NParam+4)=grad(4)
NParam=NParam+4
endif
if(iphenodowhat(j).eq.6)then
! single function, 3 parameters, c=1
dydxp(1,NParam+1)=grad(1)
dydxp(1,NParam+2)=grad(2)
dydxp(1,NParam+3)=grad(4)
NParam=NParam+3
endif
enddo
endif
return
end
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
subroutine phenoparams_init(nphenocycl,iphenodowhat,phenocyclmark,
&y0,a1,b1,c1,x01,a2,b2,c2,x02,amin,amax,bmin,bmax,cmin,cmax,y0min,
&y0max,x01min,x01max,x02min,x02max,BETA,BETAmin,BETAmax,NParam)
implicit none
integer nphenocycl,iphenodowhat(nphenocycl),NParam,i
double precision y0,a1,b1,c1,x01,a2,b2,c2,x02,amin,amax,bmin,bmax,
&cmin,cmax,x01min,x01max,x02min,x02max,y0min,y0max,
&BETA(nphenocycl*8+1),BETAmin(nphenocycl*8+1),
&BETAmax(nphenocycl*8+1),phenocyclmark(nphenocycl)
!number of parameters for each phenocycl
!iphenodowhat= 1 - 4: double function cycle
! =1: all parameters, 8 params
! =2: c1 and c2 set 1, 6 params
! =3: c1=c2=1, a1=a2, 5 params
! =4: a1=a2, 7 params
!
!iphenodowhat= 5 - 6: single function cycle
! =5: a, b, c, x0. 4 parameters
! =6: a, b, x0. c is set to be 1
!
! abcx(i,1)=a1
! abcx(i,2)=b1
! abcx(i,3)=c1
! abcx(i,4)=x01
! abcx(i,5)=a2
! abcx(i,6)=b2
! abcx(i,7)=c2
! abcx(i,8)=x02
NParam=1
BETA(1)=y0
BETAmin(1)=y0min
BETAmax(1)=y0max
do i=1,nphenocycl
if(iphenodowhat(i).eq.1)then
! all parameters in the two exp functions
BETA(NParam+1)=a1
BETA(NParam+2)=b1
BETA(NParam+3)=c1
BETA(NParam+4)=phenocyclmark(i)+x01
BETA(NParam+5)=a2
BETA(NParam+6)=b2
BETA(NParam+7)=c2
BETA(NParam+8)=phenocyclmark(i)+x02
BETAmin(NParam+1)=amin
BETAmax(NParam+1)=amax
BETAmin(NParam+2)=bmin
BETAmax(NParam+2)=bmax
BETAmin(NParam+3)=cmin
BETAmax(NParam+3)=cmax
BETAmin(NParam+4)=phenocyclmark(i)+x01min
BETAmax(NParam+4)=phenocyclmark(i)+x01max
BETAmin(NParam+5)=BETAmin(NParam+1)
BETAmax(NParam+5)=BETAmax(NParam+1)
BETAmin(NParam+6)=BETAmin(NParam+2)
BETAmax(NParam+6)=BETAmax(NParam+2)
BETAmin(NParam+7)=BETAmin(NParam+3)
BETAmax(NParam+7)=BETAmax(NParam+3)
BETAmin(NParam+8)=phenocyclmark(i)+x02min
BETAmax(NParam+8)=phenocyclmark(i)+x02max
NParam=NParam+8
endif
if(iphenodowhat(i).eq.2)then
! c1=c2=1.0
BETA(NParam+1)=a1
BETA(NParam+2)=b1
BETA(NParam+3)=phenocyclmark(i)+x01
BETA(NParam+4)=a2
BETA(NParam+5)=b2
BETA(NParam+6)=phenocyclmark(i)+x02
BETAmin(NParam+1)=amin
BETAmax(NParam+1)=amax
BETAmin(NParam+2)=bmin
BETAmax(NParam+2)=bmax
BETAmin(NParam+3)=phenocyclmark(i)+x01min
BETAmax(NParam+3)=phenocyclmark(i)+x01max
BETAmin(NParam+4)=BETAmin(NParam+1)
BETAmax(NParam+4)=BETAmax(NParam+1)
BETAmin(NParam+5)=BETAmin(NParam+2)
BETAmax(NParam+5)=BETAmax(NParam+2)
BETAmin(NParam+6)=phenocyclmark(i)+x01min
BETAmax(NParam+6)=phenocyclmark(i)+x02max
NParam=NParam+6
endif
if(iphenodowhat(i).eq.3)then
! c1=c2=1.0
! a1=a2
BETA(NParam+1)=a1
BETA(NParam+2)=b1
BETA(NParam+3)=phenocyclmark(i)+x01
BETA(NParam+4)=b2
BETA(NParam+5)=phenocyclmark(i)+x02
BETAmin(NParam+1)=amin
BETAmax(NParam+1)=amax
BETAmin(NParam+2)=bmin
BETAmax(NParam+2)=bmax
BETAmin(NParam+3)=phenocyclmark(i)+x01min
BETAmax(NParam+3)=phenocyclmark(i)+x01max
BETAmin(NParam+4)=BETAmin(NParam+2)
BETAmax(NParam+4)=BETAmax(NParam+2)
BETAmin(NParam+5)=phenocyclmark(i)+x02min
BETAmax(NParam+5)=phenocyclmark(i)+x02max
NParam=NParam+5
endif
if(iphenodowhat(i).eq.4)then
! a1=a2
BETA(NParam+1)=a1
BETA(NParam+2)=b1
BETA(NParam+3)=c1
BETA(NParam+4)=phenocyclmark(i)+x01
BETA(NParam+5)=b2
BETA(NParam+6)=c2
BETA(NParam+7)=phenocyclmark(i)+x02
BETAmin(NParam+1)=amin
BETAmax(NParam+1)=amax
BETAmin(NParam+2)=bmin
BETAmax(NParam+2)=bmax
BETAmin(NParam+3)=cmin
BETAmax(NParam+3)=cmax
BETAmin(NParam+4)=phenocyclmark(i)+x01min
BETAmax(NParam+4)=phenocyclmark(i)+x01max
BETAmin(NParam+5)=BETAmin(NParam+2)
BETAmax(NParam+5)=BETAmax(NParam+2)
BETAmin(NParam+6)=BETAmin(NParam+3)
BETAmax(NParam+6)=BETAmax(NParam+3)
BETAmin(NParam+7)=phenocyclmark(i)+x02min
BETAmax(NParam+7)=phenocyclmark(i)+x02max
NParam=NParam+7
endif
if(iphenodowhat(i).eq.5)then
! single function, 4 parameters
BETA(NParam+1)=a1
BETA(NParam+2)=b1
BETA(NParam+3)=c1
BETA(NParam+4)=phenocyclmark(i)+x01
BETAmin(NParam+1)=amin
BETAmax(NParam+1)=amax
BETAmin(NParam+2)=bmin
BETAmax(NParam+2)=bmax
BETAmin(NParam+3)=cmin
BETAmax(NParam+3)=cmax
BETAmin(NParam+4)=phenocyclmark(i)+x01min
BETAmax(NParam+4)=phenocyclmark(i)+x01max
NParam=NParam+4
endif
if(iphenodowhat(i).eq.6)then
! single function, 3 parameters, c=1
BETA(NParam+1)=a1
BETA(NParam+2)=b1
BETA(NParam+3)=phenocyclmark(i)+x01
BETAmin(NParam+1)=amin
BETAmax(NParam+1)=amax
BETAmin(NParam+2)=bmin
BETAmax(NParam+2)=bmax
BETAmin(NParam+3)=phenocyclmark(i)+x01min
BETAmax(NParam+3)=phenocyclmark(i)+x01max
NParam=NParam+3
endif
enddo
return
end
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
subroutine phenoparams_alloc(nphenocycl,iphenodowhat,BETA,abcx)
implicit none
integer nphenocycl,iphenodowhat(nphenocycl)
double precision BETA(nphenocycl*8+1),abcx(nphenocycl,8)
integer NParam,i
!number of parameters for each phenocycl
!iphenodowhat= 1 - 4: double function cycle
! =1: all parameters, 8 params
! =2: c1 and c2 set 1, 6 params
! =3: c1=c2=1, a1=a2, 5 params
! =4: a1=a2, 7 params
!
!iphenodowhat= 5 - 6: single function cycle
! =5: a, b, c, x0. 4 parameters
! =6: a, b, x0. c is set to be 1
! abcx(i,1)=a1
! abcx(i,2)=b1
! abcx(i,3)=c1
! abcx(i,4)=x01
! abcx(i,5)=a2
! abcx(i,6)=b2
! abcx(i,7)=c2
! abcx(i,8)=x02
NParam=1
do i=1,nphenocycl
if(iphenodowhat(i).eq.1)then
! all parameters in the two exp functions
abcx(i,1)=BETA(NParam+1)
abcx(i,2)=BETA(NParam+2)
abcx(i,3)=BETA(NParam+3)
abcx(i,4)=BETA(NParam+4)
abcx(i,5)=BETA(NParam+5)
abcx(i,6)=BETA(NParam+6)
abcx(i,7)=BETA(NParam+7)
abcx(i,8)=BETA(NParam+8)
NParam=NParam+8
endif
if(iphenodowhat(i).eq.2)then
! c1=c2=1.0
abcx(i,1)=BETA(NParam+1)
abcx(i,2)=BETA(NParam+2)
abcx(i,3)=1.0d0
abcx(i,4)=BETA(NParam+3)
abcx(i,5)=BETA(NParam+4)
abcx(i,6)=BETA(NParam+5)
abcx(i,7)=1.0d0
abcx(i,8)=BETA(NParam+6)
NParam=NParam+6
endif
if(iphenodowhat(i).eq.3)then
! c1=c2=1.0
! a1=a2
abcx(i,1)=BETA(NParam+1)
abcx(i,2)=BETA(NParam+2)
abcx(i,3)=1.0d0
abcx(i,4)=BETA(NParam+3)
abcx(i,5)=abcx(i,1)
abcx(i,6)=BETA(NParam+4)
abcx(i,7)=1.0d0
abcx(i,8)=BETA(NParam+5)
NParam=NParam+5
endif
if(iphenodowhat(i).eq.4)then
! a1=a2
abcx(i,1)=BETA(NParam+1)
abcx(i,2)=BETA(NParam+2)
abcx(i,3)=BETA(NParam+3)
abcx(i,4)=BETA(NParam+4)
abcx(i,5)=abcx(i,1)
abcx(i,6)=BETA(NParam+5)
abcx(i,7)=BETA(NParam+6)
abcx(i,8)=BETA(NParam+7)
NParam=NParam+7
endif
if(iphenodowhat(i).eq.5)then
! single function, 4 parameters
abcx(i,1)=BETA(NParam+1)
abcx(i,2)=BETA(NParam+2)
abcx(i,3)=BETA(NParam+3)
abcx(i,4)=BETA(NParam+4)
abcx(i,5)=0.0d0
abcx(i,6)=-0.9999d0
abcx(i,7)=0.0d0
abcx(i,8)=-0.9999d0
NParam=NParam+4
endif
if(iphenodowhat(i).eq.6)then
! single function, 3 parameters
abcx(i,1)=BETA(NParam+1)
abcx(i,2)=BETA(NParam+2)
abcx(i,3)=1.0d0
abcx(i,4)=BETA(NParam+3)
abcx(i,5)=0.0d0
abcx(i,6)=-0.9999d0
abcx(i,7)=0.0d0
abcx(i,8)=-0.9999d0
NParam=NParam+3
endif
enddo
return
end
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$