New changes from l2g
w
This commit is contained in:
+289
-116
@@ -172,10 +172,12 @@
|
||||
implicit none
|
||||
include '../testarea/LeafGasParams.h'
|
||||
include '../testarea/LeafGasHybridFit.h'
|
||||
integer i,ndim,k,j,iderivative,iwrong,jnon
|
||||
integer i,ndim,k,j,iderivative,iwrong,jnon,n,icompete,isame,i2,
|
||||
&isitnaninf,nave
|
||||
double precision beta(20),sumsquare0,beta0(20),sumsquarecp,
|
||||
&betacp(20),ftol,xtol,shortx(maxobs,4),shorty(maxobs,2),ran2,
|
||||
&ftol_relax
|
||||
&betacp(20),ftol,xtol,shortx(maxobs,10),shorty(maxobs,5),
|
||||
&ftol_relax,term1,term2,ran2,history(2000,25),discount,upper,lower,
|
||||
&f1dim_UnivPhotoFit,ff_pikaia
|
||||
parameter(ftol=1.0d-7,xtol=1.0d-7)
|
||||
external funkmin_UnivPhotoFit,f1dim_UnivPhotoFit,
|
||||
&FCN_UnivPhotoFit,ff_pikaia
|
||||
@@ -193,113 +195,312 @@
|
||||
enddo
|
||||
isitbounded=1
|
||||
call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
do i=1,ndim
|
||||
beta0(i)=beta(i)
|
||||
enddo
|
||||
sumsquare0=sumsquare
|
||||
ftol_relax=ftol
|
||||
k=0
|
||||
if(subbestsumsquare(Currentilimittype).gt.1.0d+9)then
|
||||
jnon=0
|
||||
ftol_relax=ftol*100.0d0
|
||||
endif
|
||||
30 call nongradopt(ndim,funkmin_UnivPhotoFit,f1dim_UnivPhotoFit,
|
||||
&beta,betamin,betamax,ftol_relax,sumsquare)
|
||||
call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
if((sumsquare+1.0d0).eq.sumsquare.or.sumsquare.gt.sumsquare0)then
|
||||
do i=1,ndim
|
||||
beta(i)=beta0(i)
|
||||
enddo
|
||||
sumsquare=sumsquare0
|
||||
else
|
||||
if((sumsquare0-sumsquare).gt.ftol_relax)then
|
||||
!reset the counter for arriving at a better minimum
|
||||
k=0
|
||||
else
|
||||
!if the same minimum is found, increment the counter
|
||||
k=k+1
|
||||
endif
|
||||
!global search
|
||||
do i=1,ndim
|
||||
beta0(i)=beta(i)
|
||||
history(1,i)=beta(i)
|
||||
enddo
|
||||
sumsquare0=sumsquare
|
||||
endif
|
||||
if(subbestsumsquare(Currentilimittype).gt.1.0d+9)then
|
||||
jnon=jnon+1
|
||||
!for the first run, try different initial guesses
|
||||
if(jnon.lt.100.and.k.lt.5)then
|
||||
if(ran2().gt.0.7d0)then
|
||||
do i=1,ndim
|
||||
beta(i)=betamin(i)+ran2()*(betamax(i)-betamin(i))
|
||||
enddo
|
||||
else
|
||||
do i=1,ndim
|
||||
if(ran2().gt.0.5d0)then
|
||||
beta(i)=beta(i)+(ran2()**(3.0d0/dble(k+1)))*
|
||||
&(betamax(i)-beta(i))
|
||||
else
|
||||
beta(i)=beta(i)-(ran2()**(3.0d0/dble(k+1)))*
|
||||
&(beta(i)-betamin(i))
|
||||
endif
|
||||
enddo
|
||||
endif
|
||||
call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
goto 30
|
||||
else
|
||||
if((ftol_relax-ftol).gt.ftol)then
|
||||
ftol_relax=ftol
|
||||
goto 30
|
||||
endif
|
||||
endif
|
||||
call RepeatCompassSearch(ndim,beta,sumsquare,betamin,
|
||||
&betamax,funkmin_UnivPhotoFit,f1dim_UnivPhotoFit,xtol)
|
||||
call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
if((sumsquare+1.0d0).eq.sumsquare.or.sumsquare.gt.sumsquare0)
|
||||
&then
|
||||
do i=1,ndim
|
||||
beta(i)=beta0(i)
|
||||
enddo
|
||||
sumsquare=sumsquare0
|
||||
endif
|
||||
do i=1,ndim
|
||||
betacp(i)=(beta(i)-betamin(i))/(betamax(i)-betamin(i))
|
||||
history(1,ndim+1)=sumsquare
|
||||
!entrance counter
|
||||
history(1,ndim+2)=1.0d0
|
||||
!failure counter
|
||||
history(1,ndim+3)=0.0d0
|
||||
!Is it a competition among different initial guesses?
|
||||
icompete=0
|
||||
!j the total number of calls to nongradopt; k is the number of returns to the current best and reset
|
||||
!to zero if a better minumum is found; n is the number of scouting points over the landscape of the cost function.
|
||||
!The first initial guess provided by the user is always part of the set of scouting points.the rest consist of outcomes
|
||||
!from calls to nongradopt if they are significantly different from the current best.
|
||||
jnon=0
|
||||
isame=0
|
||||
n=1
|
||||
nave=n
|
||||
ftol_relax=ftol*1000.0d0
|
||||
discount=2.0d0
|
||||
!relax the convergence criterion for scouting
|
||||
30 do i=1,ndim
|
||||
betacp(i)=beta(i)
|
||||
enddo
|
||||
sumsquarecp=sumsquare
|
||||
isitbounded=0
|
||||
call pikaia(ff_pikaia,ndim,gacontrol,betacp,sumsquarecp,i)
|
||||
isitbounded=1
|
||||
if(i.eq.0)then
|
||||
iderivative=0
|
||||
if(ifitmode.lt.0)then
|
||||
iwrong=0
|
||||
else
|
||||
iwrong=1
|
||||
endif
|
||||
k=ifitmode
|
||||
ifitmode=-1
|
||||
!ifitmode: =-2, ordinary fitting with pco2i calculated as a function of anet
|
||||
!ifitmode: =-1, ordinary fitting with anet calculated as a function of pco2i
|
||||
!ifitmode: =1, orthogonal fitting with anet calculated as a function of pco2i
|
||||
!ifitmode: =2, orthogonal fitting with pco2i calculated as a function of anet
|
||||
!for odr_leastsquare, only the predicted value of the response variable is needed, i.e., the cost function value is not needed.
|
||||
!also, only anet as a function of CO2i is considered (not the other way around) because odr_leastsquare cannot handle the situation
|
||||
!co2i as a function of anet for tpu limitation when alpha=0
|
||||
i=1
|
||||
if(ntotphips2.ge.1)i=2
|
||||
j=4
|
||||
if(Currentiknowlimit.eq.-1)then
|
||||
!fluorescence only fit. chlflphisi2 becomes a forcing variable
|
||||
i=1
|
||||
j=5
|
||||
endif
|
||||
call odr_leastsquare(ndim,FCN_UnivPhotoFit,beta,ntotsamples,
|
||||
&forcings(1:ntotsamples,1:j),j,responses(1:ntotsamples,1:i),i,
|
||||
&weitforcings(1:ntotsamples,1:j),weitresponses(1:ntotsamples,1:i),
|
||||
&iderivative,shortx(1:ntotsamples,1:j),shorty(1:ntotsamples,1:i),
|
||||
&sumsquare,iwrong)
|
||||
ifitmode=k
|
||||
!after odr_leastsquare, forcing variables are destroyed. restore to the origninals
|
||||
do i=1,ntotsamples
|
||||
pco2i(i)=pco2i_ori(i)
|
||||
aPPFDlf(i)=aPPFDlf_ori(i)
|
||||
templeaf(i)=templeaf_ori(i)
|
||||
po2i(i)=po2i_ori(i)
|
||||
chlflphips2(i)=chlflphips2_ori(i)
|
||||
enddo
|
||||
call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
if(isitnaninf(sumsquare).eq.1.or.sumsquare.gt.sumsquarecp)then
|
||||
do i=1,ndim
|
||||
betacp(i)=betamin(i)+betacp(i)*(betamax(i)-betamin(i))
|
||||
beta(i)=betacp(i)
|
||||
enddo
|
||||
call funkmin_UnivPhotoFit(ndim,betacp,sumsquarecp)
|
||||
sumsquare=sumsquarecp
|
||||
else
|
||||
do i=1,ndim
|
||||
betacp(i)=beta(i)
|
||||
enddo
|
||||
sumsquarecp=sumsquare
|
||||
endif
|
||||
if((sumsquarecp+1.0d0).ne.sumsquarecp.and.
|
||||
&sumsquare.gt.sumsquarecp)then
|
||||
call nongradopt(ndim,funkmin_UnivPhotoFit,
|
||||
&f1dim_UnivPhotoFit,beta,betamin,betamax,ftol_relax,sumsquare)
|
||||
if(isitnaninf(sumsquare).eq.1.or.sumsquare.gt.sumsquarecp)then
|
||||
do i=1,ndim
|
||||
beta(i)=betacp(i)
|
||||
enddo
|
||||
sumsquare=sumsquarecp
|
||||
endif
|
||||
if(sumsquare.gt.1.0d0)then
|
||||
term1=sumsquare*ftol_relax
|
||||
else
|
||||
term1=ftol_relax*10.0d0
|
||||
endif
|
||||
if(sumsquare.gt.sumsquare0)then
|
||||
!failure
|
||||
if((sumsquare-sumsquare0).gt.term1)then
|
||||
if(icompete.eq.1)history(1,ndim+3)=history(1,ndim+3)+1.5d0
|
||||
!even though sumsquare is much worse than sumsquare0, it is an output of optimization after all so
|
||||
!include it in the set if it has not already been included in the set.
|
||||
i=1
|
||||
i2=1
|
||||
40 if(dabs(history(i2,i)-beta(i)).gt.ftol_relax)then
|
||||
if(dabs(history(i2,ndim+1)-sumsquare).lt.term1)then
|
||||
history(i2,ndim+3)=history(i2,ndim+3)+1.0d0
|
||||
goto 60
|
||||
endif
|
||||
if(i2.ge.n)goto 50
|
||||
i2=i2+1
|
||||
i=1
|
||||
goto 40
|
||||
else
|
||||
if(i.ge.ndim)goto 60
|
||||
i=i+1
|
||||
goto 40
|
||||
endif
|
||||
50 n=n+1
|
||||
do i=1,ndim
|
||||
history(n,i)=beta(i)
|
||||
enddo
|
||||
history(n,ndim+1)=sumsquare
|
||||
history(n,ndim+2)=0.0d0
|
||||
history(n,ndim+3)=0.0d0
|
||||
!use average only when there is imporvement
|
||||
nave=n
|
||||
else
|
||||
!the difference is minimal even though sumsquare is larger than sumsquare0.
|
||||
!Increment the counter for arriving at the same minimum.
|
||||
if(icompete.eq.1)history(1,ndim+3)=history(1,ndim+3)+1.0d0
|
||||
isame=isame+1
|
||||
endif
|
||||
60 do i=1,ndim
|
||||
beta(i)=beta0(i)
|
||||
enddo
|
||||
sumsquare=sumsquare0
|
||||
else
|
||||
!success
|
||||
if((sumsquare0-sumsquare).lt.term1)then
|
||||
!negligible improvement. Increment the counter for arriving at the same minimum.
|
||||
!no increment for the set of central initial guesses
|
||||
if(icompete.eq.1)history(1,ndim+3)=history(1,ndim+3)+0.5d0
|
||||
isame=isame+1
|
||||
nave=n
|
||||
else
|
||||
!reset the counter for arriving at a better minimum.
|
||||
!Increment the set of central initial guesses
|
||||
if(dabs(discount-2.0d0).lt.ftol)then
|
||||
discount=dmax1(0.001d0,(sumsquare0-sumsquare)/1000.0d0)
|
||||
endif
|
||||
isame=0
|
||||
n=n+1
|
||||
do i=1,ndim
|
||||
history(n,i)=beta(i)
|
||||
enddo
|
||||
history(n,ndim+1)=sumsquare
|
||||
history(n,ndim+2)=0.0d0
|
||||
history(n,ndim+3)=0.0d0
|
||||
endif
|
||||
do i=1,ndim
|
||||
beta0(i)=beta(i)
|
||||
enddo
|
||||
sumsquare0=sumsquare
|
||||
endif
|
||||
jnon=jnon+1
|
||||
if(jnon.lt.200.and.isame.lt.3)then
|
||||
!we first explore around the very first initial guess
|
||||
if(jnon.lt.10)then
|
||||
icompete=1
|
||||
term1=0.05d0+dmin1(history(1,ndim+3)*0.1d0,0.9d0)
|
||||
history(1,ndim+2)=history(1,ndim+2)+1.0d0
|
||||
do i=1,ndim
|
||||
lower=history(1,i)-term1*(history(1,i)-betamin(i))
|
||||
upper=history(1,i)+term1*(betamax(i)-history(1,i))
|
||||
beta(i)=lower+ran2()*(upper-lower)
|
||||
enddo
|
||||
goto 70
|
||||
endif
|
||||
!try average if n is incremented
|
||||
if(n.gt.nave)then
|
||||
term1=1.0d0/(history(1,ndim+1)+1.0d-5)
|
||||
do i=2,n
|
||||
term1=term1+1.0d0/(history(i,ndim+1)+1.0d-5)
|
||||
enddo
|
||||
do i=1,ndim
|
||||
beta(i)=history(1,i)/(term1*(history(1,ndim+1)+1.0d-5))
|
||||
do icompete=2,n
|
||||
beta(i)=beta(i)+history(icompete,i)/
|
||||
&(term1*(history(icompete,ndim+1)+1.0d-5))
|
||||
enddo
|
||||
enddo
|
||||
nave=n
|
||||
icompete=0
|
||||
goto 70
|
||||
endif
|
||||
!try different initial guesses
|
||||
if(ran2().gt.0.2d0)then
|
||||
!guess around the best
|
||||
icompete=1
|
||||
term1=history(1,ndim+1)+
|
||||
&discount*history(1,ndim+2)*history(1,ndim+3)
|
||||
do i=2,n
|
||||
term2=history(i,ndim+1)+
|
||||
&discount*history(i,ndim+2)*history(i,ndim+3)
|
||||
if(term2.le.term1)then
|
||||
term1=term2
|
||||
do i2=1,ndim+3
|
||||
history(n+1,i2)=history(i,i2)
|
||||
history(i,i2)=history(1,i2)
|
||||
history(1,i2)=history(n+1,i2)
|
||||
enddo
|
||||
endif
|
||||
enddo
|
||||
term1=0.05d0+dmin1(history(1,ndim+2)*history(1,ndim+3)*
|
||||
&0.015d0,0.9d0)
|
||||
history(1,ndim+2)=history(1,ndim+2)+1.0d0
|
||||
do i=1,ndim
|
||||
lower=history(1,i)-term1*(history(1,i)-betamin(i))
|
||||
upper=history(1,i)+term1*(betamax(i)-history(1,i))
|
||||
beta(i)=lower+ran2()*(upper-lower)
|
||||
enddo
|
||||
else
|
||||
!completely random guess
|
||||
do i=1,ndim
|
||||
beta(i)=betamin(i)+ran2()*(betamax(i)-betamin(i))
|
||||
enddo
|
||||
icompete=0
|
||||
endif
|
||||
70 call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
goto 30
|
||||
else
|
||||
if((ftol_relax-ftol).gt.ftol)then
|
||||
if(isame.le.1)then
|
||||
n=n+1
|
||||
do i=1,ndim+3
|
||||
history(n,i)=history(1,i)
|
||||
enddo
|
||||
do i=1,ndim
|
||||
history(1,i)=beta(i)
|
||||
enddo
|
||||
history(1,ndim+1)=sumsquare
|
||||
history(1,ndim+2)=0.0d0
|
||||
history(1,ndim+3)=0.0d0
|
||||
do i=1,n
|
||||
do icompete=1,ndim
|
||||
betacp(icompete)=history(i,icompete)
|
||||
enddo
|
||||
sumsquarecp=history(i,ndim+1)
|
||||
call RepeatCompassSearch(ndim,betacp,sumsquarecp,
|
||||
&betamin,betamax,funkmin_UnivPhotoFit,f1dim_UnivPhotoFit,
|
||||
&ftol_relax)
|
||||
call funkmin_UnivPhotoFit(ndim,betacp,sumsquarecp)
|
||||
if(isitnaninf(sumsquarecp).eq.0.and.sumsquarecp.lt.
|
||||
&sumsquare)then
|
||||
do icompete=1,ndim
|
||||
beta(icompete)=betacp(icompete)
|
||||
enddo
|
||||
sumsquare=sumsquarecp
|
||||
endif
|
||||
enddo
|
||||
do i=1,ndim
|
||||
beta0(i)=beta(i)
|
||||
enddo
|
||||
sumsquare0=sumsquare
|
||||
jnon=0
|
||||
icompete=1
|
||||
else
|
||||
icompete=0
|
||||
endif
|
||||
ftol_relax=ftol
|
||||
goto 30
|
||||
endif
|
||||
endif
|
||||
|
||||
goto 110
|
||||
|
||||
do i=1,ndim
|
||||
beta0(i)=beta(i)
|
||||
betacp(i)=(beta(i)-betamin(i))/(betamax(i)-betamin(i))
|
||||
enddo
|
||||
sumsquare0=sumsquare
|
||||
sumsquarecp=sumsquare
|
||||
call pikaia(ff_pikaia,ndim,gacontrol,betacp,sumsquarecp,i)
|
||||
if(i.eq.0)then
|
||||
do i=1,ndim
|
||||
betacp(i)=betamin(i)+betacp(i)*(betamax(i)-betamin(i))
|
||||
enddo
|
||||
call funkmin_UnivPhotoFit(ndim,betacp,sumsquarecp)
|
||||
if(isitnaninf(sumsquarecp).eq.0.and.sumsquare.gt.sumsquarecp)
|
||||
&then
|
||||
do i=1,ndim
|
||||
beta(i)=betacp(i)
|
||||
enddo
|
||||
sumsquare=sumsquarecp
|
||||
endif
|
||||
endif
|
||||
else
|
||||
return
|
||||
!local search
|
||||
call nongradopt(ndim,funkmin_UnivPhotoFit,f1dim_UnivPhotoFit,
|
||||
&beta,betamin,betamax,ftol,sumsquare)
|
||||
call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
endif
|
||||
do i=1,ndim
|
||||
beta0(i)=beta(i)
|
||||
enddo
|
||||
sumsquare0=sumsquare
|
||||
iderivative=0
|
||||
if(ifitmode.lt.0)then
|
||||
iwrong=0
|
||||
else
|
||||
iwrong=1
|
||||
endif
|
||||
isitbounded=1
|
||||
k=ifitmode
|
||||
ifitmode=-1
|
||||
!ifitmode: =-2, ordinary fitting with pco2i calculated as a function of anet
|
||||
@@ -322,7 +523,6 @@
|
||||
&weitforcings(1:ntotsamples,1:j),weitresponses(1:ntotsamples,1:i),
|
||||
&iderivative,shortx(1:ntotsamples,1:j),shorty(1:ntotsamples,1:i),
|
||||
&sumsquare,iwrong)
|
||||
isitbounded=1
|
||||
ifitmode=k
|
||||
!after odr_leastsquare, forcing variables are destroyed. restore to the origninals
|
||||
do i=1,ntotsamples
|
||||
@@ -333,29 +533,12 @@
|
||||
chlflphips2(i)=chlflphips2_ori(i)
|
||||
enddo
|
||||
call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
if((sumsquare+1.0d0).eq.sumsquare.or.sumsquare.gt.sumsquare0)then
|
||||
if(isitnaninf(sumsquare).eq.1.or.sumsquare.gt.sumsquare0)then
|
||||
do i=1,ndim
|
||||
beta(i)=beta0(i)
|
||||
enddo
|
||||
sumsquare=sumsquare0
|
||||
endif
|
||||
k=0
|
||||
do i=1,ndim
|
||||
if(beta(i).lt.betamin(i))k=1
|
||||
if(beta(i).gt.betamax(i))k=1
|
||||
enddo
|
||||
if(k.eq.1)then
|
||||
do i=1,ndim
|
||||
betacp(i)=(beta(i)-betamin(i))/(betamax(i)-betamin(i))
|
||||
enddo
|
||||
isitbounded=0
|
||||
call pikaia(ff_pikaia,ndim,gacontrol,betacp,sumsquare,i)
|
||||
do i=1,ndim
|
||||
beta(i)=betamin(i)+betacp(i)*(betamax(i)-betamin(i))
|
||||
enddo
|
||||
isitbounded=1
|
||||
call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
endif
|
||||
j=0
|
||||
100 jnon=0
|
||||
105 sumsquare0=sumsquare
|
||||
@@ -370,21 +553,11 @@
|
||||
goto 105
|
||||
endif
|
||||
if(sumsquare.eq.sumsquare0)goto 110
|
||||
if(dabs(sumsquare).le.dabs(sumsquare0))then
|
||||
else
|
||||
if(dabs(sumsquare).gt.1.0d+20)then
|
||||
!in case of infinity (division by zero)
|
||||
do i=1,ndim
|
||||
beta(i)=beta0(i)
|
||||
enddo
|
||||
sumsquare=sumsquare0
|
||||
else
|
||||
!designed this way to avoid sumsquare='NAN'
|
||||
do i=1,ndim
|
||||
beta(i)=beta0(i)
|
||||
enddo
|
||||
sumsquare=sumsquare0
|
||||
endif
|
||||
if(isitnaninf(sumsquare).eq.1.or.sumsquare.gt.sumsquare0)then
|
||||
do i=1,ndim
|
||||
beta(i)=beta0(i)
|
||||
enddo
|
||||
sumsquare=sumsquare0
|
||||
endif
|
||||
sumsquarecp=sumsquare
|
||||
do i=1,ndim
|
||||
@@ -394,14 +567,14 @@
|
||||
&betamax,funkmin_UnivPhotoFit,f1dim_UnivPhotoFit,xtol)
|
||||
call funkmin_UnivPhotoFit(ndim,betacp,sumsquarecp)
|
||||
if(sumsquare.eq.sumsquarecp)goto 110
|
||||
if(dabs(sumsquarecp).lt.dabs(sumsquare))then
|
||||
if(isitnaninf(sumsquarecp).eq.0.and.sumsquarecp.lt.sumsquare)then
|
||||
do i=1,ndim
|
||||
beta(i)=betacp(i)
|
||||
enddo
|
||||
sumsquare=sumsquarecp
|
||||
endif
|
||||
j=j+1
|
||||
if(j.le.2.and.dabs(sumsquare-sumsquare0).gt.ftol)goto 100
|
||||
if(j.le.2.and.(sumsquare0-sumsquare).gt.ftol)goto 100
|
||||
!
|
||||
!------------------------------------------------------
|
||||
110 call funkmin_UnivPhotoFit(ndim,beta,sumsquare)
|
||||
|
||||
Reference in New Issue
Block a user