Initial commit

This commit is contained in:
2016-02-03 18:52:05 +00:00
commit d40505e161
507 changed files with 91383 additions and 0 deletions
+210
View File
@@ -0,0 +1,210 @@
subroutine RepeatCompassSearch(ndim,xbest,fbest,
& bmin,bmax,funkmin,f1dim,xtol)
implicit none
integer ndim
double precision xbest(1:ndim),fbest,
& bmin(1:ndim),bmax(1:ndim),xtol
double precision fvalpre,dmax,xpre(1:ndim),ftol,direction(ndim)
integer i,n
logical resetran2
common /ran2reset/resetran2
external funkmin,f1dim
!
ftol=xtol
n=0
resetran2=.true.
10 fvalpre=fbest
do i=1,ndim
xpre(i)=xbest(i)
enddo
call CompassSearch(ndim,xbest,fbest,
& bmin,bmax,funkmin,f1dim,xtol)
n=n+1
dmax=dabs(xbest(1)-xpre(1))
do i=2,ndim
if(dmax.lt.dabs(xbest(i)-xpre(i)))then
dmax=dabs(xbest(i)-xpre(i))
endif
enddo
if(dabs(fvalpre-fbest).gt.ftol.and.
& dmax.gt.xtol.and.n.lt.2)then
do i=1,ndim
direction(i)=xbest(i)-xpre(i)
enddo
call linmin(xbest,bmin,bmax,direction,
& ndim,f1dim,fbest)
goto 10
endif
return
end subroutine RepeatCompassSearch
subroutine CompassSearch(ndim,xbest,fbest,
& bmin,bmax,funkmin,f1dim,xtol)
implicit none
! This subroutine minimizes the function funkmin using the compass search method. The ! maximum number of function evaluations is maxiter. Once mexiter is reached, all
! function evaluations are ranked and returned.
!
!------------------------------------- Inputs -----------------------------------------------------
! maxiter: the maximum number of function evaluations allowed
! xbest: the initial guess
! fbest: the cost function value at xinitial
! bmin: the lower bounds of the parameters to be optimized
! bmax: the upper bounds of the parameters to be optimized
! ndim: the number of parameters to optimize
! funkmin: the name of the function to minimize
!------------------------------------- Outputs ---------------------------------------------------
! xobs: points where the function is evaluated. Ranked from the best to worst with the
! first point being the best point.
! fvalue: the function values at xobs
! ierr: =0 convergence criterion not reached
! =1 convergence criterion reached (minimum found)
!
integer ndim
double precision xbest(1:ndim),fbest,
& bmin(1:ndim),bmax(1:ndim),xtol,dx1,dx2
external funkmin,f1dim
!------------------------------- Locals -----------------------------------------------------------
double precision diftol,delta,
& xcompass(1:2*ndim,1:ndim),fcompass(1:2*ndim),
& xvec(1:ndim),xcent(1:ndim),fcent,dif,shrink,
& direction(ndim),dmax,fcent0,ran2_reset,ran2
integer i,j,k,iter
parameter(shrink=0.618d0)
!
diftol=xtol
delta=0.618d0
do i=1,ndim
xcent(i)=xbest(i)
enddo
fcent=fbest
iter=0
10 continue
do i=1,ndim
do j=1,ndim
xcompass(i,j)=xcent(j)
xcompass(ndim+i,j)=xcent(j)
enddo
xcompass(i,i)=xcent(i)+delta*(bmax(i)-xcent(i))
xcompass(ndim+i,i)=xcent(i)+delta*(bmin(i)-xcent(i))
enddo
do i=1,2*ndim
do j=1,ndim
xvec(j)=xcompass(i,j)
enddo
call funkmin(ndim,xvec,fcompass(i))
if(dabs(fcompass(i)).gt.1.0d+90)then
delta=delta*shrink
if(delta.lt.diftol)goto 100
goto 10
endif
enddo
do i=1,ndim
xbest(i)=xcompass(1,i)
enddo
fbest=fcompass(1)
do i=2,2*ndim
if(fcompass(i).lt.fbest)then
fbest=fcompass(i)
do j=1,ndim
xbest(j)=xcompass(i,j)
enddo
endif
enddo
fcent0=fcent
do i=1,ndim
xvec(i)=xcent(i)
enddo
do i=1,ndim
dx1=xcompass(i,i)-xcent(i)
dx2=xcent(i)-xcompass(i+ndim,i)
direction(i)=0.0d0
if(dx1.ne.0.0d0)then
direction(i)=(fcompass(i)-fcent)/dx1
endif
if(dx2.ne.0.0d0)then
direction(i)=direction(i)+
& (fcent-fcompass(i+ndim))/dx2
endif
direction(i)=-0.5d0*direction(i)
if(direction(i).eq.0.0d0)direction(i)=
& ran2_reset()-0.5d0
enddo
call linmin(xcent,bmin,bmax,direction,
& ndim,f1dim,fcent)
if(fcent.gt.fcent0)then
fcent=fcent0
do i=1,ndim
xcent(i)=xvec(i)
enddo
endif
dif=fcent-fbest
if(fbest.le.fcent)then
fcent=fbest
do i=1,ndim
xcent(i)=xbest(i)
enddo
endif
if(dif.ge.0.0d0)then
if(dif.gt.diftol)then
if(iter.lt.150)then
iter=iter+1
goto 10
else
iter=0
endif
endif
if(delta.lt.diftol)goto 100
delta=delta*shrink
goto 10
else
!no progress
if(dabs(dif).gt.diftol)then
if(delta.lt.diftol)goto 100
delta=delta*shrink
goto 10
endif
dmax=dabs(xcompass(1,1)-xcompass(ndim+1,1))
do i=2,ndim
if(dmax.lt.dabs(xcompass(i,i)-
& xcompass(ndim+i,i)))then
dmax=dabs(xcompass(i,i)-
& xcompass(ndim+i,i))
endif
enddo
if(dmax.gt.xtol)then
if(delta.lt.diftol)goto 100
delta=delta*shrink
goto 10
else
goto 100
endif
endif
100 fbest=fcent
do i=1,ndim
xbest(i)=xcent(i)
dx1=xcompass(i,i)-xcent(i)
dx2=xcent(i)-xcompass(i+ndim,i)
direction(i)=0.0d0
if(dx1.ne.0.0d0)then
direction(i)=(fcompass(i)-fcent)/dx1
endif
if(dx2.ne.0.0d0)then
direction(i)=direction(i)+
& (fcent-fcompass(i+ndim))/dx2
endif
direction(i)=-0.5d0*direction(i)
if(direction(i).eq.0.0d0)direction(i)=
& ran2_reset()-0.5d0
enddo
call linmin(xcent,bmin,bmax,direction,
& ndim,f1dim,fcent)
if(fcent.lt.fbest)then
fbest=fcent
do i=1,ndim
xbest(i)=xcent(i)
enddo
endif
return
end subroutine CompassSearch
@@ -0,0 +1,361 @@
subroutine funkmin_generic(ndim,beta,fvalue)
implicit none
include 'forgenericregres.h'
integer ndim
double precision beta(ndim),fvalue
!(in) ndim: the dimension of the parameter vector
!(in) beta: the parameters
!(out) fvalue: the value of the cost function at beta
!-----------------------------------------------------
integer i,j,idowhat,nparams
double precision dydxp(nyvars,(nxvars+ndim))
!
! check to see if parameters are out of bounds
if(idobounded.eq.1)then
if(betamin(1).lt.betamax(1))then
do i=1,ndim
if(beta(i).lt.betamin(i).or.
&beta(i).gt.betamax(i))then
! parameter out of bound
fvalue=1.0d+100
return
endif
enddo
endif
endif
fvalue=0.0d0
if(iregrestype.eq.1)then
!orthogonal distance regression
do i=1,nobs
call shortestdist(nyvars,nxvars,yobs(i:i,1:nyvars),
& xvars(i:i,1:nxvars),xmin(i:i,1:nxvars),
& xmax(i:i,1:nxvars),ndim,beta,iknowder,
& shorty(i:i,1:nyvars),shortx(i:i,1:nxvars))
do j=1,nyvars
fvalue=fvalue+weity(i,j)*
& (shorty(i,j)-yobs(i,j))**2
enddo
do j=1,nxvars
fvalue=fvalue+weitx(i,j)*
& (shortx(i,j)-xvars(i,j))**2
enddo
enddo
endif
if(iregrestype.eq.0)then
idowhat=0
do i=1,nobs
call surffunc(nyvars,shorty(i:i,1:nyvars),nxvars,
& xvars(i:i,1:nxvars),ndim,beta,
& dydxp(1:nyvars,1:(nxvars+ndim)),idowhat)
do j=1,nyvars
fvalue=fvalue+weity(i,j)*
& (shorty(i,j)-yobs(i,j))**2
enddo
enddo
endif
if(iregrestype.eq.2)then
nparams=ndim-nobs
idowhat=nparams
do i=1,nobs
do j=1,nxvars
idowhat=idowhat+1
shortx(i,j)=beta(idowhat)
enddo
enddo
idowhat=0
do i=1,nobs
call surffunc(nyvars,shorty(i:i,1:nyvars),nxvars,
& shortx(i:i,1:nxvars),nparams,beta,
& dydxp(1:nyvars,1:(nxvars+ndim)),idowhat)
do j=1,nyvars
fvalue=fvalue+weity(i,j)*
& (shorty(i,j)-yobs(i,j))**2
enddo
do j=1,nxvars
fvalue=fvalue+weitx(i,j)*
& (shortx(i,j)-xvars(i,j))**2
enddo
enddo
endif
if(iregrestype.eq.-1)then
!implicit orthogonal distance regression
idowhat=0
do i=1,nobs
call surffunc(nyvars,shorty(i:i,1:nyvars),nxvars,
& xvars(i:i,1:nxvars),ndim,beta,
& dydxp(1:nyvars,1:(nxvars+ndim)),idowhat)
do j=1,nyvars
fvalue=fvalue+weity(i,j)*
& shorty(i,j)**2
enddo
enddo
endif
return
end subroutine funkmin_generic
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
double precision function f1dim_generic(x)
implicit none
double precision x
CU USES funkmin_generic
INTEGER j
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /f1com/ pcom,xicom,ncom
save /f1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
double precision xt(NMAX)
!-----------------------------------------------------
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call funkmin_generic(ncom,xt,f1dim_generic)
return
END
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
SUBROUTINE FCN_generic(N,M,NP,NQ,
+ LDN,LDM,LDNP,
+ BETA,XPLUSD,
+ IFIXB,IFIXX,LDIFX,
+ IDEVAL,F,FJACB,FJACD,
+ ISTOP)
implicit none
include 'forgenericregres.h'
C SUBROUTINE ARGUMENTS
C ==> N NUMBER OF OBSERVATIONS
C ==> M NUMBER OF COLUMNS IN EXPLANATORY VARIABLE
C ==> NP NUMBER OF PARAMETERS
C ==> NQ NUMBER OF RESPONSES PER OBSERVATION
C ==> LDN LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING N
C ==> LDM LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING M
C ==> LDNP LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING NP
C ==> BETA CURRENT VALUES OF PARAMETERS
C ==> XPLUSD CURRENT VALUE OF EXPLANATORY VARIABLE, I.E., X + DELTA
C ==> IFIXB INDICATORS FOR "FIXING" PARAMETERS (BETA)
C ==> IFIXX INDICATORS FOR "FIXING" EXPLANATORY VARIABLE (X)
C ==> LDIFX LEADING DIMENSION OF ARRAY IFIXX
C ==> IDEVAL INDICATOR FOR SELECTING COMPUTATION TO BE PERFORMED
C <== F PREDICTED FUNCTION VALUES
C <== FJACB JACOBIAN WITH RESPECT TO BETA
C <== FJACD JACOBIAN WITH RESPECT TO ERRORS DELTA
C <== ISTOP STOPPING CONDITION, WHERE
C 0 MEANS CURRENT BETA AND X+DELTA WERE
C ACCEPTABLE AND VALUES WERE COMPUTED SUCCESSFULLY
C 1 MEANS CURRENT BETA AND X+DELTA ARE
C NOT ACCEPTABLE; ODRPACK SHOULD SELECT VALUES
C CLOSER TO MOST RECENTLY USED VALUES IF POSSIBLE
C -1 MEANS CURRENT BETA AND X+DELTA ARE
C NOT ACCEPTABLE; ODRPACK SHOULD STOP
C INPUT ARGUMENTS, NOT TO BE CHANGED BY THIS ROUTINE:
INTEGER I,IDEVAL,ISTOP,L,LDIFX,LDM,LDN,LDNP,M,N,NP,NQ
DOUBLE PRECISION BETA(NP),XPLUSD(LDN,M)
INTEGER IFIXB(NP),IFIXX(LDIFX,M)
C OUTPUT ARGUMENTS:
DOUBLE PRECISION F(LDN,NQ),FJACB(LDN,LDNP,NQ),FJACD(LDN,LDM,NQ)
double precision ymod(NQ),dydxp(NQ,(M+NP))
integer k,idowhat
!-----------------------------------------------------
if(idobounded.eq.1)then
if(betamin(1).lt.betamax(1))then
do I=1,NP
if(BETA(I).lt.betamin(I).or.BETA(I).gt.betamax(I))then
ISTOP = 1
RETURN
endif
enddo
endif
endif
ISTOP=0
IF (MOD(IDEVAL,10).GE.1) THEN
idowhat=0
DO 100 I = 1,N
call surffunc(NQ,ymod,M,XPLUSD(I:I,1:M),
& NP,BETA,dydxp(1:NQ,1:(M+NP)),idowhat)
DO 110 L = 1,NQ
F(I,L)=ymod(L)
110 CONTINUE
100 CONTINUE
END IF
C COMPUTE DERIVATIVES WITH RESPECT TO BETA
IF (MOD(IDEVAL/10,10).GE.1) THEN
idowhat=2
DO 200 I = 1,N
call surffunc(NQ,ymod,M,XPLUSD(I:I,1:M),
& NP,BETA,dydxp(1:NQ,1:(M+NP)),idowhat)
DO 210 L = 1,NQ
do k=1,NP
FJACB(I,k,L)=dydxp(L,k)
enddo
210 CONTINUE
200 CONTINUE
ENDIF
c compute derivatives with respect to delta
IF (MOD(IDEVAL/100,10).GE.1) THEN
idowhat=1
DO 300 I = 1,N
call surffunc(NQ,ymod,M,XPLUSD(I:I,1:M),
& NP,BETA,dydxp(1:NQ,1:(M+NP)),idowhat)
DO 310 L = 1,NQ
do k=1,M
FJACD(I,k,L)=dydxp(L,k)
enddo
310 CONTINUE
300 CONTINUE
ENDIF
RETURN
END
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
double precision function generic_pikaia(ndim,beta01)
implicit none
include 'forgenericregres.h'
integer ndim,i
double precision beta01(ndim),beta(ndim),fvalue
do i=1,ndim
! beta01(i)=(beta(i)-betamin(i))/(betamax(i)-betamin(i))
beta(i)=betamin(i)+beta01(i)*(betamax(i)-betamin(i))
enddo
call funkmin_generic(ndim,beta,fvalue)
generic_pikaia=1.0d0/(fvalue+0.00001d0)
return
end
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
subroutine distcenter(nx,x,fequ,fvalue,idowhat)
implicit none
include 'leastdistance.h'
!idowhat=1, evaluating the system of equations and calculating the sum of squares.
!idowhat=2, calculating the distance.
integer nx,idowhat
double precision x(nx),fequ(nx),fvalue
!----------------------------------------------------------
integer i,j,ider
double precision y(my),dydxp(my,(nx+nparams)),
& xcopy(nx),sum,yplush(my),yminush(my),h
parameter(h=1.0d-7)
!==============End of Variable Declaration==================
j=0
call surffunc(my,y,nx,x,nparams,params,
& dydxp(1:my,1:(nx+nparams)),j)
if(idowhat.eq.1)then
if(iknowder.eq.1)then
call surffunc(my,y,nx,x,nparams,params,
& dydxp(1:my,1:(nx+nparams)),iknowder)
endif
if(iknowder.eq.0)then
do i=1,nx
xcopy(i)=x(i)
enddo
do i=1,nx
xcopy(i)=x(i)+h
call surffunc(my,yplush,nx,xcopy,nparams,params,
& dydxp(1:my,1:(nx+nparams)),iknowder)
xcopy(i)=x(i)-h
call surffunc(my,yminush,nx,xcopy,nparams,params,
& dydxp(1:my,1:(nx+nparams)),iknowder)
do j=1,my
dydxp(j,i)=(yplush(j)-yminush(j))/(2.0d0*h)
enddo
xcopy(i)=x(i)
enddo
endif
do i=1,nx
sum=0.0d0
do j=1,my
sum=sum+(y(j)-targety(j))*dydxp(j,i)
enddo
fequ(i)=x(i)-(targetx(i)-sum)
enddo
fvalue=0.0d0
do i=1,nx
fvalue=fvalue+fequ(i)*fequ(i)
enddo
endif
if(idowhat.eq.2)then
fvalue=0.0d0
do i=1,my
fvalue=fvalue+(y(i)-targety(i))**2
enddo
do i=1,nx
fvalue=fvalue+(x(i)-targetx(i))**2
enddo
endif
return
end subroutine distcenter
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
subroutine distcentersys(nunknowns,x,fequ,fsqsum)
implicit none
integer nunknowns,idowhat
double precision x(nunknowns),
& fequ(nunknowns),fsqsum
parameter(idowhat=1)
call distcenter(nunknowns,x,fequ,fsqsum,idowhat)
return
end subroutine distcentersys
!-----------------------------------------------------------
subroutine fsqsum_distcenter(nunknowns,x,fsqsum)
implicit none
integer nunknowns,idowhat
double precision x(nunknowns),fsqsum,
& fequ(nunknowns)
parameter(idowhat=1)
call distcenter(nunknowns,x,fequ,fsqsum,idowhat)
return
end
!-----------------------------------------------------------
double precision function f1dimsqsum_distcenter(x)
implicit none
double precision x
INTEGER j,idowhat
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /cpf1com/ pcom,xicom,ncom
save /cpf1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
double precision xt(NMAX),fequ(NMAX)
parameter(idowhat=1)
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call distcenter(ncom,xt,fequ,
& f1dimsqsum_distcenter,idowhat)
return
END
!------------------------------------------------------------
subroutine s2_distcenter(nunknowns,x,s2)
implicit none
integer nunknowns,idowhat
double precision x(nunknowns),s2,fequ(nunknowns)
parameter(idowhat=2)
call distcenter(nunknowns,x,fequ,s2,idowhat)
return
end
!-----------------------------------------------------------
double precision function f1dims2_distcenter(x)
implicit none
double precision x
INTEGER j,idowhat
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /cpf1com/ pcom,xicom,ncom
save /cpf1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
double precision xt(NMAX),fequ(NMAX)
parameter(idowhat=2)
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call distcenter(ncom,xt,fequ,
& f1dims2_distcenter,idowhat)
return
END
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+146
View File
@@ -0,0 +1,146 @@
subroutine funkmin_neural(ndim,beta,fvalue)
implicit none
include 'NeuralNetRegres.h'
integer ndim
double precision beta(ndim),fvalue
!(in) ndim: the dimension of the parameter vector
!(in) beta: the parameters
!(out) fvalue: the value of the cost function at beta
!-----------------------------------------------------
integer i,j,k,idowhat
double precision w(maxnx,maxnh),bph(maxnh),q(maxnh),
&bend,annfunc,ypred
!
! check to see if parameters are out of bounds
if(betamin(1).lt.betamax(1))then
do i=1,ndim
if(beta(i).lt.betamin(i).or.
& beta(i).gt.betamax(i))then
! parameter out of bound
fvalue=1.0d+100
return
endif
enddo
endif
idowhat=1
call coeff_beta(idowhat,nx,nh,beta,w(1:nx,1:nh),bph,q,bend)
fvalue=0.0d0
do i=1,nobs
ypred=annfunc(nx,xsamp(i:i,1:nx),nh,q,w(1:nx,1:nh),bph,bend)
fvalue=fvalue+(ysamp(i)-ypred)*(ysamp(i)-ypred)
enddo
return
end subroutine funkmin_neural
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
double precision function f1dim_neural(x)
implicit none
double precision x
CU USES funkmin_neural
INTEGER j
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /f1com/ pcom,xicom,ncom
save /f1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
double precision xt(NMAX)
!-----------------------------------------------------
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call funkmin_neural(ncom,xt,f1dim_neural)
return
END
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
SUBROUTINE FCN_neural(N,M,NP,NQ,
+ LDN,LDM,LDNP,
+ BETA,XPLUSD,
+ IFIXB,IFIXX,LDIFX,
+ IDEVAL,F,FJACB,FJACD,
+ ISTOP)
implicit none
C SUBROUTINE ARGUMENTS
C ==> N NUMBER OF OBSERVATIONS
C ==> M NUMBER OF COLUMNS IN EXPLANATORY VARIABLE
C ==> NP NUMBER OF PARAMETERS
C ==> NQ NUMBER OF RESPONSES PER OBSERVATION
C ==> LDN LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING N
C ==> LDM LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING M
C ==> LDNP LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING NP
C ==> BETA CURRENT VALUES OF PARAMETERS
C ==> XPLUSD CURRENT VALUE OF EXPLANATORY VARIABLE, I.E., X + DELTA
C ==> IFIXB INDICATORS FOR "FIXING" PARAMETERS (BETA)
C ==> IFIXX INDICATORS FOR "FIXING" EXPLANATORY VARIABLE (X)
C ==> LDIFX LEADING DIMENSION OF ARRAY IFIXX
C ==> IDEVAL INDICATOR FOR SELECTING COMPUTATION TO BE PERFORMED
C <== F PREDICTED FUNCTION VALUES
C <== FJACB JACOBIAN WITH RESPECT TO BETA
C <== FJACD JACOBIAN WITH RESPECT TO ERRORS DELTA
C <== ISTOP STOPPING CONDITION, WHERE
C 0 MEANS CURRENT BETA AND X+DELTA WERE
C ACCEPTABLE AND VALUES WERE COMPUTED SUCCESSFULLY
C 1 MEANS CURRENT BETA AND X+DELTA ARE
C NOT ACCEPTABLE; ODRPACK SHOULD SELECT VALUES
C CLOSER TO MOST RECENTLY USED VALUES IF POSSIBLE
C -1 MEANS CURRENT BETA AND X+DELTA ARE
C NOT ACCEPTABLE; ODRPACK SHOULD STOP
C INPUT ARGUMENTS, NOT TO BE CHANGED BY THIS ROUTINE:
INTEGER II,IDEVAL,ISTOP,L,LDIFX,LDM,LDN,LDNP,M,N,NP,NQ
DOUBLE PRECISION BETA(NP),XPLUSD(LDN,M)
INTEGER IFIXB(NP),IFIXX(LDIFX,M)
C OUTPUT ARGUMENTS:
DOUBLE PRECISION F(LDN,NQ),FJACB(LDN,LDNP,NQ),FJACD(LDN,LDM,NQ)
!
integer k,i,j,s,t,ierr,idowhat
include 'NeuralNetRegres.h'
double precision w(maxnx,maxnh),bph(maxnh),
& q(maxnh),bend,xnew(maxnx),annfunc,
& derBETA(NP),derw(maxnx,maxnh),derbph(maxnh),
& derq(maxnh),derbend
C CHECK FOR UNACCEPTABLE VALUES FOR THIS PROBLEM
c
do I=1,NP
if(BETA(I).lt.betamin(I).or.BETA(I).gt.betamax(I))then
ISTOP = 1
RETURN
endif
enddo
idowhat=1
call coeff_beta(idowhat,nx,nh,BETA,
& w(1:nx,1:nh),bph,q,bend)
!---------------- find the ann function values--------------------------
IF (MOD(IDEVAL,10).GE.1) THEN
DO 110 L = 1,NQ
DO 100 I = 1,N
do k=1,M
xnew(k)=XPLUSD(I,k)
enddo
F(I,L)=annfunc(nx,xnew,nh,q,w(1:nx,1:nh),bph,bend)
100 CONTINUE
110 CONTINUE
END IF
!----------------------------------------------------------------------
C COMPUTE DERIVATIVES WITH RESPECT TO BETA
IF (MOD(IDEVAL/10,10).GE.1) THEN
idowhat=2
DO 200 I = 1,N
do k=1,M
xnew(k)=XPLUSD(I,k)
enddo
call derannfunc(nx,xnew,nh,q,w(1:nx,1:nh),
& bph,bend,derq,derw(1:nx,1:nh),derbph,derbend)
call coeff_beta(idowhat,nx,nh,derBETA,
& derw(1:nx,1:nh),derbph,derq,derbend)
DO 210 L = 1,NQ
do k=1,NP
FJACB(I,k,L)=derBETA(k)
enddo
210 CONTINUE
200 CONTINUE
END IF
RETURN
END
!
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
@@ -0,0 +1,72 @@
subroutine FilterNeuralNetRegres(idowhat,nx0,nobs0,nh0,
&xsamp0,ysamp0,yatxsamp0,rsq,w,bph,q,bend,xnew,ypred)
implicit none
!
!=============Inputs regardless of idowhat=========================
!idowhat: =1, fit the data and estimate the coefficients. Provide the
! initial guess for the coefficients or set bend to -9999
! =2, coefficients are already available, calculate y at xnew
!nx0: the number of independent (x) variables
!nobs0: the total number of samples
!nh0: the total number of hidden nodes to use. One hidden layer is
! assumed.
!============When idowhat=1========================================
! --------Inputs--------
!xsamp0: the values of the independent (x) variables
!ysamp0: the values of the dependent (y) variable. y is one dimension.
! --------Outputs-------
!w: the slope coefficient to time the normalized x in the activation function
!bph: the intercept coefficient in the activation function
!q: the coefficient to time the value of the activation function
!bend: the residual constant in the neural network regression
!yatxsamp0: the predicted y value at xsamp0
!rsq: R squared
!============When idowhat=2=========================================
! --------Inputs--------
!w: the slope coefficient to time the normalized x in the activation function
!bph: the intercept coefficient in the activation function
!q: the coefficient to time the value of the activation function
!bend: the residual constant in the neural network regression
!xnew: the new x point who y value is to be estimated (when idowhat=2)
! --------Outputs-------
!ypred: the predicted y value at xnew
!
integer idowhat,nx0,nobs0,nh0
double precision xsamp0(nobs0,nx0),ysamp0(nobs0),
& yatxsamp0(nobs0),rsq,w(nx0,nh0),bph(nh0),q(nh0),
& bend,xnew(nx0),ypred,fn9999,dif_y(nobs0)
parameter(fn9999=-9999.0d0)
!============Locals=========================================
integer i,j,m,n,nobs,isoutlier_2sides
!
if(idowhat.eq.1)then
nobs=nobs0
10 n=0
do i=1,nobs
if(dabs(ysamp0(i)-fn9999).gt.1.0d-6)then
n=n+1
ysamp0(n)=ysamp0(i)
do j=1,nx0
xsamp0(n,j)=xsamp0(i,j)
enddo
endif
enddo
nobs=n
call NeuralNetRegres(idowhat,nx0,nobs,nh0,xsamp0(1:nobs,1:nx0),
&ysamp0,yatxsamp0,rsq,w(1:nx0,1:nh0),bph,q,bend,xnew,ypred)
do i=1,nobs
dif_y(i)=ysamp0(i)-yatxsamp0(i)
enddo
m=isoutlier_2sides(nobs,dif_y)
if(m.gt.0)then
ysamp0(m)=fn9999
goto 10
endif
return
endif
if(idowhat.eq.2)call NeuralNetRegres(idowhat,nx0,nobs0,nh0,
&xsamp0(1:nobs0,1:nx0),ysamp0,yatxsamp0,rsq,w(1:nx0,1:nh0),bph,
&q,bend,xnew,ypred)
return
end
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
@@ -0,0 +1,54 @@
Subroutine FilterRegres(nobs,ny,yobs,nx,xobs,weity0,
&weitx,ndim,beta,betamin,betamax,xmin,xmax,
&iderivative,iregrestype,shorty,shortx,fatbeta)
implicit none
!Generic Regression with outlier filtering. Use the subroutine GenericRegres.
!iregrestype=0, ordinary distance regression
!iregrestype=1, orthogonal distance regression. Direct search methods
! determine the shortest distance within the iteration
!iregrestype=2, orthogonal distance regression. Direct search methods
! expand the parameter vector to include x positions.
!iregrestype=-1, implicit regression
!iderivative=0, no derivatives provided, using central finite difference
!iderivative=1, derivatives provided.
!If the weity0(i,j) is modified on exit, the corresponding point is detected
!as an outlier
integer nobs,ny,nx,iderivative,ndim,iregrestype
double precision yobs(nobs,ny),xobs(nobs,nx),weity0(nobs,ny),
&weity(nobs,ny),weitx(nobs,nx),xmin(nobs,nx),xmax(nobs,nx),
&beta(ndim),betamin(ndim),betamax(ndim),shorty(nobs,ny),
&shortx(nobs,nx),fatbeta,dif_y(nobs),tiny
parameter(tiny=1.0d-9)
!
integer i,j,k,m,isoutlier_2sides,iok,ivector(nobs)
!-----------------------------------------------------
do i=1,nobs
do j=1,ny
weity(i,j)=weity0(i,j)
enddo
enddo
10 call GenericRegres(nobs,ny,yobs(1:nobs,1:ny),nx,xobs(1:nobs,1:nx),
&weity(1:nobs,1:ny),weitx(1:nobs,1:nx),ndim,beta,betamin,betamax,
&xmin(1:nobs,1:nx),xmax(1:nobs,1:nx),iderivative,iregrestype,
&shorty(1:nobs,1:ny),shortx(1:nobs,1:nx),fatbeta)
k=0
do j=1,ny
iok=0
do i=1,nobs
if(dabs(weity(i,j)).gt.tiny)then
!do not consider points with weit = 0 for the purpose of identifying outliers
iok=iok+1
ivector(iok)=i
dif_y(iok)=weity(i,j)*(yobs(i,j)-shorty(i,j))
endif
enddo
m=isoutlier_2sides(iok,dif_y)
if(m.gt.0)then
k=k+1
weity(ivector(m),j)=0.0d0
endif
enddo
if(k.gt.0)goto 10
return
end subroutine FilterRegres
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+334
View File
@@ -0,0 +1,334 @@
program test
implicit none
integer ndim
double precision x0(10),xt(10),fvalue
ndim=2
x0(1)=-90.0d0
x0(2)=1000.0d0
call GSA(ndim,x0,xt,fvalue)
write(*,*)fvalue,xt(1),xt(2)
end
* Generalized Simulated Annealing - Code
* Program developed by Members of Lab. of Molecular Modeling
* Kleber C. Mundim (1995)
* ------------------------------------------------------
* Global optimization method using Generalized Simulated Annealing
* as for example;
* GSA Procedure + Your objective/coust function
* ______________ __________________
* | | Set of Parameters | |
* | | =================> | Routine with |
* | GSA-routine | | your objective |
* | | <================= | function |
* |______________| Objective function |__________________|
*
* ------------------------------------------------------
* First Version Jan./1994 (Kleber Mundim and Constantino Tsallis)
* Second Version Jun./1995 (Marcelo Moret)
* Third Version Sep./1995 (Thierry Lemaire and Amin Bassrei)
*
* Some Basic References and literature citation:
*
*1- Title : Geometry Optimization and Conformational Analysis Through
* Generalized Simulated Annealing
* Authors : Kleber C. Mundim and Constantino Tsallis
* Journal : Int.Journal of Quantum Chemistry, 58 (1996),373-381
*
*2- Title : Stochastic Molecular Optimization using Generalized
* Simulated Annealing
* Authors : Marcelo Moret, Pedro G. Pascutti, Paulo M. Bish
* and Kleber C. Mundim
* Journal : Journal of Computational Chemistry, 19 (1998) 647-657
*
*3- Title : Modeling Gravity Anomalies Through Generalized
* Simulated Annealing
* Authors : Kleber C. Mundim, Thierry Lemaire and Amin Bassrei
* Journal : Physica A, 252 (1998) 405-416
* ------------------------------------------------------
* Most important vectors and parameters used in the GSA routines.
* NDimension --> Number of parameters to be optimized (problem dependent).
* X_t(i) --> This vector contains the parameters.
* X_0(i) --> X_0(i) contains X_t at the time t-1.
* X_Min --> Minimal parameters obtained.
* To --> Initial Temperature.
* qV --> qV caracterize the Visiting Probability Function.
* qA --> qA Acceptance Parameter.
* qT --> qT Temperature parameter
* NStopMax --> Maximum number of GSA loops (problem dependent).
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
subroutine GSA(ndim,X0,Xt,fvalue)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
* This routine start the GSA-loop
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (MaxDim=500)
dimension X0(ndim),Xt(ndim)
COMMON /Par1/ qV1,qV2,qA1,qT1,D,exp1,exp2,Coef,Tqt,To,ToScale
COMMON /Par2/ qA,qV,qT
COMMON /Par3/ NDimension,NStopMax,NRAN
COMMON /Xvector/ X_t(Maxdim), X_0(Maxdim), X_Min(Maxdim)
DATA One /1.0D+00/
NDimension=ndim
CALL GSAini()
DO i=1,NDimension
X_0(i)=X0(i)
X_Min(i) = X_0(i)
X_t(i) = X_0(i)
ENDDO
func_0 = func(X_0)
func_Min = func_0
func_t = func_0
OneqA1 = One/qA1
Time = 0.0D0
NCycle = 0
DO WHILE (NCycle.LE.NStopMax)
Time = Time + One
NCycle = NCycle + 1
T = Tqt/((One+Time)**qT1 - One)
IF(D.EQ.0.0D0) THEN
Tup = One
ELSE
Tup = T**(D/(qT-3.0D0))
ENDIF
CALL Gfunc(T,Tup)
func_t = func(X_t)
IF(func_t .LE. func_0) THEN
DO I=1, NDimension
X_0(I) = X_t(I)
ENDDO
func_0 = func_t
IF(func_t .LE. func_Min) THEN
func_Min = func_t
DO I=1,NDimension
X_Min(I) = X_t(I)
ENDDO
ENDIF
ELSE
DeltaE = func_t - func_0
qA1= qA - One
PqA = One/((One+qA1*DeltaE/T)**OneqA1)
Rand = RAN3(NRAN)
IF(Rand .LT. PqA) THEN
DO I=1,NDimension
X_0(I) = X_t(I)
ENDDO
func_0 = func_t
ENDIF
ENDIF
ENDDO
fvalue=func_t
do I=1,ndim
Xt(I)=X_t(I)
enddo
return
END
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
SUBROUTINE Gfunc(T,Tup)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
* This routine evaluate the new set o parameters using the
* visiting probability function g(q,T).
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (MaxDim=500)
COMMON /Par1/ qV1,qV2,qA1,qT1,D,exp1,exp2,Coef,Tqt,To,ToScale
COMMON /Par3/ NDimension,NStopMax,NRAN
COMMON /Xvector/ X_t(Maxdim), X_0(Maxdim), X_Min(Maxdim)
DATA One /1.00000D+00/
DO I = 1,NDimension
R = RAN3(NRAN)
S = RAN3(NRAN)
DeltaX = Coef*Tup/(One+qV1*R*R/T**exp1)**exp2
IF(S.LE.0.5) DeltaX = -DeltaX
X_t(I) = X_0(I) + DeltaX
ENDDO
RETURN
END
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
FUNCTION dgamma(r)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
* This routine evaluate usual Gamma function.
IMPLICIT REAL*8 (a - h, o - z)
PARAMETER (
1 p0 = 0.999999999999999990d+00, p1 = -0.422784335098466784d+00,
2 p2 = -0.233093736421782878d+00, p3 = 0.191091101387638410d+00,
3 p4 = -0.024552490005641278d+00, p5 = -0.017645244547851414d+00,
4 p6 = 0.008023273027855346d+00)
PARAMETER (
1 p7 = -0.000804329819255744d+00,p8 = -0.000360837876648255d+00,
2 p9 = 0.000145596568617526d+00,p10 = -0.000017545539395205d+00,
3 p11 = -0.000002591225267689d+00,p12 = 0.000001337767384067d+00,
4 p13 = -0.000000199542863674d+00)
n = NINT(r - 2)
w = r - (n + 2)
y = ((((((((((((p13 * w + p12)* w + p11)* w + p10)*
1 w + p9) * w + p8) * w + p7) * w + p6) * w + p5) *
2 w + p4) * w + p3) * w + p2) * w + p1) * w + p0
IF (n .gt. 0) THEN
w = r - 1
DO k = 2, n
w = w * (r - k)
END DO
ELSE
w = 1
DO k = 0, -n - 1
y = y * (r + k)
END DO
END IF
dgamma = w / y
RETURN
END
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
DOUBLE PRECISION FUNCTION RAN3(IDUM)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
* This routine return an randomic number 0<= r <= 1
C IMPLICIT REAL*4(M)
C PARAMETER (MBIG=4000000.,MSEED=1618033.,MZ=0.,FAC=2.5D-7)
PARAMETER (MBIG=1000000000,MSEED=161803398,MZ=0,FAC=1.D-9)
COMMON /RAN1A/ IFF,MJ,MK,INEXT,INEXTP,MA(55)
* DATA IFF /0/
* INEXT=0
* INEXTP=31
IF(IDUM.LT.0.OR.IFF.EQ.0)THEN
IFF=1
MJ=MSEED-IABS(IDUM)
MJ=MOD(MJ,MBIG)
MA(55)=MJ
MK=1
DO 11 I=1,54
II=MOD(21*I,55)
MA(II)=MK
MK=MJ-MK
IF(MK.LT.MZ)MK=MK+MBIG
MJ=MA(II)
11 CONTINUE
DO 13 K=1,4
DO 12 I=1,55
MA(I)=MA(I)-MA(1+MOD(I+30,55))
IF(MA(I).LT.MZ)MA(I)=MA(I)+MBIG
12 CONTINUE
13 CONTINUE
INEXT=0
INEXTP=31
IDUM=1
ENDIF
INEXT=INEXT+1
IF(INEXT.EQ.56)INEXT=1
INEXTP=INEXTP+1
IF(INEXTP.EQ.56)INEXTP=1
MJ=MA(INEXT)-MA(INEXTP)
IF(MJ.LT.MZ)MJ=MJ+MBIG
MA(INEXT)=MJ
RAN3=MJ*FAC
RETURN
END
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
SUBROUTINE GSAini()
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
* This routine read and initialize the GSA parameters
* The number of parameters to be optimized (NDIMENSION) is problem
* dependent.
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (MaxDim=500)
COMMON /Par1/ qV1,qV2,qA1,qT1,D,exp1,exp2,Coef,Tqt,To,ToScale
COMMON /Par2/ qA,qV,qT
COMMON /Par3/ NDimension,NStopMax,NRAN
DATA One /1.00000D+00/
CHARACTER tempo*8
qA=1.5d0
qT=1.5d0
qV=1.5d0
NStopMax=1000
To=1.0E-00
CALL TIME(tempo)
READ(tempo(7:8),"(I2)")NRAN
NRAN = -NRAN
D = 10.5d0
Pi = 3.14159265359D0
* Acceptance probability
qA1= qA - One
* Temperature
qT1 = qT - One
Tqt = To*(2.0D0**qT1-One)
* Visiting probability
qV1= qV - One
qV2= 2.0D0**qV1 - One
tmp= One/qV1 - 0.5D0
GamaDown = dgamma(tmp)
exp1 = 2.0D0/(3.0D0 - qV)
IF(D.EQ.0.0D0) THEN
Coef1 = One
exp2 = One/qv1 - 0.5D0
GamaUp = GamaDown
ELSE
Coef1 = (qV1/Pi)**(D*0.5D0)
exp2 = One/qV1 + 0.5D0*D - 0.5D0
GamaUp = dgamma(exp2)
ENDIF
Coef = Coef1*GamaUp/GamaDown
RETURN
END
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
FUNCTION func(X)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (MaxDim=500)
* This subrotuine make link between GSA and your Objective function
* X(nDimension) is a vector that contains the parameters set.
* GSA Procedure + Your objective/coust function
* ______________ __________________
* | | Set of Parameters X(i) | |
* | | =================> | Routine with |
* | GSA-routine | | your objective |
* | | <================= | function |
* |______________| Value of the function (f) |__________________|
COMMON /Par3/ NDimension,NStopMax,NRAN
DIMENSION X(MaxDim)
* CALL here your routine with the objective function
* X(i) is parameters set and f is the value of the objective function
! CALL funct(X,f)
! func = f
func=(X(1)-2.0d0)*(X(1)-2.0d0)+(X(2)-13.8d0)*(X(2)-13.8d0)
RETURN
END
+6
View File
@@ -0,0 +1,6 @@
Initial GSA parameters
1.5 qA Acceptance index
1.5 qT Temperature index
1.5 qV Visiting index
1000 NStopMax Max number of GSA-loops
1.0E-00 To Initial Temperature
+333
View File
@@ -0,0 +1,333 @@
Subroutine GenericRegres(npoints,ny,y,nx,x,weity0,
&weitx0,ndim0,beta_in_out,betamin0,betamax0,xmin0,xmax0,
&iderivative,iregrestype0,shorty0,shortx0,fatbeta)
implicit none
!iregrestype0=0, ordinary regression
!iregrestype0=1, orthogonal distance regression. Direct search methods
! determine the shortest distance within the iteration
!iregrestype0=2, orthogonal distance regression. Direct search methods
! expand the parameter vector to include x positions.
!iregrestype0=-1, implicit regression
!iderivative=0, no derivative provided
!iderivative=1, derivative provided
include 'forgenericregres.h'
integer npoints,ny,nx,iderivative,ndim0,iregrestype0
double precision y(npoints,ny),x(npoints,nx),weity0(npoints,ny),
&weitx0(npoints,nx),xmin0(npoints,nx),xmax0(npoints,nx),
&beta_in_out(ndim0),betamin0(ndim0),betamax0(ndim0),
&shorty0(npoints,ny),shortx0(npoints,nx),fatbeta
!
integer i,j,INFO,ndim,k
double precision xtol,beta(ndim0+nx*npoints),
&betacp(ndim0+nx*npoints),fatbetacp,beta0(ndim0+nx*npoints),
&fatbeta0,ftol,gacontrol(12),ran2,ftol_relax
parameter(xtol=1.0d-7,ftol=1.0d-7)
external funkmin_generic,FCN_generic,f1dim_generic,generic_pikaia
!-----------------------------------------------------
ndim=ndim0
nxvars=nx
nyvars=ny
if((nx*npoints+ndim0).gt.1000)iregrestype0=0
iregrestype=iregrestype0
iknowder=iderivative
nobs=npoints
do i=1,npoints
do j=1,nxvars
xvars(i,j)=x(i,j)
xmin(i,j)=xmin0(i,j)
xmax(i,j)=xmax0(i,j)
weitx0(i,j)=1.0d0
weitx(i,j)=weitx0(i,j)
enddo
do j=1,nyvars
yobs(i,j)=y(i,j)
weity(i,j)=weity0(i,j)
enddo
enddo
do i=1,ndim
betamin(i)=betamin0(i)
betamax(i)=betamax0(i)
beta(i)=beta_in_out(i)
enddo
if(iregrestype.eq.2)iregrestype=1
c gacontrol( 1) - number of individuals in a population (default
c is 100)
c gacontrol( 2) - number of generations over which solution is
c to evolve (default is 500)
c gacontrol( 3) - number of significant digits (i.e., number of
c genes) retained in chromosomal encoding (default
c is 6) (Note: This number is limited by the
c machine floating point precision. Most 32-bit
c floating point representations have only 6 full
c digits of precision. To achieve greater preci-
c sion this routine could be converted to double
c precision, but note that this would also require
c a double precision random number generator, which
c likely would not have more than 9 digits of
c precision if it used 4-byte integers internally.)
c gacontrol( 4) - crossover probability; must be <= 1.0 (default
c is 0.85). If crossover takes place, either one
c or two splicing points are used, with equal
c probabilities
c gacontrol( 5) - mutation mode; 1/2/3/4/5 (default is 2)
c 1=one-point mutation, fixed rate
c 2=one-point, adjustable rate based on fitness
c 3=one-point, adjustable rate based on distance
c 4=one-point+creep, fixed rate
c 5=one-point+creep, adjustable rate based on fitness
c 6=one-point+creep, adjustable rate based on distance
c gacontrol( 6) - initial mutation rate; should be small (default
c is 0.005) (Note: the mutation rate is the proba-
c bility that any one gene locus will mutate in
c any one generation.)
c gacontrol( 7) - minimum mutation rate; must be >= 0.0 (default
c is 0.0005)
c gacontrol( 8) - maximum mutation rate; must be <= 1.0 (default
c is 0.25)
c gacontrol( 9) - relative fitness differential; range from 0
c (none) to 1 (maximum). (default is 1.)
c gacontrol(10) - reproduction plan; 1/2/3=Full generational
c replacement/Steady-state-replace-random/Steady-
c state-replace-worst (default is 3)
c gacontrol(11) - elitism flag; 0/1=off/on (default is 0)
c (Applies only to reproduction plans 1 and 2)
c gacontrol(12) - printed output 0/1/2=None/Minimal/Verbose
c (default is 0)
idobounded=1
10 call funkmin_generic(ndim,beta,fatbeta)
do i=1,ndim
beta0(i)=beta(i)
enddo
fatbeta0=fatbeta
j=0
k=0
ftol_relax=ftol*100.0d0
30 call nongradopt(ndim,funkmin_generic,
&f1dim_generic,beta,betamin,betamax,ftol_relax,fatbeta)
call funkmin_generic(ndim,beta,fatbeta)
if((fatbeta+1.0d0).eq.fatbeta.or.fatbeta.gt.fatbeta0)then
do i=1,ndim
beta(i)=beta0(i)
enddo
fatbeta=fatbeta0
else
if((fatbeta0-fatbeta).lt.ftol_relax)then
!increment the counter for arriving at the same minimum
k=k+1
else
!reset the counter for arriving at a better minimum
k=0
endif
do i=1,ndim
beta0(i)=beta(i)
enddo
fatbeta0=fatbeta
endif
j=j+1
!try different initial guesses
if(j.lt.100.and.k.lt.5)then
if(ran2().gt.0.3d0)then
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
else
do i=1,ndim
beta(i)=betamin(i)+ran2()*(betamax(i)-betamin(i))
enddo
endif
call funkmin_generic(ndim,beta,fatbeta)
goto 30
else
if((ftol_relax-ftol).gt.ftol)then
ftol_relax=ftol
goto 30
endif
endif
call RepeatCompassSearch(ndim,beta,fatbeta,
&betamin,betamax,funkmin_generic,f1dim_generic,xtol)
call funkmin_generic(ndim,beta,fatbeta)
k=0
if((fatbeta+1.0d0).eq.fatbeta)k=1
do i=1,ndim
if((beta(i)+1.0d0).eq.beta(i))k=1
enddo
if(k.eq.1)then
do i=1,ndim
beta(i)=betamin(i)+(betamax(i)-betamin(i))*ran2()
enddo
goto 10
endif
if(fatbeta.ge.fatbeta0)then
!if RepeatCompassSearch cannot improve, we end the search
do i=1,ndim
beta(i)=beta0(i)
enddo
fatbeta=fatbeta0
goto 110
else
if((fatbeta0-fatbeta).lt.ftol)goto 40
endif
do i=1,12
gacontrol(i)=-1.0d0
enddo
gacontrol(1)=250.0d0
gacontrol(2)=5000.0d0
gacontrol(3)=8.0d0
do i=1,ndim
beta0(i)=(beta(i)-betamin(i))/(betamax(i)-betamin(i))
enddo
idobounded=0
call pikaia(generic_pikaia,ndim,gacontrol,beta0,fatbeta0,j)
fatbeta0=1.0d+100
if(j.eq.0)then
do i=1,ndim
beta0(i)=betamin(i)+beta0(i)*(betamax(i)-betamin(i))
enddo
idobounded=1
call funkmin_generic(ndim,beta0,fatbeta0)
k=0
if((fatbeta0+1.0d0).eq.fatbeta0)k=1
do i=1,ndim
if((beta0(i)+1.0d0).eq.beta0(i))k=1
enddo
if(k.eq.1)fatbeta0=1.0d+100
endif
40 if(fatbeta0.gt.fatbeta)then
fatbeta0=fatbeta
do i=1,ndim
beta0(i)=beta(i)
enddo
endif
do i=1,ndim
beta(i)=beta0(i)
enddo
fatbeta=fatbeta0
!
INFO=iregrestype
idobounded=0
call odr_leastsquare(ndim,FCN_generic,beta,nobs,
&xvars(1:nobs,1:nxvars),nxvars,yobs(1:nobs,1:nyvars),
&nyvars,weitx(1:nobs,1:nxvars),weity(1:nobs,1:nyvars),
&iderivative,shortx(1:nobs,1:nxvars),
&shorty(1:nobs,1:nyvars),fatbeta,INFO)
idobounded=1
call funkmin_generic(ndim,beta,fatbeta)
k=0
if((fatbeta+1.0d0).eq.fatbeta)k=1
do i=1,ndim
if((beta(i)+1.0d0).eq.beta(i))k=1
enddo
if(k.eq.1)fatbeta=1.0d+100
if(dabs(fatbeta).le.dabs(fatbeta0))then
else
do i=1,ndim
beta(i)=beta0(i)
enddo
fatbeta=fatbeta0
endif
do i=1,ndim
if(beta(i).lt.betamin(i).or.beta(i).gt.betamax(i))then
do j=1,ndim
beta(j)=beta0(j)
enddo
fatbeta=fatbeta0
endif
enddo
fatbeta0=fatbeta
iregrestype=iregrestype0
if(iregrestype.eq.2)then
do i=1,npoints
do j=1,nx
ndim=ndim+1
beta(ndim)=shortx(i,j)
betamin(ndim)=xmin0(i,j)
betamax(ndim)=xmax0(i,j)
if(beta(ndim).lt.betamin(ndim).or.
&beta(ndim).gt.betamax(ndim))then
beta(ndim)=x(i,j)
endif
enddo
enddo
call funkmin_generic(ndim,beta,fatbeta)
endif
j=0
100 j=j+1
fatbeta0=fatbeta
do i=1,ndim
beta0(i)=beta(i)
enddo
call nongradopt(ndim,funkmin_generic,
&f1dim_generic,beta,betamin,betamax,ftol,fatbeta)
call funkmin_generic(ndim,beta,fatbeta)
k=0
if((fatbeta+1.0d0).eq.fatbeta)k=1
do i=1,ndim
if((beta(i)+1.0d0).eq.beta(i))k=1
enddo
if(k.eq.1)fatbeta=1.0d+100
if(dabs(fatbeta).ge.dabs(fatbeta0))then
fatbeta=fatbeta0
do i=1,ndim
beta(i)=beta0(i)
enddo
goto 110
endif
fatbetacp=fatbeta
do i=1,ndim
betacp(i)=beta(i)
enddo
call RepeatCompassSearch(ndim,betacp,fatbetacp,
&betamin,betamax,funkmin_generic,f1dim_generic,xtol)
call funkmin_generic(ndim,betacp,fatbetacp)
k=0
if((fatbetacp+1.0d0).eq.fatbetacp)k=1
do i=1,ndim
if((betacp(i)+1.0d0).eq.betacp(i))k=1
enddo
if(k.eq.1)fatbetacp=1.0d+100
if(dabs(fatbetacp).lt.dabs(fatbeta))then
fatbeta=fatbetacp
do i=1,ndim
beta(i)=betacp(i)
enddo
else
goto 110
endif
if(j.ge.2.or.fatbeta.eq.fatbeta0)goto 110
if(dabs(fatbeta0-fatbeta).gt.ftol)then
do i=1,ndim
betacp(i)=beta(i)-beta0(i)
beta0(i)=beta(i)
enddo
fatbeta0=fatbeta
call linmin(beta,betamin,betamax,betacp,ndim,
&f1dim_generic,fatbeta)
call funkmin_generic(ndim,beta,fatbeta)
if(dabs(fatbeta).lt.dabs(fatbeta0))goto 100
fatbeta=fatbeta0
do i=1,ndim
beta(i)=beta0(i)
enddo
endif
110 call funkmin_generic(ndim,beta,fatbeta)
do i=1,ndim0
beta_in_out(i)=beta(i)
enddo
do i=1,npoints
do j=1,nyvars
shorty0(i,j)=shorty(i,j)
enddo
do j=1,nxvars
shortx0(i,j)=shortx(i,j)
enddo
enddo
return
end subroutine GenericRegres
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+358
View File
@@ -0,0 +1,358 @@
c DRIVER 2
c --------------------------------------------------------------
c CUSTOMIZED DRIVER FOR L-BFGS-B (version 2.4)
c --------------------------------------------------------------
c
c L-BFGS-B is a code for solving large nonlinear optimization
c problems with simple bounds on the variables.
c
c The code can also be used for unconstrained problems and is
c as efficient for these problems as the earlier limited memory
c code L-BFGS.
c
c This driver illustrates how to control the termination of the
c run and how to design customized output.
c
c References:
c
c [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
c memory algorithm for bound constrained optimization'',
c SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
c
c [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN
c Subroutines for Large Scale Bound Constrained Optimization''
c Tech. Report, NAM-11, EECS Department, Northwestern University,
c 1994.
c
c (Postscript files of these papers are available via anonymous
c ftp to ece.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
c
c * * *
c
c NEOS, November 1994. (Latest revision April 1997.)
c Optimization Technology Center.
c Argonne National Laboratory and Northwestern University.
c Written by
c Ciyou Zhu
c in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
c
c
c **************
subroutine Lbfgsb_2_4(n,x,f,l,u,nbd,funkminfjac,
& pgtol,info)
implicit none
! info =0, best parameters on output
! info =1, output may not be best parameters
! info <0: parameter out of bounds. |info| denotes the out-of-bound parameter
! info =11: the correlation matrix is not postitive definite (the determinant is negative)
c This driver shows how to replace the default stopping test
c by other termination criteria. It also illustrates how to
c print the values of several parameters during the course of
c the iteration. The sample problem used here is the same as in
c DRIVER1 (the extended Rosenbrock function with bounds on the
c variables).
integer nmax, mmax, lenwa
parameter (nmax = 1024, mmax = 17)
parameter (lenwa = 2*mmax*nmax + 4*nmax
+ + 11*mmax*mmax + 8*mmax)
c nmax is the dimension of the largest problem to be solved.
c mmax is the maximum number of limited memory corrections.
c lenwa is the corresponding real workspace required.
c Declare the variables needed by the code.
c A description of all these variables is given at the end of
c driver1.
character*60 task, csave
logical lsave(4)
integer n, m, iprint, maxiter,info,idogradient,
+ nbd(nmax), iwa(3*nmax), isave(44)
double precision f, factr, pgtol,
+ x(nmax), l(nmax), u(nmax), g(nmax), dsave(29),
+ wa(lenwa)
parameter(maxiter=2000)
external funkminfjac
c Declare a few additional local variables.
integer i
c We suppress the default output.
iprint = -1
c We suppress both code-supplied stopping tests because the
c user is providing his own stopping criteria.
factr = 1.0d+1
! require funkminfjac to do function value and derivative calculations together
idogradient=1
c We specify the number
c m of limited memory corrections stored. (n and m should not
c exceed the limits nmax and mmax respectively.)
m = 5
c All variables have both lower and upper bounds
! do 10 i = 1, n
! nbd(i) = 2
! 10 continue
c We now define the starting point.
c We start the iteration by initializing task.
task = 'START'
info=0
c ------- The beginning of the loop ----------
111 continue
c This is the call to the L-BFGS-B code.
call setulb(n,m,x,l,u,nbd,f,g,factr,pgtol,wa,iwa,task,iprint,
+ csave,lsave,isave,dsave)
if (task(1:2) .eq. 'FG') then
c The minimization routine has returned to request the
c function f and gradient g values at the current x.
c Compute the cost function value f
! call funkmin(n,x,f)
c Compute gradient g of the cost function at x
! call fjac(n,x,f,g)
call funkminfjac(n,x,idogradient,f,g,info)
if(info.lt.0.or.info.eq.11)return
c Go back to the minimization routine.
goto 111
elseif (task(1:5) .eq. 'NEW_X') then
c
c The minimization routine has returned with a new iterate.
c At this point have the opportunity of stopping the iteration
c or observing the values of certain parameters
c
c First are two examples of stopping tests.
c Note: task(1:4) must be assigned the value 'STOP' to terminate
c the iteration and ensure that the final results are
c printed in the default format. The rest of the character
c string task may be used to store other information.
c 1) Terminate if the total number of f and g evaluations
c exceeds maxiter.
if (isave(34) .ge. maxiter)
+ task='STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
c 2) Terminate if |proj g|/(1 + |f|) < pgtol, where
c "proj g" denoted the projected gradient
if (dsave(13) .le. pgtol*(1.0d0 + dabs(f)))
+ task='STOP: THE PROJECTED GRADIENT IS SUFFICIENTLY SMALL'
c We now wish to get the following information at each
c iteration:
c
c 1) the current iteration number, isave(30),
c 2) the total number of f and g evaluations, isave(34),
c 3) the value of the objective function f,
c 4) the norm of the projected gradient, dsve(13)
c
c See the comments at the end of driver1 for a description
c of the variables isave and dsave.
c Go back to the minimization routine.
goto 111
else
c We terminate execution when task is neither FG nor NEW_X.
c We print the information contained in the string task
c if the default output is not used and the execution is
c not stopped intentionally by the user. In this case the last
! x and f may not be the best
if (task(1:4).eq.'ERROR')info=1
endif
c ---------- the end of the loop -------------
return
end subroutine Lbfgsb_2_4
c======================= The end of Lbfgsb_2_4 ============================
c --------------------------------------------------------------
c DESCRIPTION OF THE VARIABLES IN L-BFGS-B
c --------------------------------------------------------------
c
c n is an INTEGER variable that must be set by the user to the
c number of variables. It is not altered by the routine.
c
c m is an INTEGER variable that must be set by the user to the
c number of corrections used in the limited memory matrix.
c It is not altered by the routine. Values of m < 3 are
c not recommended, and large values of m can result in excessive
c computing time. The range 3 <= m <= 20 is recommended.
c
c x is a DOUBLE PRECISION array of length n. On initial entry
c it must be set by the user to the values of the initial
c estimate of the solution vector. Upon successful exit, it
c contains the values of the variables at the best point
c found (usually an approximate solution).
c
c l is a DOUBLE PRECISION array of length n that must be set by
c the user to the values of the lower bounds on the variables. If
c the i-th variable has no lower bound, l(i) need not be defined.
c
c u is a DOUBLE PRECISION array of length n that must be set by
c the user to the values of the upper bounds on the variables. If
c the i-th variable has no upper bound, u(i) need not be defined.
c
c nbd is an INTEGER array of dimension n that must be set by the
c user to the type of bounds imposed on the variables:
c nbd(i)=0 if x(i) is unbounded,
c 1 if x(i) has only a lower bound,
c 2 if x(i) has both lower and upper bounds,
c 3 if x(i) has only an upper bound.
c
c f is a DOUBLE PRECISION variable. If the routine setulb returns
c with task(1:2)= 'FG', then f must be set by the user to
c contain the value of the function at the point x.
c
c g is a DOUBLE PRECISION array of length n. If the routine setulb
c returns with taskb(1:2)= 'FG', then g must be set by the user to
c contain the components of the gradient at the point x.
c
c factr is a DOUBLE PRECISION variable that must be set by the user.
c It is a tolerance in the termination test for the algorithm.
c The iteration will stop when
c
c (f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr*epsmch
c
c where epsmch is the machine precision which is automatically
c generated by the code. Typical values for factr on a computer
c with 15 digits of accuracy in double precision are:
c factr=1.d+12 for low accuracy;
c 1.d+7 for moderate accuracy;
c 1.d+1 for extremely high accuracy.
c The user can suppress this termination test by setting factr=0.
c
c pgtol is a double precision variable.
c On entry pgtol >= 0 is specified by the user. The iteration
c will stop when
c
c max{|proj g_i | i = 1, ..., n} <= pgtol
c
c where pg_i is the ith component of the projected gradient.
c The user can suppress this termination test by setting pgtol=0.
c
c wa is a DOUBLE PRECISION array of length
c (2mmax + 4)nmax + 11mmax^2 + 8mmax used as workspace.
c This array must not be altered by the user.
c
c iwa is an INTEGER array of length 3nmax used as
c workspace. This array must not be altered by the user.
c
c task is a CHARACTER string of length 60.
c On first entry, it must be set to 'START'.
c On a return with task(1:2)='FG', the user must evaluate the
c function f and gradient g at the returned value of x.
c On a return with task(1:5)='NEW_X', an iteration of the
c algorithm has concluded, and f and g contain f(x) and g(x)
c respectively. The user can decide whether to continue or stop
c the iteration.
c When
c task(1:4)='CONV', the termination test in L-BFGS-B has been
c satisfied;
c task(1:4)='ABNO', the routine has terminated abnormally
c without being able to satisfy the termination conditions,
c x contains the best approximation found,
c f and g contain f(x) and g(x) respectively;
c task(1:5)='ERROR', the routine has detected an error in the
c input parameters;
c On exit with task = 'CONV', 'ABNO' or 'ERROR', the variable task
c contains additional information that the user can print.
c This array should not be altered unless the user wants to
c stop the run for some reason. See driver2 or driver3
c for a detailed explanation on how to stop the run
c by assigning task(1:4)='STOP' in the driver.
c
c iprint is an INTEGER variable that must be set by the user.
c It controls the frequency and type of output generated:
c iprint<0 no output is generated;
c iprint=0 print only one line at the last iteration;
c 0<iprint<99 print also f and |proj g| every iprint iterations;
c iprint=99 print details of every iteration except n-vectors;
c iprint=100 print also the changes of active set and final x;
c iprint>100 print details of every iteration including x and g;
c When iprint > 0, the file iterate.dat will be created to
c summarize the iteration.
c
c csave is a CHARACTER working array of length 60.
c
c lsave is a LOGICAL working array of dimension 4.
c On exit with task = 'NEW_X', the following information is
c available:
c lsave(1) = .true. the initial x did not satisfy the bounds;
c lsave(2) = .true. the problem contains bounds;
c lsave(3) = .true. each variable has upper and lower bounds.
c
c isave is an INTEGER working array of dimension 44.
c On exit with task = 'NEW_X', it contains information that
c the user may want to access:
c isave(30) = the current iteration number;
c isave(34) = the total number of function and gradient
c evaluations;
c isave(36) = the number of function value or gradient
c evaluations in the current iteration;
c isave(38) = the number of free variables in the current
c iteration;
c isave(39) = the number of active constraints at the current
c iteration;
c
c See the subroutine setulb.f for a description of other
c information contained in isave.
c
c dsave is a DOUBLE PRECISION working array of dimension 29.
c On exit with task = 'NEW_X', it contains information that
c the user may want to access:
c dsave(2) = the value of f at the previous iteration;
c dsave(5) = the machine precision epsmch generated by the code;
c dsave(13) = the infinity norm of the projected gradient;
c
c See the subroutine setulb.f for a description of other
c information contained in dsave.
c
c --------------------------------------------------------------
c END OF THE DESCRIPTION OF THE VARIABLES IN L-BFGS-B
c --------------------------------------------------------------
c
c << An example of subroutine 'timer' for AIX Version 3.2 >>
c
c subroutine timer(ttime)
c double precision ttime
c integer itemp, integer mclock
c
c itemp = mclock()
c ttime = dble(itemp)*1.0d-2
c return
c end
c-----------------------------------------------------------------------
@@ -0,0 +1,411 @@
subroutine funkmin_generic(ndim,beta,fvalue)
implicit none
include 'forgenericregres.h'
integer ndim
double precision beta(ndim),fvalue
!(in) ndim: the dimension of the parameter vector
!(in) beta: the parameters
!(out) fvalue: the value of the cost function at beta
!-----------------------------------------------------
integer i,j,k,idowhat,nparams,ibreak
double precision dydxp(nyvars,(nxvars+ndim)),params(ndim)
ibreak=39
!
! check to see if parameters are out of bounds
if(betamin(1).lt.betamax(1))then
do i=1,ndim
if(beta(i).lt.betamin(i).or.
& beta(i).gt.betamax(i))then
! parameter out of bound
fvalue=1.0d+100
return
endif
enddo
endif
fvalue=0.0d0
if(iregrestype.eq.0)then
idowhat=0
do i=1,nobs
if(i.le.ibreak)then
nparams=ndim-1
do j=1,nparams
params(j)=beta(j)
enddo
else
nparams=ndim-1
do j=1,nparams
params(j)=beta(j)
enddo
params(nparams)=beta(ndim)
endif
call surffunc(nyvars,shorty(i:i,1:nyvars),nxvars,
& xvars(i:i,1:nxvars),nparams,params,
& dydxp(1:nyvars,1:(nxvars+nparams)),idowhat)
do j=1,nyvars
fvalue=fvalue+weity(i,j)*
& (shorty(i,j)-yobs(i,j))**2
enddo
enddo
endif
return
if(iregrestype.eq.1)then
!orthogonal distance regression
do i=1,nobs
call shortestdist(nyvars,nxvars,yobs(i:i,1:nyvars),
& xvars(i:i,1:nxvars),xmin(i:i,1:nxvars),
& xmax(i:i,1:nxvars),ndim,beta,iknowder,
& shorty(i:i,1:nyvars),shortx(i:i,1:nxvars))
do j=1,nyvars
fvalue=fvalue+weity(i,j)*
& (shorty(i,j)-yobs(i,j))**2
enddo
do j=1,nxvars
fvalue=fvalue+weitx(i,j)*
& (shortx(i,j)-xvars(i,j))**2
enddo
enddo
endif
if(iregrestype.eq.2)then
nparams=ndim-nobs
idowhat=nparams
do i=1,nobs
do j=1,nxvars
idowhat=idowhat+1
shortx(i,j)=beta(idowhat)
enddo
enddo
idowhat=0
do i=1,nobs
call surffunc(nyvars,shorty(i:i,1:nyvars),nxvars,
& shortx(i:i,1:nxvars),nparams,beta,
& dydxp(1:nyvars,1:(nxvars+ndim)),idowhat)
do j=1,nyvars
fvalue=fvalue+weity(i,j)*
& (shorty(i,j)-yobs(i,j))**2
enddo
do j=1,nxvars
fvalue=fvalue+weitx(i,j)*
& (shortx(i,j)-xvars(i,j))**2
enddo
enddo
endif
if(iregrestype.eq.-1)then
!implicit orthogonal distance regression
idowhat=0
do i=1,nobs
call surffunc(nyvars,shorty(i:i,1:nyvars),nxvars,
& xvars(i:i,1:nxvars),ndim,beta,
& dydxp(1:nyvars,1:(nxvars+ndim)),idowhat)
do j=1,nyvars
fvalue=fvalue+weity(i,j)*
& shorty(i,j)**2
enddo
enddo
endif
return
end subroutine funkmin_generic
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
double precision function f1dim_generic(x)
implicit none
double precision x
CU USES funkmin_generic
INTEGER j
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /f1com/ pcom,xicom,ncom
save /f1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
double precision xt(NMAX)
!-----------------------------------------------------
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call funkmin_generic(ncom,xt,f1dim_generic)
return
END
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
SUBROUTINE FCN_generic(N,M,NP,NQ,
+ LDN,LDM,LDNP,
+ BETA,XPLUSD,
+ IFIXB,IFIXX,LDIFX,
+ IDEVAL,F,FJACB,FJACD,
+ ISTOP)
implicit none
include 'forgenericregres.h'
C SUBROUTINE ARGUMENTS
C ==> N NUMBER OF OBSERVATIONS
C ==> M NUMBER OF COLUMNS IN EXPLANATORY VARIABLE
C ==> NP NUMBER OF PARAMETERS
C ==> NQ NUMBER OF RESPONSES PER OBSERVATION
C ==> LDN LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING N
C ==> LDM LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING M
C ==> LDNP LEADING DIMENSION DECLARATOR EQUAL OR EXCEEDING NP
C ==> BETA CURRENT VALUES OF PARAMETERS
C ==> XPLUSD CURRENT VALUE OF EXPLANATORY VARIABLE, I.E., X + DELTA
C ==> IFIXB INDICATORS FOR "FIXING" PARAMETERS (BETA)
C ==> IFIXX INDICATORS FOR "FIXING" EXPLANATORY VARIABLE (X)
C ==> LDIFX LEADING DIMENSION OF ARRAY IFIXX
C ==> IDEVAL INDICATOR FOR SELECTING COMPUTATION TO BE PERFORMED
C <== F PREDICTED FUNCTION VALUES
C <== FJACB JACOBIAN WITH RESPECT TO BETA
C <== FJACD JACOBIAN WITH RESPECT TO ERRORS DELTA
C <== ISTOP STOPPING CONDITION, WHERE
C 0 MEANS CURRENT BETA AND X+DELTA WERE
C ACCEPTABLE AND VALUES WERE COMPUTED SUCCESSFULLY
C 1 MEANS CURRENT BETA AND X+DELTA ARE
C NOT ACCEPTABLE; ODRPACK SHOULD SELECT VALUES
C CLOSER TO MOST RECENTLY USED VALUES IF POSSIBLE
C -1 MEANS CURRENT BETA AND X+DELTA ARE
C NOT ACCEPTABLE; ODRPACK SHOULD STOP
C INPUT ARGUMENTS, NOT TO BE CHANGED BY THIS ROUTINE:
INTEGER I,IDEVAL,ISTOP,L,LDIFX,LDM,LDN,LDNP,M,N,NP,NQ
DOUBLE PRECISION BETA(NP),XPLUSD(LDN,M)
INTEGER IFIXB(NP),IFIXX(LDIFX,M)
C OUTPUT ARGUMENTS:
DOUBLE PRECISION F(LDN,NQ),FJACB(LDN,LDNP,NQ),FJACD(LDN,LDM,NQ)
double precision ymod(NQ),dydxp(NQ,(M+NP)),params(NP)
integer k,idowhat,nparams,ibreak
!-----------------------------------------------------
ibreak=39
if(betamin(1).lt.betamax(1))then
do I=1,NP
if(BETA(I).lt.betamin(I).or.BETA(I).gt.betamax(I))then
ISTOP = 1
RETURN
endif
enddo
endif
ISTOP=0
IF (MOD(IDEVAL,10).GE.1) THEN
idowhat=0
DO 100 I = 1,N
if(I.le.ibreak)then
nparams=NP-1
do k=1,nparams
params(k)=BETA(k)
enddo
else
nparams=NP-1
do k=1,nparams
params(k)=BETA(k)
enddo
params(nparams)=BETA(NP)
endif
call surffunc(NQ,ymod,M,XPLUSD(I:I,1:M),
&nparams,params,dydxp(1:NQ,1:(M+nparams)),idowhat)
DO 110 L = 1,NQ
F(I,L)=ymod(L)
110 CONTINUE
100 CONTINUE
END IF
C COMPUTE DERIVATIVES WITH RESPECT TO BETA
IF (MOD(IDEVAL/10,10).GE.1) THEN
idowhat=2
DO 200 I = 1,N
if(I.le.ibreak)then
nparams=NP-1
do k=1,nparams
params(k)=BETA(k)
enddo
else
nparams=NP-1
do k=1,nparams
params(k)=BETA(k)
enddo
params(nparams)=BETA(NP)
endif
call surffunc(NQ,ymod,M,XPLUSD(I:I,1:M),
&nparams,params,dydxp(1:NQ,1:(M+nparams)),idowhat)
DO 210 L = 1,NQ
do k=1,nparams
FJACB(I,k,L)=dydxp(L,k)
enddo
if(I.le.ibreak)then
FJACB(I,NP,L)=0.0d0
else
FJACB(I,NP,L)=dydxp(L,nparams)
FJACB(I,nparams,L)=0.0d0
endif
210 CONTINUE
200 CONTINUE
ENDIF
c compute derivatives with respect to delta
IF (MOD(IDEVAL/100,10).GE.1) THEN
idowhat=1
DO 300 I = 1,N
if(I.le.ibreak)then
nparams=NP-1
do k=1,nparams
params(k)=BETA(k)
enddo
else
nparams=NP-1
do k=1,nparams
params(k)=BETA(k)
enddo
params(nparams)=BETA(NP)
endif
call surffunc(NQ,ymod,M,XPLUSD(I:I,1:M),
&nparams,params,dydxp(1:NQ,1:(M+nparams)),idowhat)
DO 310 L = 1,NQ
do k=1,M
FJACD(I,k,L)=dydxp(L,k)
enddo
310 CONTINUE
300 CONTINUE
ENDIF
RETURN
END
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
subroutine distcenter(nx,x,fequ,fvalue,idowhat)
implicit none
include 'leastdistance.h'
!idowhat=1, evaluating the system of equations and calculating the sum of squares.
!idowhat=2, calculating the distance.
integer nx,idowhat
double precision x(nx),fequ(nx),fvalue
!----------------------------------------------------------
integer i,j,ider
double precision y(my),dydxp(my,(nx+nparams)),
& xcopy(nx),sum,yplush(my),yminush(my),h
parameter(h=1.0d-7)
!==============End of Variable Declaration==================
j=0
call surffunc(my,y,nx,x,nparams,params,
& dydxp(1:my,1:(nx+nparams)),j)
if(idowhat.eq.1)then
if(iknowder.eq.1)then
call surffunc(my,y,nx,x,nparams,params,
& dydxp(1:my,1:(nx+nparams)),iknowder)
endif
if(iknowder.eq.0)then
do i=1,nx
xcopy(i)=x(i)
enddo
do i=1,nx
xcopy(i)=x(i)+h
call surffunc(my,yplush,nx,xcopy,nparams,params,
& dydxp(1:my,1:(nx+nparams)),iknowder)
xcopy(i)=x(i)-h
call surffunc(my,yminush,nx,xcopy,nparams,params,
& dydxp(1:my,1:(nx+nparams)),iknowder)
do j=1,my
dydxp(j,i)=(yplush(j)-yminush(j))/(2.0d0*h)
enddo
xcopy(i)=x(i)
enddo
endif
do i=1,nx
sum=0.0d0
do j=1,my
sum=sum+(y(j)-targety(j))*dydxp(j,i)
enddo
fequ(i)=x(i)-(targetx(i)-sum)
enddo
fvalue=0.0d0
do i=1,nx
fvalue=fvalue+fequ(i)*fequ(i)
enddo
endif
if(idowhat.eq.2)then
fvalue=0.0d0
do i=1,my
fvalue=fvalue+(y(i)-targety(i))**2
enddo
do i=1,nx
fvalue=fvalue+(x(i)-targetx(i))**2
enddo
endif
return
end subroutine distcenter
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
subroutine distcentersys(nunknowns,x,fequ,fsqsum)
implicit none
integer nunknowns,idowhat
double precision x(nunknowns),
& fequ(nunknowns),fsqsum
parameter(idowhat=1)
call distcenter(nunknowns,x,fequ,fsqsum,idowhat)
return
end subroutine distcentersys
!-----------------------------------------------------------
subroutine fsqsum_distcenter(nunknowns,x,fsqsum)
implicit none
integer nunknowns,idowhat
double precision x(nunknowns),fsqsum,
& fequ(nunknowns)
parameter(idowhat=1)
call distcenter(nunknowns,x,fequ,fsqsum,idowhat)
return
end
!-----------------------------------------------------------
double precision function f1dimsqsum_distcenter(x)
implicit none
double precision x
INTEGER j,idowhat
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /cpf1com/ pcom,xicom,ncom
save /cpf1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
double precision xt(NMAX),fequ(NMAX)
parameter(idowhat=1)
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call distcenter(ncom,xt,fequ,
& f1dimsqsum_distcenter,idowhat)
return
END
!------------------------------------------------------------
subroutine s2_distcenter(nunknowns,x,s2)
implicit none
integer nunknowns,idowhat
double precision x(nunknowns),s2,fequ(nunknowns)
parameter(idowhat=2)
call distcenter(nunknowns,x,fequ,s2,idowhat)
return
end
!-----------------------------------------------------------
double precision function f1dims2_distcenter(x)
implicit none
double precision x
INTEGER j,idowhat
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /cpf1com/ pcom,xicom,ncom
save /cpf1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
double precision xt(NMAX),fequ(NMAX)
parameter(idowhat=2)
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call distcenter(ncom,xt,fequ,
& f1dims2_distcenter,idowhat)
return
END
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
@@ -0,0 +1,179 @@
subroutine NeuralNetRegres(idowhat,nx0,nobs0,nh0,xsamp0,
&ysamp0,yatxsamp0,rsq,w,bph,q,bend,xnew,ypred)
implicit none
include 'NeuralNetRegres.h'
!
!=============Inputs regardless of idowhat=========================
!idowhat: =1, fit the data and estimate the coefficients. Provide the
! initial guess for the coefficients or set bend to -9999
! =2, coefficients are already available, calculate y at xnew
!nx0: the number of independent (x) variables
!nobs0: the total number of samples
!nh0: the total number of hidden nodes to use. One hidden layer is
! assumed.
!============When idowhat=1========================================
! --------Inputs--------
!xsamp0: the values of the independent (x) variables
!ysamp0: the values of the dependent (y) variable. y is one dimension.
! --------Outputs-------
!w: the slope coefficient to time the normalized x in the activation function
!bph: the intercept coefficient in the activation function
!q: the coefficient to time the value of the activation function
!bend: the residual constant in the neural network regression
!yatxsamp0: the predicted y value at xsamp0
!rsq: R squared
!============When idowhat=2=========================================
! --------Inputs--------
!w: the slope coefficient to time the normalized x in the activation function
!bph: the intercept coefficient in the activation function
!q: the coefficient to time the value of the activation function
!bend: the residual constant in the neural network regression
!xnew: the new x point who y value is to be estimated (when idowhat=2)
! --------Outputs-------
!ypred: the predicted y value at xnew
!
integer idowhat,nx0,nobs0,nh0
double precision xsamp0(nobs0,nx0),ysamp0(nobs0),
& yatxsamp0(nobs0),rsq,w(nx0,nh0),bph(nh0),q(nh0),
& bend,xnew(nx0),ypred
!============Locals=========================================
integer i,j,ndim,ny,INFO,iderivative,iregrestype
!iregrestype=0, ordinary distance regression
double precision xnormk(nx0),xnormb(nx0),std,fmean,
& xmin,xmax,fatbeta,fatbeta0,fatbetacp,ftol,
& beta(nx0*nh0+2*nh0+1),betacp(nx0*nh0+2*nh0+1),rms,
& agrind,ran2,annfunc,weitx(1:nobs0,1:nx0),
& weity(1:nobs0),shortx(1:nobs0,1:nx0),
& shorty(1:nobs0),yv(nobs0),fn9999,tiny
parameter(ftol=1.0d-8,iderivative=1,iregrestype=0,
&fn9999=-9999.0d0,tiny=1.0d-8)
external funkmin_neural,f1dim_neural,FCN_neural
!
if(idowhat.eq.1)then
!Regression
nx=nx0
nobs=nobs0
nh=nh0
!xnormk: the slope of the linear transformation for xsamp0
!xnormb: the intercept of the linear transformation for xsamp0
!Transform xsamp to become bounded (-1,1) so that different independent variables
!are comparable in magnitude
!xmin ~ -1
!xmax ~ +1
do i=1,nobs
ysamp(i)=ysamp0(i)
weity(i)=1.0d0
do j=1,nx
weitx(i,j)=1.0d0
enddo
enddo
do i=1,nx
call stdmaxmeanmin(nobs,xsamp0(1:nobs,i:i),
& std,fmean,xmin,xmax)
if(xmax.eq.xmin)then
xnormk(i)=1.0d0
xnormb(i)=0.0d0
else
xnormk(i)=2.0d0/(xmax-xmin)
xnormb(i)=-(xmax+xmin)/(xmax-xmin)
endif
do j=1,nobs
xsamp(j,i)=xnormk(i)*xsamp0(j,i)+xnormb(i)
enddo
enddo
ndim=2*nh+nh*nx+1
do i=1,ndim
betamin(i)=-1.0d+20
betamax(i)=1.0d+20
enddo
if(dabs(bend-fn9999).lt.tiny)then
!no initial guess. Use the general guess
do i=1,ndim
beta(i)=(ran2()-0.5d0)*2.0d0
enddo
else
!initial guess provided. transform the guessed bph and w coefficients to correspond
!to the transformed x.
do i=1,nh0
do j=1,nx0
w(j,i)=w(j,i)/xnormk(j)
enddo
enddo
do i=1,nh0
do j=1,nx0
bph(i)=bph(i)-w(j,i)*xnormb(j)
enddo
enddo
call coeff_beta(2,nx,nh,beta,w(1:nx,1:nh),bph,q,bend)
endif
do i=1,ndim
betacp(i)=beta(i)
if(beta(i).lt.betamin(i).or.beta(i).gt.betamax(i))then
! write(*,*)'Inproper initial guess in NeuralNetRegres.f'
beta(i)=ran2()
endif
betacp(i)=beta(i)
enddo
call funkmin_neural(ndim,beta,fatbeta0)
INFO=iregrestype
ny=1
fatbeta=fatbeta0
90 call odr_leastsquare(ndim,FCN_neural,beta,nobs,
&xsamp(1:nobs,1:nx),nx,ysamp(1:nobs),ny,weitx(1:nobs,1:nx),
&weity(1:nobs),iderivative,shortx(1:nobs,1:nx),shorty(1:nobs),
&fatbeta,INFO)
call funkmin_neural(ndim,beta,fatbeta)
! if((fatbeta0-fatbeta).gt.ftol)then
! fatbeta0=fatbeta
! do i=1,ndim
! betacp(i)=beta(i)
! enddo
! goto 90
! endif
if(fatbeta.gt.fatbeta0)then
j=0
do i=1,ndim
beta(i)=betacp(i)
if(beta(i).lt.betamin(i).or.beta(i).gt.betamax(i))j=1
enddo
fatbeta=fatbeta0
if(j.ne.0)then
do i=1,ndim
beta(i)=(ran2()-0.5d0)*2.0d0
enddo
call funkmin_neural(ndim,beta,fatbeta)
endif
endif
100 fatbetacp=fatbeta
call nongradopt(ndim,funkmin_neural,f1dim_neural,
&beta,betamin,betamax,ftol,fatbeta)
! call RepeatCompassSearch(ndim,beta,fatbeta,
! &betamin,betamax,funkmin_neural,f1dim_neural,ftol)
! if(dabs(fatbetacp-fatbeta).gt.ftol)goto 100
call funkmin_neural(ndim,beta,fatbeta)
call coeff_beta(idowhat,nx,nh,beta,w(1:nx,1:nh),bph,q,bend)
!transform the estimated bph and w coefficients so that the original x
!values can be used directly.
do i=1,nh0
do j=1,nx0
bph(i)=bph(i)+w(j,i)*xnormb(j)
enddo
enddo
do i=1,nh0
do j=1,nx0
w(j,i)=w(j,i)*xnormk(j)
enddo
enddo
do i=1,nobs0
yatxsamp0(i)=annfunc(nx0,xsamp0(i:i,1:nx0),nh0,q,
& w(1:nx0,1:nh0),bph,bend)
enddo
call rsq_rms(ysamp0,yatxsamp0,nobs0,rsq,rms,agrind)
endif
if(idowhat.eq.2)then
!Predict y at x with the regression coefficients already estimated
ypred=annfunc(nx0,xnew,nh0,q,w(1:nx0,1:nh0),bph,bend)
endif
return
end
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
@@ -0,0 +1,9 @@
integer maxnobs,maxnx,maxnh
parameter(maxnx=30,maxnh=maxnx*10,maxnobs=maxnx*1000)
integer nx,nh,nobs
common /annintegers/nx,nh,nobs
double precision ysamp(maxnobs),xsamp(maxnobs,maxnx),
& betamin(maxnx*maxnh+2*maxnh),
& betamax(maxnx*maxnh+2*maxnh)
common /anndouble/ysamp,xsamp,betamin,betamax
+121
View File
@@ -0,0 +1,121 @@
SUBROUTINE amebsa(p,y,mp,np,ndim,pb,yb,ftol,funk,iter,temptr)
INTEGER iter,mp,ndim,np,NMAX
double precision ftol,temptr,yb,p(mp,np),pb(np),y(mp),funk
PARAMETER (NMAX=200)
EXTERNAL funk
CU USES amotsa,funk,ran1
INTEGER i,idum,ihi,ilo,inhi,j,m,n
double precision rtol,sum,swap,tt,yhi,ylo,ynhi,ysave,yt,ytry,
&psum(NMAX),amotsa,ran1
COMMON /ambsa/ tt,idum
tt=-temptr
1 do 12 n=1,ndim
sum=0.0d0
do 11 m=1,ndim+1
sum=sum+p(m,n)
11 continue
psum(n)=sum
12 continue
2 ilo=1
inhi=1
ihi=2
ylo=y(1)+tt*dlog(ran1(idum))
ynhi=ylo
yhi=y(2)+tt*dlog(ran1(idum))
if (ylo.gt.yhi) then
ihi=1
inhi=2
ilo=2
ynhi=yhi
yhi=ylo
ylo=ynhi
endif
do 13 i=3,ndim+1
yt=y(i)+tt*dlog(ran1(idum))
if(yt.le.ylo) then
ilo=i
ylo=yt
endif
if(yt.gt.yhi) then
inhi=ihi
ynhi=yhi
ihi=i
yhi=yt
else if(yt.gt.ynhi) then
inhi=i
ynhi=yt
endif
13 continue
rtol=2.0d0*dabs(yhi-ylo)/(dabs(yhi)+dabs(ylo))
if(rtol.lt.ftol.or.iter.lt.0) then
swap=y(1)
y(1)=y(ilo)
y(ilo)=swap
do 14 n=1,ndim
swap=p(1,n)
p(1,n)=p(ilo,n)
p(ilo,n)=swap
14 continue
return
endif
iter=iter-2
ytry=amotsa(p,y,psum,mp,np,ndim,pb,yb,funk,ihi,yhi,-1.0d0)
if (ytry.le.ylo) then
ytry=amotsa(p,y,psum,mp,np,ndim,pb,yb,funk,ihi,yhi,2.0d0)
else if (ytry.ge.ynhi) then
ysave=yhi
ytry=amotsa(p,y,psum,mp,np,ndim,pb,yb,funk,ihi,yhi,0.5d0)
if (ytry.ge.ysave) then
do 16 i=1,ndim+1
if(i.ne.ilo)then
do 15 j=1,ndim
psum(j)=0.5d0*(p(i,j)+p(ilo,j))
p(i,j)=psum(j)
15 continue
y(i)=funk(psum)
endif
16 continue
iter=iter-ndim
goto 1
endif
else
iter=iter+1
endif
goto 2
END
double precision FUNCTION amotsa
&(p,y,psum,mp,np,ndim,pb,yb,funk,ihi,yhi,fac)
INTEGER ihi,mp,ndim,np,NMAX
double precision amotsa,fac,yb,yhi,p(mp,np),pb(np),psum(np),
&y(mp),funk
PARAMETER (NMAX=200)
EXTERNAL funk
CU USES funk,ran1
INTEGER idum,j
double precision fac1,fac2,tt,yflu,ytry,ptry(NMAX),ran1
COMMON /ambsa/ tt,idum
fac1=(1.-fac)/ndim
fac2=fac1-fac
do 11 j=1,ndim
ptry(j)=psum(j)*fac1-p(ihi,j)*fac2
11 continue
ytry=funk(ptry)
if (ytry.le.yb) then
do 12 j=1,ndim
pb(j)=ptry(j)
12 continue
yb=ytry
endif
yflu=ytry-tt*log(ran1(idum))
if (yflu.lt.yhi) then
y(ihi)=ytry
yhi=yflu
do 13 j=1,ndim
psum(j)=psum(j)-p(ihi,j)+ptry(j)
p(ihi,j)=ptry(j)
13 continue
endif
amotsa=yflu
return
END
@@ -0,0 +1,103 @@
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
double precision function annfunc(nparams,params,nh,q,w,bph,bend)
implicit none
integer nparams,nh
!nh is the number of hidden nodes in one hiden layer
!params is the inputs
!w is the weighting coefficients for the inputs
double precision params(nparams),q(nh),
&w(nparams,nh),bph(nh),bend
integer i,v
double precision term,activatefunc
annfunc=bend
do i=1,nh
term=bph(i)
do v=1,nparams
term=term+w(v,i)*params(v)
enddo
annfunc=annfunc+q(i)*activatefunc(term)
enddo
end
subroutine derannfunc(nparams,params,nh,q,w,bph,
& bend,derq,derw,derbph,derbend)
implicit none
integer nparams,nh
!nh is the number of hidden nodes in one hiden layer
!params is the inputs
!w is the weighting coefficients for the inputs
double precision params(nparams),q(nh),w(nparams,nh),
&bph(nh),bend,derq(nh),derw(nparams,nh),derbph(nh),derbend
integer i,v
double precision term,activatefunc,gradactivatefunc
derbend=1.0d0
do i=1,nh
term=bph(i)
do v=1,nparams
term=term+w(v,i)*params(v)
enddo
derq(i)=activatefunc(term)
derbph(i)=q(i)*gradactivatefunc(term)
do v=1,nparams
derw(v,i)=derbph(i)*params(v)
enddo
enddo
end
double precision function activatefunc(x)
implicit none
double precision x,crit
parameter(crit=300)
! activatefunc=2.0d0*datan(x)/3.14159265d0
! return
if(x.gt.-crit)then
activatefunc=1.0d0/(1.0d0+dexp(-x))
else
activatefunc=dexp(x)/(1.0d0+dexp(x))
endif
return
end
double precision function gradactivatefunc(x)
implicit none
double precision x,crit
parameter(crit=600)
! gradactivatefunc=2.0d0/(3.14159265d0*(1.0d0+x*x))
! return
if(x.gt.-crit.and.x.lt.crit)then
gradactivatefunc=
& (1.0d0/(dexp(x/2.0d0)+dexp(-x/2.0d0)))**2
else
gradactivatefunc=0.0d0
endif
return
end
subroutine gradannfunc(nparams,params,nh,q,w,bph,
&der_params)
implicit none
integer nparams,nh
double precision params(nparams),der_params(nparams),
&q(nh),w(nparams,nh),bph(nh)
integer i,v
double precision term,dsigdterm,
& gradactivatefunc,activatefunc
do i=1,nparams
der_params(i)=0.0d0
enddo
do i=1,nh
term=bph(i)
do v=1,nparams
term=term+w(v,i)*params(v)
enddo
dsigdterm=gradactivatefunc(term)
do v=1,nparams
der_params(v)=der_params(v)+q(i)*dsigdterm*w(v,i)
enddo
enddo
return
end
+49
View File
@@ -0,0 +1,49 @@
subroutine coeff_beta(idowhat,nx,nh,BETA,w,bph,q,bend)
implicit none
!idowhat=1, allocate BETA to w, bph, q
! =2, allocate w, bph, q to BETA
!
integer k,i,nx,nh,j,idowhat
double precision w(1:nx,1:nh),bph(nh),q(nh),
& bend,BETA(nx*nh+2*nh+1)
if(idowhat.eq.1)then
k=0
do i=1,nx
do j=1,nh
k=k+1
w(i,j)=BETA(k)
enddo
enddo
do i=1,nh
k=k+1
bph(i)=BETA(k)
enddo
do i=1,nh
k=k+1
q(i)=BETA(k)
enddo
k=k+1
bend=BETA(k)
endif
!
if(idowhat.eq.2)then
k=0
do i=1,nx
do j=1,nh
k=k+1
BETA(k)=w(i,j)
enddo
enddo
do i=1,nh
k=k+1
BETA(k)=bph(i)
enddo
do i=1,nh
k=k+1
BETA(k)=q(i)
enddo
k=k+1
BETA(k)=bend
endif
return
end
@@ -0,0 +1,198 @@
subroutine cpRepeatCompassSearch(ndim,xbest,fbest,
& bmin,bmax,funkmin,f1dim,xtol)
implicit none
integer ndim
double precision xbest(1:ndim),fbest,
& bmin(1:ndim),bmax(1:ndim),xtol
double precision fvalpre,dmax,xpre(1:ndim),ftol,direction(ndim)
parameter(ftol=1.0d-7)
integer i,n
logical resetran2
common /cpran2reset/resetran2
external funkmin,f1dim
!
n=0
resetran2=.true.
10 fvalpre=fbest
do i=1,ndim
xpre(i)=xbest(i)
enddo
call cpCompassSearch(ndim,xbest,fbest,
& bmin,bmax,funkmin,f1dim,xtol)
n=n+1
dmax=dabs(xbest(1)-xpre(1))
do i=2,ndim
if(dmax.lt.dabs(xbest(i)-xpre(i)))then
dmax=dabs(xbest(i)-xpre(i))
endif
enddo
if(dabs(fvalpre-fbest).gt.ftol.and.
& dmax.gt.xtol.and.n.lt.5000)then
do i=1,ndim
direction(i)=xbest(i)-xpre(i)
enddo
call linmin(xbest,bmin,bmax,direction,
& ndim,f1dim,fbest)
goto 10
endif
return
end subroutine cpRepeatCompassSearch
subroutine cpCompassSearch(ndim,xbest,fbest,
& bmin,bmax,funkmin,f1dim,xtol)
implicit none
! This subroutine minimizes the function funkmin using the compass search method. The ! maximum number of function evaluations is maxiter. Once mexiter is reached, all
! function evaluations are ranked and returned.
!
!------------------------------------- Inputs -----------------------------------------------------
! maxiter: the maximum number of function evaluations allowed
! xbest: the initial guess
! fbest: the cost function value at xinitial
! bmin: the lower bounds of the parameters to be optimized
! bmax: the upper bounds of the parameters to be optimized
! ndim: the number of parameters to optimize
! funkmin: the name of the function to minimize
!------------------------------------- Outputs ---------------------------------------------------
! xobs: points where the function is evaluated. Ranked from the best to worst with the
! first point being the best point.
! fvalue: the function values at xobs
! ierr: =0 convergence criterion not reached
! =1 convergence criterion reached (minimum found)
!
integer ndim
double precision xbest(1:ndim),fbest,
& bmin(1:ndim),bmax(1:ndim),xtol,dx1,dx2
external funkmin,f1dim
!------------------------------- Locals -----------------------------------------------------------
double precision diftol,delta,
& xcompass(1:2*ndim,1:ndim),fcompass(1:2*ndim),
& xvec(1:ndim),xcent(1:ndim),fcent,dif,shrink,
& direction(ndim),dmax,fcent0,cpran2_reset
parameter(shrink=0.618d0,diftol=1.0d-7)
integer i,j,k
!
delta=0.618d0
do i=1,ndim
xcent(i)=xbest(i)
enddo
fcent=fbest
10 continue
do i=1,ndim
do j=1,ndim
xcompass(i,j)=xcent(j)
xcompass(ndim+i,j)=xcent(j)
enddo
xcompass(i,i)=xcent(i)+delta*(bmax(i)-xcent(i))
xcompass(ndim+i,i)=xcent(i)+delta*(bmin(i)-xcent(i))
enddo
do i=1,2*ndim
do j=1,ndim
xvec(j)=xcompass(i,j)
enddo
call funkmin(ndim,xvec,fcompass(i))
enddo
do i=1,ndim
xbest(i)=xcompass(1,i)
enddo
fbest=fcompass(1)
do i=2,2*ndim
if(fcompass(i).lt.fbest)then
fbest=fcompass(i)
do j=1,ndim
xbest(j)=xcompass(i,j)
enddo
endif
enddo
fcent0=fcent
do i=1,ndim
xvec(i)=xcent(i)
enddo
do i=1,ndim
dx1=xcompass(i,i)-xcent(i)
dx2=xcent(i)-xcompass(i+ndim,i)
direction(i)=0.0d0
if(dx1.ne.0.0d0)then
direction(i)=(fcompass(i)-fcent)/dx1
endif
if(dx2.ne.0.0d0)then
direction(i)=direction(i)+
& (fcent-fcompass(i+ndim))/dx2
endif
direction(i)=-0.5d0*direction(i)
if(direction(i).eq.0.0d0)direction(i)=
& cpran2_reset()-0.5d0
enddo
call cplinmin(xcent,bmin,bmax,direction,
& ndim,f1dim,fcent)
if(fcent.gt.fcent0)then
fcent=fcent0
do i=1,ndim
xcent(i)=xvec(i)
enddo
endif
dif=fcent-fbest
if(fbest.le.fcent)then
fcent=fbest
do i=1,ndim
xcent(i)=xbest(i)
enddo
endif
if(dif.ge.0.0d0)then
if(dif.gt.diftol)goto 10
if(delta.lt.diftol)goto 100
delta=delta*shrink
goto 10
else
!no progress
if(dabs(dif).gt.diftol)then
if(delta.lt.diftol)goto 100
delta=delta*shrink
goto 10
endif
dmax=dabs(xcompass(1,1)-xcompass(ndim+1,1))
do i=2,ndim
if(dmax.lt.dabs(xcompass(i,i)-
& xcompass(ndim+i,i)))then
dmax=dabs(xcompass(i,i)-
& xcompass(ndim+i,i))
endif
enddo
if(dmax.gt.xtol)then
if(delta.lt.diftol)goto 100
delta=delta*shrink
goto 10
else
goto 100
endif
endif
100 fbest=fcent
do i=1,ndim
xbest(i)=xcent(i)
dx1=xcompass(i,i)-xcent(i)
dx2=xcent(i)-xcompass(i+ndim,i)
direction(i)=0.0d0
if(dx1.ne.0.0d0)then
direction(i)=(fcompass(i)-fcent)/dx1
endif
if(dx2.ne.0.0d0)then
direction(i)=direction(i)+
& (fcent-fcompass(i+ndim))/dx2
endif
direction(i)=-0.5d0*direction(i)
if(direction(i).eq.0.0d0)direction(i)=
& cpran2_reset()-0.5d0
enddo
call cplinmin(xcent,bmin,bmax,direction,
& ndim,f1dim,fcent)
if(fcent.lt.fbest)then
fbest=fcent
do i=1,ndim
xbest(i)=xcent(i)
enddo
endif
return
end subroutine cpCompassSearch
+247
View File
@@ -0,0 +1,247 @@
subroutine cpnongradopt(ndim,funkmin,f1dim,beta,
& bmin,bmax,ftol,fatbeta)
implicit none
!
! This subroutine minimizes function funkmin to estimate ndim parameters
! using non-gradient based methods
!
integer ndim
double precision beta(1:ndim),bmin(1:ndim),
& bmax(1:ndim),ftol,fatbeta
!
! ------------------ Inputs -----------------------------
! ndim: the total number of parameters to be estimated
! bmax: the maximum possible value of beta, used to determine the distance scaling factor
! bmin: the minimum possible value of beta, used to determine the distance scaling factor
! beta: initial guess, overwritten upon return
! ftol: tolerance for convergence
! fatbeta: the cost function valuate at beta, overwritten upon return
! funkmin is the name of the subroutine that computes the cost function
! f1dim: the one dimensional cost function
! ------------------ Outputs ----------------------------
! beta: The best parameters obtained
! fatbeta: the cost function value at beta
integer n,nn,mpamoeba,npamoeba,iredo,maxredo,ITMAX,
& icycle
parameter(maxredo=20,ITMAX=20000)
double precision fbest,xbest(1:ndim),
& xinidir(1:ndim,1:ndim),xbest0(1:ndim),
& pamoeba(1:ndim+1,1:ndim),famoeba(1:ndim+1)
external funkmin,f1dim
! End of declaration of variables
!---------------------------------------------------------------
icycle=0
1 iredo=0
3 do n=1,ndim
xbest(n)=beta(n)
do nn=1,ndim
xinidir(n,nn)=0.0d0
enddo
xinidir(n,n)=1.0d0
enddo
fbest=fatbeta
call cppowell(beta,xinidir(1:ndim,1:ndim),ndim,
&ndim,ftol,fatbeta,bmin,bmax,funkmin,f1dim,ITMAX)
if(fatbeta.gt.fbest)then
do n=1,ndim
beta(n)=xbest(n)
enddo
fatbeta=fbest
goto 10
endif
if((fbest-fatbeta).gt.ftol)then
if(iredo.gt.maxredo)goto 10
iredo=iredo+1
goto 3
endif
10 iredo=0
20 do n=1,ndim
xbest(n)=beta(n)
enddo
fbest=fatbeta
do nn=1,ndim
pamoeba(1,nn)=beta(nn)
enddo
famoeba(1)=fatbeta
do n=2,ndim+1
do nn=1,ndim
pamoeba(n,nn)=beta(nn)
enddo
if((bmax(n-1)-pamoeba(n,n-1))
& .gt.(pamoeba(n,n-1)-bmin(n-1)))then
pamoeba(n,n-1)=pamoeba(n,n-1)+
& (bmax(n-1)-pamoeba(n,n-1))*0.1d0
else
pamoeba(n,n-1)=pamoeba(n,n-1)-
& (pamoeba(n,n-1)-bmin(n-1))*0.1d0
endif
do nn=1,ndim
xbest0(nn)=pamoeba(n,nn)
enddo
call funkmin(ndim,xbest0,famoeba(n))
enddo
mpamoeba=ndim+1
npamoeba=ndim
call cpguamoeba(pamoeba(1:ndim+1,1:ndim),
& famoeba(1:ndim+1),mpamoeba,npamoeba,ndim,
& ftol,funkmin,ITMAX/20)
nn=1
do n=2,ndim+1
if(famoeba(n).lt.famoeba(nn))nn=n
enddo
fatbeta=famoeba(nn)
do n=1,ndim
beta(n)=pamoeba(nn,n)
if(beta(n).lt.bmin(n).or.beta(n).gt.bmax(n))then
do nn=1,ndim
beta(nn)=xbest(nn)
enddo
fatbeta=fbest
return
endif
enddo
if((fbest-fatbeta).gt.ftol)then
if(iredo.gt.maxredo)then
if(icycle.lt.maxredo)then
icycle=icycle+1
goto 1
else
return
endif
endif
iredo=iredo+1
goto 20
endif
return
end subroutine cpnongradopt
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
SUBROUTINE cpguamoeba(p,y,mp,np,ndim,ftol,funkmin,ITMAX)
implicit none
INTEGER iter,mp,ndim,np,NMAX,ITMAX
double precision ftol,p(mp,np),y(mp),TINY
PARAMETER (TINY=1.0d-20)
external funkmin
CU USES cpguamotry,funkmin
INTEGER i,ihi,ilo,inhi,j,m,n
double precision rtol,sum,swap,ysave,ytry,psum(ndim),
& cpguamotry,degen
iter=0
1 do 12 n=1,ndim
sum=0.0d0
do 11 m=1,ndim+1
sum=sum+p(m,n)
11 continue
psum(n)=sum
12 continue
2 ilo=1
if (y(1).gt.y(2)) then
ihi=1
inhi=2
else
ihi=2
inhi=1
endif
do 13 i=1,ndim+1
if(y(i).le.y(ilo)) ilo=i
if(y(i).gt.y(ihi)) then
inhi=ihi
ihi=i
else if(y(i).gt.y(inhi)) then
if(i.ne.ihi) inhi=i
endif
13 continue
rtol=2.0d0*dabs(y(ihi)-y(ilo))/
& (dabs(y(ihi))+dabs(y(ilo))+TINY)
if (rtol.lt.ftol) then
swap=y(1)
y(1)=y(ilo)
y(ilo)=swap
do 14 n=1,ndim
swap=p(1,n)
p(1,n)=p(ilo,n)
p(ilo,n)=swap
14 continue
return
endif
! check to see if the simplex is degenerate; if so, stop
degen=0.0d0
do i=1,mp
do m=i+1,mp
do n=1,np
if(dabs(p(m,n)-p(i,n)).gt.degen)then
degen=dabs(p(m,n)-p(i,n))
endif
enddo
enddo
enddo
if(degen.lt.ftol*ftol)then
swap=y(1)
y(1)=y(ilo)
y(ilo)=swap
do n=1,ndim
swap=p(1,n)
p(1,n)=p(ilo,n)
p(ilo,n)=swap
enddo
return
endif
if(iter.ge.ITMAX)return
iter=iter+2
ytry=cpguamotry(p,y,psum,mp,np,ndim,funkmin,ihi,-1.0d0)
if (ytry.le.y(ilo))then
ytry=cpguamotry(p,y,psum,mp,np,ndim,funkmin,ihi,2.0d0)
else if (ytry.ge.y(inhi)) then
ysave=y(ihi)
ytry=cpguamotry(p,y,psum,mp,np,ndim,funkmin,ihi,0.5d0)
if (ytry.ge.ysave) then
do 16 i=1,ndim+1
if(i.ne.ilo)then
do 15 j=1,ndim
psum(j)=0.5d0*(p(i,j)+p(ilo,j))
p(i,j)=psum(j)
15 continue
call funkmin(ndim,psum,y(i))
endif
16 continue
iter=iter+ndim
goto 1
endif
else
iter=iter-1
endif
goto 2
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
DOUBLE PRECISION FUNCTION cpguamotry(p,y,psum,
& mp,np,ndim,funkmin,ihi,fac)
implicit none
INTEGER ihi,mp,ndim,np
double precision fac,p(mp,np),psum(np),y(mp)
EXTERNAL funkmin
CU USES funkmin
INTEGER j
double precision fac1,fac2,ytry,ptry(ndim)
fac1=(1.0d0-fac)/dble(ndim)
fac2=fac1-fac
do 11 j=1,ndim
ptry(j)=psum(j)*fac1-p(ihi,j)*fac2
11 continue
call funkmin(ndim,ptry,ytry)
if (ytry.lt.y(ihi)) then
y(ihi)=ytry
do 12 j=1,ndim
psum(j)=psum(j)-p(ihi,j)+ptry(j)
p(ihi,j)=ptry(j)
12 continue
endif
cpguamotry=ytry
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
c#######################################################################
@@ -0,0 +1,152 @@
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
subroutine cpodr_leastsquare(nparams,FCN,params,
& npoints,xobs,yobs,iderivative,INFO)
implicit none
!if derivatives are provided, set iderivative to 1, otherwise set it to 0
C ODRPACK ARGUMENT DEFINITIONS
C ==> FCN NAME OF THE USER SUPPLIED FUNCTION SUBROUTINE
C ==> N NUMBER OF OBSERVATIONS
C ==> M COLUMNS OF DATA IN THE EXPLANATORY VARIABLE
C ==> NP NUMBER OF PARAMETERS
C ==> NQ NUMBER OF RESPONSES PER OBSERVATION
C <==> BETA FUNCTION PARAMETERS
C ==> Y RESPONSE VARIABLE
C ==> LDY LEADING DIMENSION OF ARRAY Y
C ==> X EXPLANATORY VARIABLE
C ==> LDX LEADING DIMENSION OF ARRAY X
C ==> WE "EPSILON" WEIGHTS
C ==> LDWE LEADING DIMENSION OF ARRAY WE
C ==> LD2WE SECOND DIMENSION OF ARRAY WE
C ==> WD "DELTA" WEIGHTS
C ==> LDWD LEADING DIMENSION OF ARRAY WD
C ==> LD2WD SECOND DIMENSION OF ARRAY WD
C ==> IFIXB INDICATORS FOR "FIXING" PARAMETERS (BETA)
C ==> IFIXX INDICATORS FOR "FIXING" EXPLANATORY VARIABLE (X)
C ==> LDIFX LEADING DIMENSION OF ARRAY IFIXX
C ==> JOB TASK TO BE PERFORMED
C ==> NDIGIT GOOD DIGITS IN SUBROUTINE FUNCTION RESULTS
C ==> TAUFAC TRUST REGION INITIALIZATION FACTOR
C ==> SSTOL SUM OF SQUARES CONVERGENCE CRITERION
C ==> PARTOL PARAMETER CONVERGENCE CRITERION
C ==> MAXIT MAXIMUM NUMBER OF ITERATIONS
C ==> IPRINT PRINT CONTROL
C ==> LUNERR LOGICAL UNIT FOR ERROR REPORTS
C ==> LUNRPT LOGICAL UNIT FOR COMPUTATION REPORTS
C ==> STPB STEP SIZES FOR FINITE DIFFERENCE DERIVATIVES WRT BETA
C ==> STPD STEP SIZES FOR FINITE DIFFERENCE DERIVATIVES WRT DELTA
C ==> LDSTPD LEADING DIMENSION OF ARRAY STPD
C ==> SCLB SCALE VALUES FOR PARAMETERS BETA
C ==> SCLD SCALE VALUES FOR ERRORS DELTA IN EXPLANATORY VARIABLE
C ==> LDSCLD LEADING DIMENSION OF ARRAY SCLD
C <==> WORK DOUBLE PRECISION WORK VECTOR
C ==> LWORK DIMENSION OF VECTOR WORK
C <== IWORK INTEGER WORK VECTOR
C ==> LIWORK DIMENSION OF VECTOR IWORK
C <== INFO STOPPING CONDITION
C PARAMETERS SPECIFYING MAXIMUM PROBLEM SIZES HANDLED BY THIS DRIVER
C MAXN MAXIMUM NUMBER OF OBSERVATIONS
C MAXM MAXIMUM NUMBER OF COLUMNS IN EXPLANATORY VARIABLE
C MAXNP MAXIMUM NUMBER OF FUNCTION PARAMETERS
C MAXNQ MAXIMUM NUMBER OF RESPONSES PER OBSERVATION
C PARAMETER DECLARATIONS AND SPECIFICATIONS
INTEGER LDIFX,LDSCLD,LDSTPD,LDWD,LDWE,LDX,LDY,LD2WD,LD2WE,
+ LIWORK,LWORK,MAXM,MAXN,MAXNP,MAXNQ
PARAMETER (MAXM=25,MAXN=10000,MAXNP=30,MAXNQ=1,
+ LDY=MAXN,LDX=MAXN,
+ LDWE=1,LD2WE=1,LDWD=1,LD2WD=1,
+ LDIFX=MAXN,LDSTPD=1,LDSCLD=1,
+ LWORK=18 + 11*MAXNP + MAXNP**2 + MAXM + MAXM**2 +
+ 4*MAXN*MAXNQ + 6*MAXN*MAXM + 2*MAXN*MAXNQ*MAXNP +
+ 2*MAXN*MAXNQ*MAXM + MAXNQ**2 +
+ 5*MAXNQ + MAXNQ*(MAXNP+MAXM) + LDWE*LD2WE*MAXNQ,
+ LIWORK=20+MAXNP+MAXNQ*(MAXNP+MAXM))
C VARIABLE DECLARATIONS
INTEGER I,INFO,IPRINT,J,JOB,L,LUNERR,LUNRPT,M,MAXIT,N,
+ NDIGIT,NP,NQ
INTEGER IFIXB(MAXNP),IFIXX(LDIFX,MAXM),IWORK(LIWORK)
DOUBLE PRECISION PARTOL,SSTOL,TAUFAC
DOUBLE PRECISION BETA(MAXNP),SCLB(MAXNP),SCLD(LDSCLD,MAXM),
+ STPB(MAXNP),STPD(LDSTPD,MAXM),
+ WD(LDWD,LD2WD,MAXM),WE(LDWE,LD2WE,MAXNQ),
+ WORK(LWORK),X(LDX,MAXM),Y(LDY,MAXNQ)
c
integer npoints,i1,i2,i3,i4,i5,nparams,iderivative
double precision yobs(npoints),xobs(npoints),
& params(nparams)
EXTERNAL FCN
c
C SPECIFY DEFAULT VALUES FOR DODRC ARGUMENTS
WE(1,1,1) = -1.0D0
WD(1,1,1) = -1.0D0
IFIXB(1) = -1
! IFIXX(1,1) = -1
if(iderivative.eq.0)then
!no derivatives provided, using central finite difference
JOB=13
else
JOB=43
endif
NDIGIT = -1
TAUFAC = -1.0D0
SSTOL = -1.0D0
PARTOL = -1.0D0
MAXIT = -1
! IPRINT = -1
IPRINT=0
LUNERR = -1
LUNRPT = -1
STPB(1) = -1.0D0
STPD(1,1) = -1.0D0
SCLB(1) = -1.0D0
SCLD(1,1) = -1.0D0
MAXIT = 200000
C SET UP ODRPACK REPORT FILES
LUNERR = 107
LUNRPT = 108
c
N=npoints
NP=nparams
M=1
NQ=1
do I=1,NP
BETA(I)=params(I)
enddo
do I=1,N
X(I,1)=xobs(I)
Y(I,1)=yobs(I)
enddo
NQ=1
C READ PROBLEM DATA, AND SET NONDEFAULT VALUE FOR ARGUMENT IFIXX
DO 10 I=1,N
DO 15 J=1, M
IFIXX(I,J) = 1
15 CONTINUE
10 CONTINUE
60 CALL DODRC(FCN,
+ N,M,NP,NQ,
+ BETA,
+ Y,LDY,X,LDX,
+ WE,LDWE,LD2WE,WD,LDWD,LD2WD,
+ IFIXB,IFIXX,LDIFX,
+ JOB,NDIGIT,TAUFAC,
+ SSTOL,PARTOL,MAXIT,
+ IPRINT,LUNERR,LUNRPT,
+ STPB,STPD,LDSTPD,
+ SCLB,SCLD,LDSCLD,
+ WORK,LWORK,IWORK,LIWORK,
+ INFO)
i1=mod(INFO,10)
i2=(mod(INFO,100)-i1)/10
i3=(mod(INFO,1000)-mod(INFO,100))/100
i4=(mod(INFO,10000)-mod(INFO,1000))/1000
i5=(INFO-mod(INFO,10000))/10000
do I=1,NP
params(I)=BETA(I)
enddo
return
END
+344
View File
@@ -0,0 +1,344 @@
SUBROUTINE cppowell(p,xi,n,np,ftol,fret,pmin,pmax,
& funkmin,f1dim,ITMAX)
! fret must be given on entry
implicit none
INTEGER iter,n,np,NMAX,ITMAX
double precision fret,ftol,p(np),xi(np,np),TINY,
& pmin(np),pmax(np)
PARAMETER (NMAX=1000,TINY=1.0d-25)
CU USES funkmin,linmin
INTEGER i,ibig,j
double precision del,fp,fptt,t,pt(NMAX),
& ptt(NMAX),xit(NMAX)
external funkmin,f1dim
do 11 j=1,n
pt(j)=p(j)
11 continue
iter=0
1 iter=iter+1
fp=fret
ibig=0
del=0.0d0
do 13 i=1,n
do 12 j=1,n
xit(j)=xi(j,i)
12 continue
fptt=fret
call cplinmin(p,pmin,pmax,xit,n,f1dim,fret)
if(fptt-fret.gt.del)then
del=fptt-fret
ibig=i
endif
13 continue
if(2.0d0*(fp-fret).le.ftol*(dabs(fp)+dabs(fret))+TINY)return
if(iter.eq.ITMAX)then
! write(*,*)'powell exceeding maximum iterations'
return
endif
do 14 j=1,n
ptt(j)=2.0d0*p(j)-pt(j)
xit(j)=p(j)-pt(j)
pt(j)=p(j)
14 continue
call funkmin(n,ptt,fptt)
if(fptt.ge.fp)goto 1
t=2.0d0*(fp-2.0d0*fret+fptt)*(fp-fret-del)**2-
& del*(fp-fptt)**2
if(t.ge.0.0d0)goto 1
call cplinmin(p,pmin,pmax,xit,n,f1dim,fret)
do 15 j=1,n
xi(j,ibig)=xi(j,n)
xi(j,n)=xit(j)
15 continue
goto 1
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
SUBROUTINE cplinmin(p,pmin,pmax,xi,n,f1dim,fret)
implicit none
INTEGER n
double precision fret,p(n),xi(n),TOL,pmin(n),pmax(n)
PARAMETER (TOL=1.0d-8)
CU USES brent,f1dim,mnbrak
INTEGER j,k,ierr
double precision ax,bx,fa,fb,fx,xmin,xx,cpbrent,xxmin,xxmax
!((((((((((((((((((((((((((((((((((((((((((((((((((((
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /cpf1com/ pcom,xicom,ncom
save /cpf1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
EXTERNAL f1dim
ncom=n
do j=1,n
pcom(j)=p(j)
xicom(j)=xi(j)
enddo
xxmax=1.0d+100
xxmin=-1.0d+100
do j=1,n
if(xicom(j).gt.1.0d-100)then
! if(xicom(j).gt.0.0d0)then
xx=(pmax(j)-pcom(j))/xicom(j)
ax=(pmin(j)-pcom(j))/xicom(j)
else
if(xicom(j).lt.(-1.0d-100))then
! if(xicom(j).lt.0.0d0)then
ax=(pmax(j)-pcom(j))/xicom(j)
xx=(pmin(j)-pcom(j))/xicom(j)
else
xx=1.0d+100
ax=-1.0d+100
endif
endif
if(xxmax.gt.xx)then
xxmax=xx
endif
if(xxmin.lt.ax)then
xxmin=ax
endif
enddo
ax=0.0d0
if(dabs(xxmax).gt.dabs(xxmin))then
xx=0.25d0*xxmax
else
xx=0.25d0*xxmin
endif
call cpmnbrak(ax,xx,bx,fa,fx,fb,
& xxmin,xxmax,ierr,f1dim)
if(ierr.eq.0)then
fret=cpbrent(ax,xx,bx,f1dim,TOL,xmin)
else
xmin=xx
fret=fx
endif
do 12 j=1,n
xi(j)=xmin*xi(j)
p(j)=p(j)+xi(j)
12 continue
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
!
double precision function cpbrent(ax,bx,cx,f,tol,xmin)
implicit none
INTEGER ITMAX
double precision ax,bx,cx,tol,xmin,f,CGOLD,ZEPS
EXTERNAL f
PARAMETER (ITMAX=10000,CGOLD=.381966d0,ZEPS=1.0d-10)
INTEGER iter
double precision a,b,d,e,etemp,fu,fv,fw,fx,p,q,r,tol1,
& tol2,u,v,w,x,xm
a=dmin1(ax,cx)
b=dmax1(ax,cx)
v=bx
w=v
x=v
e=0.0d0
fx=f(x)
fv=fx
fw=fx
do 11 iter=1,ITMAX
xm=0.5d0*(a+b)
tol1=tol*dabs(x)+ZEPS
tol2=2.0d0*tol1
if(dabs(x-xm).le.(tol2-.5d0*(b-a))) goto 3
if(dabs(e).gt.tol1) then
r=(x-w)*(fx-fv)
q=(x-v)*(fx-fw)
p=(x-v)*q-(x-w)*r
q=2.0d0*(q-r)
if(q.gt.0.0d0) p=-p
q=dabs(q)
etemp=e
e=d
if(dabs(p).ge.dabs(.5d0*q*etemp).or.
& p.le.q*(a-x).or.p.ge.q*(b-x))goto 1
d=p/q
u=x+d
if(u-a.lt.tol2.or.b-u.lt.tol2)d=dsign(tol1,xm-x)
goto 2
endif
1 if(x.ge.xm)then
e=a-x
else
e=b-x
endif
d=CGOLD*e
2 if(dabs(d).ge.tol1) then
u=x+d
else
u=x+dsign(tol1,d)
endif
fu=f(u)
if(fu.le.fx)then
if(u.ge.x)then
a=x
else
b=x
endif
v=w
fv=fw
w=x
fw=fx
x=u
fx=fu
else
if(u.lt.x) then
a=u
else
b=u
endif
if(fu.le.fw.or.w.eq.x)then
v=w
fv=fw
w=u
fw=fu
else if(fu.le.fv.or.v.eq.x.or.v.eq.w)then
v=u
fv=fu
endif
endif
11 continue
! write(*,*) 'brent exceed maximum iterations'
3 xmin=x
cpbrent=fx
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
! double precision function f1dim(x)
! implicit none
! double precision x
!CU USES funkmin
! INTEGER j
!((((((((((((((((((((((((((((((((((((((((((((((((((((
! integer NMAX,ncom
! parameter(NMAX=1000)
! double precision pcom(NMAX),xicom(NMAX)
! COMMON /cpf1com/ pcom,xicom,ncom
! save /cpf1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
! double precision xt(NMAX)
! do 11 j=1,ncom
! xt(j)=pcom(j)+x*xicom(j)
!11 continue
! call funkmin(ncom,xt,f1dim)
! return
! END
!C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
SUBROUTINE cpmnbrak(ax,bx,cx,fa,fb,fc,xxmin,xxmax,
& ierr,func)
implicit none
double precision ax,bx,cx,fa,fb,fc,
& func,GOLD,GLIMIT,TINY
EXTERNAL func
PARAMETER(GOLD=1.618034d0,GLIMIT=100.0d0,TINY=1.0d-20)
double precision dum,fu,q,r,u,ulim,xxmin,xxmax
integer ierr
ierr=0
fa=func(ax)
fb=func(bx)
if(fb.gt.fa)then
dum=ax
ax=bx
bx=dum
dum=fb
fb=fa
fa=dum
endif
if(fa.eq.fb)then
cx=(bx+ax)/2.0d0
fc=func(cx)
if(fc.le.fa)return
endif
cx=bx+GOLD*(bx-ax)
if(cx.le.xxmin)then
cx=0.5d0*(dmin1(ax,bx)+xxmin)
endif
if(cx.ge.xxmax)then
cx=0.5d0*(dmax1(ax,bx)+xxmax)
endif
fc=func(cx)
1 if(fb.ge.fc)then
r=(bx-ax)*(fb-fc)
q=(bx-cx)*(fb-fa)
u=bx-((bx-cx)*q-(bx-ax)*r)/
& (2.0d0*dsign(dmax1(dabs(q-r),TINY),q-r))
ulim=bx+GLIMIT*(cx-bx)
if(ulim.ge.xxmax)then
ulim=xxmax-tiny
endif
if(ulim.le.xxmin)then
ulim=xxmin+tiny
endif
if((bx-u)*(u-cx).gt.0.0d0)then
fu=func(u)
if(fu.lt.fc)then
ax=bx
fa=fb
bx=u
fb=fu
return
elseif(fu.gt.fb)then
cx=u
fc=fu
return
endif
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fu=func(u)
elseif((cx-u)*(u-ulim).gt.0.0d0)then
fu=func(u)
if(fu.lt.fc)then
bx=cx
cx=u
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fb=fc
fc=fu
fu=func(u)
endif
else if((u-ulim)*(ulim-cx).ge.0.0d0)then
u=ulim
fu=func(u)
else
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fu=func(u)
endif
ax=bx
bx=cx
cx=u
fa=fb
fb=fc
fc=fu
r=dmin1(dabs(ax-bx),dabs(ax-cx))
r=dmin1(r,dabs(bx-cx))
if(r.lt.tiny)then
! bracketing failed
ierr=1
return
endif
goto 1
endif
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+119
View File
@@ -0,0 +1,119 @@
subroutine distancesys(nunknowns,scldxp,
& scldfequ,scldfsqsum,idowhat)
implicit none
!
!--------------------- Variables through arguments -------------------------
!(in) nunknowns: the number of unknowns and non-linear equations
!(in) scldxp(1:nunknowns): the scaled unknowns in the nonlinear system
!(out) scldfequ(1:nunknowns): the scaled function values evaluated at imported unknowns
!(out) scldfsqsum: half of the sum of the squared scaled function values.
integer nunknowns,idowhat
double precision scldxp(1:nunknowns),
& scldfequ(1:nunknowns),scldfsqsum
!--------------------------- Local variables-----------------------------------
integer i,j,numys
parameter
double precision xvar(nunknowns),xscalingfact(nunknowns),
& xtarget(nunknowns),yvar(numys),yscalingfact(numys),
& ytarget(numys),diffy(numys)
!^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
do i=1,nunknowns
scalingfact(i)=1.0d0
xvar(i)=scldxp(i)/xscalingfact(i)
enddo
call surface(numys,yvar,nunknowns,xvar)
do i=1,numys
diff(i)=yvar(i)-ytarget(i)
endif
if(idowhat.eq.1)then
scldfsqsum=0.0d0
do i=1,nunknowns
scldfequ(i)=scldfequ(i)*scalingfact(i)
scldfsqsum=scldfsqsum+scldfequ(i)*scldfequ(i)
enddo
scldfsqsum=0.5d0*scldfsqsum
endif
if(idowhat.eq.2)then
return
end subroutine leafsys
subroutine surface(numys,ysurface,nunknowns,xvar)
implicit none
integer numys,nunknowns
double precision ysurface(numys),xvar(nunknowns)
ysurface(1)=xvar(1)
return
end
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
subroutine sqsum_fequ(nunknowns,xp,fequsqsum)
!This subroutine returns half of the sum of the squared equation residues
implicit none
integer nunknowns
double precision xp(nunknowns),fequsqsum,
& fequ(nunknowns)
integer idowhat
parameter(idowhat=1)
call distancesys(nunknowns,xp,fequ,fequsqsum,idowhat)
return
end
double precision function cpf1dim_fequ(x)
!this function subroutine returns half of the sum of the squared equation residues for line search
INTEGER NMAX
double precision x
PARAMETER (NMAX=1000)
INTEGER j,ncom,idowhat
parameter(idowhat=1)
double precision pcom(NMAX),xicom(NMAX),
& xt(NMAX),fequ(NMAX)
COMMON /cpf1com/ pcom,xicom,ncom
save /cpf1com/
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call distancesys(ncom,xt,fequ,cpf1dim_fequ,idowhat)
return
END
subroutine getequationvalues((nunknowns,xp,
& fequ,fequsqsum)
!this subroutine is for solving a nonlinear system
implicit none
integer nunknowns,idowhat
double precision xp(nunknowns),fequ(nunknowns),fequsqsum
parameter(idowhat=1)
call distancesys(nunknowns,xp,fequ,fequsqsum,idowhat)
return
end
subroutine getsqdistance(nunknowns,xp,sqdistance)
!This subroutine returns the distance between a point on a curve (surface) and another point
!that is specified in distancesys
implicit none
integer nunknowns,idowhat
double precision xp(nunknowns),sqdistance,fequ(nunknowns)
parameter(idowhat=2)
call distancesys(nunknowns,xp,fequ,sqdistance,idowhat)
return
end
double precision function cpf1dim_distance(x)
!this function subroutine returns the distance for line search
INTEGER NMAX
double precision x
PARAMETER (NMAX=1000)
INTEGER j,ncom,idowhat
parameter(idowhat=2)
double precision pcom(NMAX),xicom(NMAX),
& xt(NMAX),fequ(NMAX)
COMMON /cpf1com/ pcom,xicom,ncom
save /cpf1com/
do 11 j=1,ncom
xt(j)=pcom(j)+x*xicom(j)
11 continue
call distancesys(ncom,xt,fequ,cpf1dim_distance,idowhat)
return
END
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -0,0 +1,122 @@
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
double precision function
&annfunc(nparams,params,nh,q,w,bph,bend,c)
implicit none
integer nparams,nh
!nh is the number of hidden nodes in one hiden layer
!params is the inputs
!w is the weighting coefficients for the inputs
double precision params(nparams),q(nh),
& w(nparams,nh),bph(nh),bend,c(nh)
integer i,v
double precision term,activatefunc1,activatefunc2
annfunc=bend
do i=1,nh
term=bph(i)
do v=1,nparams
term=term+w(v,i)*params(v)
enddo
annfunc=annfunc+q(i)*activatefunc1(term)+
&c(i)*activatefunc2(term)
enddo
end
subroutine derannfunc(nparams,params,nh,q,w,bph,
& bend,c,derq,derw,derbph,derbend,derc)
implicit none
integer nparams,nh
!nh is the number of hidden nodes in one hiden layer
!params is the inputs
!w is the weighting coefficients for the inputs
double precision params(nparams),q(nh),
& w(nparams,nh),bph(nh),bend,c(nh),derq(nh),
& derw(nparams,nh),derbph(nh),derbend,derc(nh)
integer i,v
double precision term,activatefunc1,gradactivatefunc1,
&activatefunc2,gradactivatefunc2
derbend=1.0d0
do i=1,nh
term=bph(i)
do v=1,nparams
term=term+w(v,i)*params(v)
enddo
derq(i)=activatefunc1(term)
derc(i)=activatefunc2(term)
derbph(i)=q(i)*gradactivatefunc1(term)+
& c(i)*gradactivatefunc2(term)
do v=1,nparams
derw(v,i)=derbph(i)*params(v)
enddo
enddo
end
subroutine gradannfunc(nparams,params,nh,q,w,bph,
& c,der_params)
implicit none
integer nparams,nh
double precision params(nparams),der_params(nparams),
& q(nh),w(nparams,nh),bph(nh),c(nh)
integer i,v
double precision term,gradactivatefunc1,gradactivatefunc2
do i=1,nparams
der_params(i)=0.0d0
enddo
do i=1,nh
term=bph(i)
do v=1,nparams
term=term+w(v,i)*params(v)
enddo
do v=1,nparams
der_params(v)=der_params(v)+(q(i)*gradactivatefunc1(term)
&+c(i)*gradactivatefunc2(term))*w(v,i)
enddo
enddo
return
end
double precision function activatefunc1(x)
implicit none
double precision x,crit
parameter(crit=300)
if(x.gt.-crit)then
activatefunc1=1.0d0/(1.0d0+dexp(-x))
else
activatefunc1=dexp(x)/(1.0d0+dexp(x))
endif
return
end
double precision function gradactivatefunc1(x)
implicit none
double precision x,crit
parameter(crit=600)
if(x.gt.-crit.and.x.lt.crit)then
gradactivatefunc1=
& (1.0d0/(dexp(x/2.0d0)+dexp(-x/2.0d0)))**2
else
gradactivatefunc1=0.0d0
endif
return
end
double precision function activatefunc2(x)
implicit none
double precision x
! activatefunc2=2.0d0*datan(x)/3.14159265d0
! activatefunc2=1.001d0+dsin(x)
activatefunc2=x+x*x
return
end
double precision function gradactivatefunc2(x)
implicit none
double precision x,crit
parameter(crit=600)
! gradactivatefunc2=2.0d0/(3.14159265d0*(1.0d0+x*x))
! gradactivatefunc2=dcos(x)
gradactivatefunc2=1.0d0+2.0d0*x
return
end
@@ -0,0 +1,105 @@
subroutine findmindistance(funcnleq1,fmin_funcnleq1,
& f1dim_funcnleq1,x0min,x0ori,xp,x0max,fp,
& nunknowns,iwhichsolver)
implicit none
integer nunknowns,iwhichsolver
double precision x0min(nunknowns),x0ori(nunknowns),
& xp(nunknowns),x0max(nunknowns),fp(nunknowns)
!-------- Specified values ---------------------------------------
!funcnleq1: the subroutine that calculates the functional values of the
! the nonlinear system in the following form:
! funcnleq1(nunknowns,xp,fp,fsqsum)
!fmin_funcnleq1: the subroutine that calls funcnleq1 and returns fsqsum (half
! of the sum of the squared functional values of the nonlinear system)
! fmin_funcnleq1(nunknowns,xp,fsqsum)
!f1dim_funcnleq1: a function subroutine that returns fsqsum
! f1dim_funcnleq1(xp)
! nunknowns: The number of unknowns to be solved
! x0ori(1:nunknowns): initial guess for the unknowns
! x0min(1:nunknowns): lower bound of the solution
! x0max(1:nunknowns): upper bound of the solution
! --------- Calculated values -------------------------------------
! fp(1:nunknowns): function values at the last step of iteration
! xp(1:nunknowns): final solutions
! iwhichsolver:
! =1 solved by plain fixed point method 1
! =2 solved by fixed point method 2
! =3 solved by fixed point method 3
! =4 solved by fixed point method 4
! =6 solved by broydn
! =7 Solved by multiobjective minimization.
! =-9999 Best approximation returned. Solution may not be accurate.
! --------- Local variables ---------------------------------------
double precision x0(nunknowns),TOLF,stpmax,scldstpmax,
& sum,tb,tp,xb(nunknowns),fb(nunknowns),fsqsum,
& f1dim_funcnleq1
integer i,irepeat,maxrepeats,IERR,notfound
intrinsic dble
parameter(maxrepeats=100,notfound=-9999,TOLF=1.0d-10)
external funcnleq1,fmin_funcnleq1,f1dim_funcnleq1
!-------------------------------------------------------------------
stpmax=0.0d0
sum=0.0d0
do i=1, nunknowns
x0(i)=x0ori(i)
sum=sum+x0ori(i)*x0ori(i)
stpmax=stpmax+
& (x0min(i)-x0max(i))*(x0min(i)-x0max(i))
enddo
stpmax=dsqrt(stpmax)/4.0d0
scldstpmax=stpmax/dmax1(dsqrt(sum),dble(nunknowns))
! In Numerical Recipes, scldstpmax (STPMX) is 100
scldstpmax=dmax1(100.0d0,scldstpmax)
iwhichsolver=notfound
do irepeat=1,maxrepeats
call fixedpoint(funcnleq1,x0min,x0,xp,
& x0max,fp,nunknowns,TOLF,stpmax,iwhichsolver)
tp=dabs(fp(1))
do i=1,nunknowns
if(dabs(fp(i)).gt.tp)tp=dabs(fp(i))
xb(i)=xp(i)
enddo
call broydn(x0min,xb,x0max,scldstpmax,nunknowns,
& fb,funcnleq1,TOLF,IERR)
call funcnleq1(nunknowns,xb,fb,fsqsum)
tb=dabs(fb(1))
do i=2,nunknowns
if(dabs(fb(i)).gt.tb)tb=dabs(fb(i))
enddo
if(tb.lt.tp)then
do i=1,nunknowns
xp(i)=xb(i)
fp(i)=fb(i)
enddo
if(iwhichsolver.eq.notfound.and.
& tb.lt.TOLF)then
iwhichsolver=6
endif
endif
fsqsum=0.0d0
do i=1,nunknowns
fsqsum=fsqsum+fp(i)*fp(i)
enddo
fsqsum=fsqsum*0.5d0
call nongradopt(nunknowns,fmin_funcnleq1,
& f1dim_funcnleq1,xp,x0min,x0max,TOLF,fsqsum)
call RepeatCompassSearch(nunknowns,xp,fsqsum,
& x0min,x0max,fmin_funcnleq1,f1dim_funcnleq1,TOLF)
call funcnleq1(nunknowns,xp,fp,fsqsum)
if(iwhichsolver.eq.notfound)then
tp=dabs(fp(1))
do i=2,nunknowns
if(dabs(fp(i)).gt.tp)tp=dabs(fp(i))
enddo
if(tp.lt.TOLF)iwhichsolver=7
endif
IERR=0
do i=1,nunknowns
if(dabs(xp(i)-x0(i)).gt.TOLF)IERR=1
enddo
if(IERR.eq.0)return
do i=1,nunknowns
x0(i)=xp(i)
enddo
enddo
end subroutine findmindistance
@@ -0,0 +1,15 @@
integer maxndim,nobs,nxvars,nyvars,maxnobs,
& maxnxvars,maxnyvars,iregrestype,iknowder,idobounded
parameter(maxnobs=50000,maxnxvars=10,maxnyvars=10,
& maxndim=1000)
common /int_com_generic/nobs,nxvars,nyvars,iregrestype,
&iknowder,idobounded
double precision xvars(maxnobs,maxnxvars),
& yobs(maxnobs,maxnyvars),weity(maxnobs,maxnyvars),
& weitx(maxnobs,maxnxvars),betamin(maxndim),
& betamax(maxndim),shorty(maxnobs,maxnyvars),
& shortx(maxnobs,maxnxvars),xmin(maxnobs,maxnxvars),
& xmax(maxnobs,maxnxvars)
common /dble_com_generic/xvars,yobs,weity,weitx,
& betamin,betamax,shorty,shortx,xmin,xmax
save /int_com_generic/,/dble_com_generic/
@@ -0,0 +1,80 @@
subroutine function_generic(ndim,beta,nxvars,
& xvars,nyvars,ymod)
integer ndim,nxvars,nyvars
double precision beta(ndim),xvars(nxvars),
& ymod(nyvars)
double precision y0,a,b,c,x0,x,term,crit
parameter(crit=300.0d0)
a=beta(1)
b=beta(2)
c=beta(3)
x0=beta(4)
y0=beta(5)
x=xvars(1)
if((-(x-x0)/b).lt.crit)then
term=dexp(-(x-x0)/b)
ymod(1)=y0+a*(1.0d0/(1.0d0+term))**c
else
term=dexp((x-x0)/b)
ymod(1)=y0+a*(term/(1.0d0+term))**c
endif
return
end
subroutine der_function_generic(np,beta,m,
& xvars,nq,der_beta)
implicit none
integer np,m,nq
double precision beta(np),xvars(m),der_beta(np,nq)
double precision y0,a,b,c,x0,x,term,crit
parameter(crit=300.0d0)
a=beta(1)
b=beta(2)
c=beta(3)
x0=beta(4)
y0=beta(5)
x=xvars(1)
der_beta(5,1)=1.0d0
if((-(x-x0)/b).lt.crit)then
term=dexp(-(x-x0)/b)
der_beta(1,1)=(1.0d0/(1.0d0+term))**c
! der_x=(a*c*term/b)*(1.0d0/(1.0d0+term))**(1.0d0+c)
der_beta(4,1)=-(a*c*term/b)*
& (1.0d0/(1.0d0+term))**(1.0d0+c)
der_beta(2,1)=-(a*c*term*(x-x0)/(b*b))*
& (1.0d0/(1.0d0+term))**(1.0d0+c)
der_beta(3,1)=-(a*dlog(1.0d0+term))*
& (1.0d0/(1.0d0+term))**c
else
term=(x-x0)/b
der_beta(1,1)=(dexp(term)/(1.0d0+dexp(term)))**c
! der_x=(a*c/b)*(dexp(term*c/(c+1.0d0))/
! & (1.0d0+dexp(term)))**(c+1.0d0)
der_beta(4,1)=-(a*c/b)*(dexp(term*c/(c+1))/
& (1.0d0+dexp(term)))**(c+1.0d0)
der_beta(2,1)=-(a*c*(x-x0)/(b*b))*(dexp(term*c/
& (c+1.0d0))/(1.0d0+dexp(term)))**(1.0d0+c)
der_beta(3,1)=-a*(dlog(1.0d0+dexp(term))-term)*
& (dexp(term)/(1.0d0+dexp(term)))**c
endif
return
end
subroutine indices_function_generic(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
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,10 @@
!------------------CommonBlock-----------------------------
integer maxmy,maxnx,maxnparams
parameter(maxmy=10,maxnx=10,maxnparams=30)
integer my,iknowder,nparams
double precision targetx(maxnx),targety(maxmy),
& params(maxnparams)
common /distcom/targetx,targety,params,
& my,iknowder,nparams
save /distcom/
!----------------------------------------------------------
+412
View File
@@ -0,0 +1,412 @@
subroutine nongradopt(ndim,funkmin,f1dim,beta,
& bmin,bmax,ftol,fatbeta)
implicit none
! This subroutine minimizes function funkmin to estimate ndim parameters
! using non-gradient based methods
!
integer ndim
double precision beta(1:ndim),bmin(1:ndim),
& bmax(1:ndim),ftol,fatbeta
!
! ------------------ Inputs -----------------------------
! ndim: the total number of parameters to be estimated
! bmax: the maximum possible value of beta, used to determine the distance scaling factor
! bmin: the minimum possible value of beta, used to determine the distance scaling factor
! beta: initial guess, overwritten upon return
! ftol: tolerance for convergence
! fatbeta: the cost function valuate at beta, overwritten upon return
! funkmin is the name of the subroutine that computes the cost function
! f1dim: the one dimensional cost function
! ------------------ Outputs ----------------------------
! beta: The best parameters obtained
! fatbeta: the cost function value at beta
integer n,nn,mpamoeba,npamoeba,iredo,maxredo,ITMAX,
& icycle
parameter(maxredo=10,ITMAX=10000)
double precision fbest,xbest(1:ndim),term,
& xinidir(1:ndim,1:ndim),xbest0(1:ndim),
& pamoeba(1:ndim+1,1:ndim),famoeba(1:ndim+1)
external funkmin,f1dim
! End of declaration of variables
!---------------------------------------------------------------
icycle=0
1 iredo=0
3 do n=1,ndim
xbest(n)=beta(n)
do nn=1,ndim
xinidir(n,nn)=0.0d0
enddo
xinidir(n,n)=1.0d0
enddo
fbest=fatbeta
call powell(beta,xinidir(1:ndim,1:ndim),ndim,ndim,
& ftol,fatbeta,bmin,bmax,funkmin,f1dim,ITMAX)
if(fatbeta.gt.fbest)then
do n=1,ndim
beta(n)=xbest(n)
enddo
fatbeta=fbest
goto 10
endif
if((fbest-fatbeta).gt.ftol)then
if(iredo.gt.maxredo)goto 10
iredo=iredo+1
goto 3
endif
10 iredo=0
20 do n=1,ndim
xbest(n)=beta(n)
enddo
fbest=fatbeta
do nn=1,ndim
pamoeba(1,nn)=beta(nn)
enddo
famoeba(1)=fatbeta
do n=2,ndim+1
do nn=1,ndim
pamoeba(n,nn)=beta(nn)
enddo
if((bmax(n-1)-pamoeba(n,n-1))
& .gt.(pamoeba(n,n-1)-bmin(n-1)))then
pamoeba(n,n-1)=pamoeba(n,n-1)+
& (bmax(n-1)-pamoeba(n,n-1))*0.1d0
else
pamoeba(n,n-1)=pamoeba(n,n-1)-
& (pamoeba(n,n-1)-bmin(n-1))*0.1d0
endif
do nn=1,ndim
xbest0(nn)=pamoeba(n,nn)
enddo
call funkmin(ndim,xbest0,famoeba(n))
enddo
mpamoeba=ndim+1
npamoeba=ndim
fatbeta=1.0d+100
term=1.0d0
30 nn=ITMAX/20
call amebsa(pamoeba(1:ndim+1,1:ndim),famoeba(1:ndim+1),
&mpamoeba,npamoeba,ndim,beta,fatbeta,ftol,funkmin,nn,term)
if(fatbeta.lt.fbest)then
if((fbest-fatbeta).gt.ftol*100.0d0.and.term.gt.1.0d-2)then
term=term/3.0d0
fbest=fatbeta
goto 30
endif
do n=1,ndim
xbest(n)=beta(n)
enddo
fbest=fatbeta
else
do n=1,ndim
beta(n)=xbest(n)
enddo
fatbeta=fbest
endif
do nn=1,ndim
pamoeba(1,nn)=beta(nn)
enddo
famoeba(1)=fatbeta
do n=2,ndim+1
do nn=1,ndim
pamoeba(n,nn)=beta(nn)
enddo
if((bmax(n-1)-pamoeba(n,n-1))
& .gt.(pamoeba(n,n-1)-bmin(n-1)))then
pamoeba(n,n-1)=pamoeba(n,n-1)+
& (bmax(n-1)-pamoeba(n,n-1))*0.1d0
else
pamoeba(n,n-1)=pamoeba(n,n-1)-
& (pamoeba(n,n-1)-bmin(n-1))*0.1d0
endif
do nn=1,ndim
xbest0(nn)=pamoeba(n,nn)
enddo
call funkmin(ndim,xbest0,famoeba(n))
enddo
mpamoeba=ndim+1
npamoeba=ndim
call guamoeba(pamoeba(1:ndim+1,1:ndim),famoeba(1:ndim+1),
&mpamoeba,npamoeba,ndim,ftol,funkmin,ITMAX/20)
nn=1
do n=2,ndim+1
if(famoeba(n).lt.famoeba(nn))nn=n
enddo
fatbeta=famoeba(nn)
do n=1,ndim
beta(n)=pamoeba(nn,n)
if(beta(n).lt.bmin(n).or.beta(n).gt.bmax(n))then
do nn=1,ndim
beta(nn)=xbest(nn)
enddo
fatbeta=fbest
return
endif
enddo
if((fbest-fatbeta).gt.ftol)then
if(iredo.gt.maxredo)then
if(icycle.lt.maxredo)then
icycle=icycle+1
goto 1
else
return
endif
endif
iredo=iredo+1
goto 20
endif
return
end subroutine nongradopt
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
SUBROUTINE guamoeba(p,y,mp,np,ndim,ftol,funkmin,ITMAX)
implicit none
INTEGER iter,mp,ndim,np,NMAX,ITMAX
double precision ftol,p(mp,np),y(mp),TINY
PARAMETER (TINY=1.0d-10)
external funkmin
CU USES guamotry,funkmin
INTEGER i,ihi,ilo,inhi,j,m,n
double precision rtol,sum,swap,ysave,ytry,psum(ndim),
& guamotry,degen
iter=0
1 do 12 n=1,ndim
sum=0.0d0
do 11 m=1,ndim+1
sum=sum+p(m,n)
11 continue
psum(n)=sum
12 continue
2 ilo=1
if (y(1).gt.y(2)) then
ihi=1
inhi=2
else
ihi=2
inhi=1
endif
do 13 i=1,ndim+1
if(y(i).le.y(ilo)) ilo=i
if(y(i).gt.y(ihi)) then
inhi=ihi
ihi=i
else if(y(i).gt.y(inhi)) then
if(i.ne.ihi) inhi=i
endif
13 continue
rtol=2.0d0*dabs(y(ihi)-y(ilo))/
& (dabs(y(ihi))+dabs(y(ilo))+TINY)
if (rtol.lt.ftol) then
swap=y(1)
y(1)=y(ilo)
y(ilo)=swap
do 14 n=1,ndim
swap=p(1,n)
p(1,n)=p(ilo,n)
p(ilo,n)=swap
14 continue
return
endif
! check to see if the simplex is degenerate; if so, stop
degen=0.0d0
do i=1,mp
do m=i+1,mp
do n=1,np
if(dabs(p(m,n)-p(i,n)).gt.degen)then
degen=dabs(p(m,n)-p(i,n))
endif
enddo
enddo
enddo
if(degen.lt.ftol*ftol)then
swap=y(1)
y(1)=y(ilo)
y(ilo)=swap
do n=1,ndim
swap=p(1,n)
p(1,n)=p(ilo,n)
p(ilo,n)=swap
enddo
return
endif
if(iter.ge.ITMAX)return
iter=iter+2
ytry=guamotry(p,y,psum,mp,np,ndim,funkmin,ihi,-1.0d0)
if (ytry.le.y(ilo))then
ytry=guamotry(p,y,psum,mp,np,ndim,funkmin,ihi,2.0d0)
else if (ytry.ge.y(inhi)) then
ysave=y(ihi)
ytry=guamotry(p,y,psum,mp,np,ndim,funkmin,ihi,0.5d0)
if (ytry.ge.ysave) then
do 16 i=1,ndim+1
if(i.ne.ilo)then
do 15 j=1,ndim
psum(j)=0.5d0*(p(i,j)+p(ilo,j))
p(i,j)=psum(j)
15 continue
call funkmin(ndim,psum,y(i))
endif
16 continue
iter=iter+ndim
goto 1
endif
else
iter=iter-1
endif
goto 2
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
DOUBLE PRECISION FUNCTION guamotry(p,y,psum,
& mp,np,ndim,funkmin,ihi,fac)
implicit none
INTEGER ihi,mp,ndim,np
double precision fac,p(mp,np),psum(np),y(mp)
EXTERNAL funkmin
CU USES funkmin
INTEGER j
double precision fac1,fac2,ytry,ptry(ndim)
fac1=(1.0d0-fac)/dble(ndim)
fac2=fac1-fac
do 11 j=1,ndim
ptry(j)=psum(j)*fac1-p(ihi,j)*fac2
11 continue
call funkmin(ndim,ptry,ytry)
if (ytry.lt.y(ihi)) then
y(ihi)=ytry
do 12 j=1,ndim
psum(j)=psum(j)-p(ihi,j)+ptry(j)
p(ihi,j)=ptry(j)
12 continue
endif
guamotry=ytry
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
c#######################################################################
SUBROUTINE amebsa(p,y,mp,np,ndim,pb,yb,ftol,funkmin,iter,temptr)
implicit none
INTEGER iter,mp,ndim,np
double precision ftol,temptr,yb,p(mp,np),pb(np),y(mp)
EXTERNAL funkmin
CU USES amotsa,funkmin,ran1
INTEGER i,idum,ihi,ilo,inhi,j,m,n
double precision rtol,sum,swap,tt,yhi,ylo,ynhi,ysave,yt,ytry,
&psum(ndim),amotsa,ran1
COMMON /ambsa/ tt,idum
tt=-temptr
1 do 12 n=1,ndim
sum=0.0d0
do 11 m=1,ndim+1
sum=sum+p(m,n)
11 continue
psum(n)=sum
12 continue
2 ilo=1
inhi=1
ihi=2
ylo=y(1)+tt*dlog(ran1(idum))
ynhi=ylo
yhi=y(2)+tt*dlog(ran1(idum))
if (ylo.gt.yhi) then
ihi=1
inhi=2
ilo=2
ynhi=yhi
yhi=ylo
ylo=ynhi
endif
do 13 i=3,ndim+1
yt=y(i)+tt*dlog(ran1(idum))
if(yt.le.ylo) then
ilo=i
ylo=yt
endif
if(yt.gt.yhi) then
inhi=ihi
ynhi=yhi
ihi=i
yhi=yt
else if(yt.gt.ynhi) then
inhi=i
ynhi=yt
endif
13 continue
rtol=2.0d0*dabs(yhi-ylo)/(dabs(yhi)+dabs(ylo))
if(rtol.lt.ftol.or.iter.lt.0) then
swap=y(1)
y(1)=y(ilo)
y(ilo)=swap
do 14 n=1,ndim
swap=p(1,n)
p(1,n)=p(ilo,n)
p(ilo,n)=swap
14 continue
return
endif
iter=iter-2
ytry=amotsa(p(1:mp,1:np),
&y,psum,mp,np,ndim,pb,yb,funkmin,ihi,yhi,-1.0d0)
if (ytry.le.ylo) then
ytry=amotsa(p(1:mp,1:np),
&y,psum,mp,np,ndim,pb,yb,funkmin,ihi,yhi,2.0d0)
else if (ytry.ge.ynhi) then
ysave=yhi
ytry=amotsa(p(1:mp,1:np),
&y,psum,mp,np,ndim,pb,yb,funkmin,ihi,yhi,0.5d0)
if (ytry.ge.ysave) then
do 16 i=1,ndim+1
if(i.ne.ilo)then
do 15 j=1,ndim
psum(j)=0.5d0*(p(i,j)+p(ilo,j))
p(i,j)=psum(j)
15 continue
call funkmin(ndim,psum,y(i))
endif
16 continue
iter=iter-ndim
goto 1
endif
else
iter=iter+1
endif
goto 2
END
double precision FUNCTION amotsa
&(p,y,psum,mp,np,ndim,pb,yb,funkmin,ihi,yhi,fac)
implicit none
INTEGER ihi,mp,ndim,np
double precision fac,yb,yhi,p(mp,np),pb(np),psum(ndim),y(mp)
EXTERNAL funkmin
CU USES funkmin,ran1
INTEGER idum,j
double precision fac1,fac2,tt,yflu,ytry,ptry(ndim),ran1
COMMON /ambsa/ tt,idum
fac1=(1.0d0-fac)/dble(ndim)
fac2=fac1-fac
do 11 j=1,ndim
ptry(j)=psum(j)*fac1-p(ihi,j)*fac2
11 continue
call funkmin(ndim,ptry,ytry)
if (ytry.le.yb) then
do 12 j=1,ndim
pb(j)=ptry(j)
12 continue
yb=ytry
endif
yflu=ytry-tt*log(ran1(idum))
if (yflu.lt.yhi) then
y(ihi)=ytry
yhi=yflu
do 13 j=1,ndim
psum(j)=psum(j)-p(ihi,j)+ptry(j)
p(ihi,j)=ptry(j)
13 continue
endif
amotsa=yflu
return
END
@@ -0,0 +1,249 @@
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
subroutine odr_leastsquare(NP,FCN,BETA,N,X,M,Y,NQ,
&weitx,weity,iderivative,shortx,shorty,fvalue,INFO)
implicit none
!if derivatives are provided, set iderivative to 1, otherwise set it to 0.
!for ordinary least square regression, set INFO to 0.
!for explicit orthorgonal distance regression, set INFO to 1.
!the content of INFO is destroyed on return
C ODRPACK ARGUMENT DEFINITIONS
C ==> FCN NAME OF THE USER SUPPLIED FUNCTION SUBROUTINE
C ==> N NUMBER OF OBSERVATIONS
C ==> M COLUMNS OF DATA IN THE EXPLANATORY VARIABLE
C ==> NP NUMBER OF PARAMETERS
C ==> NQ NUMBER OF RESPONSES PER OBSERVATION
C <==> BETA FUNCTION PARAMETERS
C ==> Y RESPONSE VARIABLE
C ==> X EXPLANATORY VARIABLE
C ==> LWORK DIMENSION OF VECTOR WORK
C ==> LIWORK DIMENSION OF VECTOR IWORK
C <== INFO STOPPING CONDITION
C VARIABLE DECLARATIONS
INTEGER INFO,M,N,NP,NQ,iderivative,LWORK,LIWORK
double precision weity(N,NQ),weitx(N,M),shorty(N,NQ),
&shortx(N,M),fvalue,BETA(NP),X(N,M),Y(N,NQ)
EXTERNAL FCN
LWORK=18+11*NP+NP**2+M+M**2+4*N*NQ+6*N*M+2*N*NQ*NP+
&2*N*NQ*M+NQ**2+5*NQ+NQ*(NP+M)+N*1*NQ
LIWORK=20+NP+NQ*(NP+M)
call odr_interface(NP,FCN,BETA,N,X(1:N,1:M),M,Y(1:N,1:NQ),NQ,
&LWORK,LIWORK,weitx(1:N,1:M),weity(1:N,1:NQ),iderivative,
&shortx(1:N,1:M),shorty(1:N,1:NQ),fvalue,INFO)
return
end subroutine odr_leastsquare
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
subroutine odr_interface(NP,FCN,BETA,N,X,M,Y,NQ,LWORK,
&LIWORK,weitx,weity,iderivative,shortx,shorty,fvalue,INFO)
implicit none
!if derivatives are provided, set iderivative to 1, otherwise set it to 0.
!for ordinary least square regression, set INFO to 0.
!for explicit orthorgonal distance regression, set INFO to 1.
!the content of INFO is destroyed on return
C ODRPACK ARGUMENT DEFINITIONS
C ==> FCN NAME OF THE USER SUPPLIED FUNCTION SUBROUTINE
C ==> N NUMBER OF OBSERVATIONS
C ==> M COLUMNS OF DATA IN THE EXPLANATORY VARIABLE
C ==> NP NUMBER OF PARAMETERS
C ==> NQ NUMBER OF RESPONSES PER OBSERVATION
C <==> BETA FUNCTION PARAMETERS
C ==> Y RESPONSE VARIABLE
C ==> LDY LEADING DIMENSION OF ARRAY Y
C ==> X EXPLANATORY VARIABLE
C ==> LDX LEADING DIMENSION OF ARRAY X
C ==> WE "EPSILON" WEIGHTS
C ==> LDWE LEADING DIMENSION OF ARRAY WE
C ==> LD2WE SECOND DIMENSION OF ARRAY WE
C ==> WD "DELTA" WEIGHTS
C ==> LDWD LEADING DIMENSION OF ARRAY WD
C ==> LD2WD SECOND DIMENSION OF ARRAY WD
C ==> IFIXB INDICATORS FOR "FIXING" PARAMETERS (BETA)
C ==> IFIXX INDICATORS FOR "FIXING" EXPLANATORY VARIABLE (X)
C ==> LDIFX LEADING DIMENSION OF ARRAY IFIXX
C ==> JOB TASK TO BE PERFORMED
C ==> NDIGIT GOOD DIGITS IN SUBROUTINE FUNCTION RESULTS
C ==> TAUFAC TRUST REGION INITIALIZATION FACTOR
C ==> SSTOL SUM OF SQUARES CONVERGENCE CRITERION
C ==> PARTOL PARAMETER CONVERGENCE CRITERION
C ==> MAXIT MAXIMUM NUMBER OF ITERATIONS
C ==> IPRINT PRINT CONTROL
C ==> LUNERR LOGICAL UNIT FOR ERROR REPORTS
C ==> LUNRPT LOGICAL UNIT FOR COMPUTATION REPORTS
C ==> STPB STEP SIZES FOR FINITE DIFFERENCE DERIVATIVES WRT BETA
C ==> STPD STEP SIZES FOR FINITE DIFFERENCE DERIVATIVES WRT DELTA
C ==> LDSTPD LEADING DIMENSION OF ARRAY STPD
C ==> SCLB SCALE VALUES FOR PARAMETERS BETA
C ==> SCLD SCALE VALUES FOR ERRORS DELTA IN EXPLANATORY VARIABLE
C ==> LDSCLD LEADING DIMENSION OF ARRAY SCLD
C <==> WORK DOUBLE PRECISION WORK VECTOR
C ==> LWORK DIMENSION OF VECTOR WORK
C <== IWORK INTEGER WORK VECTOR
C ==> LIWORK DIMENSION OF VECTOR IWORK
C <== INFO STOPPING CONDITION
C PARAMETER DECLARATIONS AND SPECIFICATIONS
INTEGER LDIFX,LDSCLD,LDSTPD,LDWD,LDWE,LDX,LDY,LD2WD,LD2WE,
+ LIWORK,LWORK
C VARIABLE DECLARATIONS
INTEGER I,INFO,IPRINT,J,JOB,L,LUNERR,LUNRPT,M,MAXIT,N,
+ NDIGIT,NP,NQ
INTEGER IFIXB(NP),IFIXX(N,M),IWORK(LIWORK)
DOUBLE PRECISION PARTOL,SSTOL,TAUFAC
DOUBLE PRECISION BETA(NP),SCLB(NP),SCLD(1,M),
+ STPB(NP),STPD(1,M),
+ WD(N,1,M),WE(N,1,NQ),
+ WORK(LWORK),X(N,M),Y(N,NQ)
!------------For using information in WORK----------------------------
LOGICAL
+ ISODR
INTEGER
+ DELTAI,EPSI,XPLUSI,FNI,SDI,VCVI,
+ RVARI,WSSI,WSSDEI,WSSEPI,RCONDI,ETAI,
+ OLMAVI,TAUI,ALPHAI,ACTRSI,PNORMI,RNORSI,PRERSI,
+ PARTLI,SSTOLI,TAUFCI,EPSMAI,
+ BETA0I,BETACI,BETASI,BETANI,SI,SSI,SSFI,QRAUXI,UI,
+ FSI,FJACBI,WE1I,DIFFI,
+ DELTSI,DELTNI,TI,TTI,OMEGAI,FJACDI,
+ WRK1I,WRK2I,WRK3I,WRK4I,WRK5I,WRK6I,WRK7I,
+ LWKMN
c
integer i1,i2,i3,i4,i5,iderivative
double precision weity(N,NQ),weitx(N,M),shorty(N,NQ),
&shortx(N,M),fvalue
EXTERNAL FCN
c
C SPECIFY DEFAULT VALUES FOR DODRC ARGUMENTS
LDY=N
LDX=N
LDWE=N
LD2WE=1
LDWD=N
LD2WD=1
LDIFX=N
LDSTPD=1
LDSCLD=1
WE(1,1,1) = -1.0D0
WD(1,1,1) = -1.0D0
IFIXB(1) = -1
! IFIXX(1,1) = -1
if(INFO.eq.0)then
!explicit ordinary least square fitting
ISODR=.false.
if(iderivative.eq.0)then
!no derivatives provided, using central finite difference
JOB=13
else
!don't check derivatives
JOB=43
!check derivatives
! JOB=23
endif
endif
if(INFO.eq.1)then
!explicit orthogonal distance regression
ISODR=.true.
if(iderivative.eq.0)then
!no derivatives provided, using central finite difference
JOB=10
else
!don't check derivatives
JOB=40
!check derivatives
! JOB=20
endif
endif
if(INFO.eq.-1)then
!implicit orthogonal distance regression
ISODR=.true.
if(iderivative.eq.0)then
!no derivatives provided, using central finite difference
JOB=11
else
!don't check derivatives
JOB=31
!check derivatives
! JOB=21
endif
endif
NDIGIT = -1
TAUFAC = -1.0D0
SSTOL = -1.0D0
PARTOL = -1.0D0
MAXIT = -1
IPRINT = -1
IPRINT=0
LUNERR = -1
LUNRPT = -1
STPB(1) = -1.0D0
STPD(1,1) = -1.0D0
SCLB(1) = -1.0D0
SCLD(1,1) = -1.0D0
MAXIT = 200000
C SET UP ODRPACK REPORT FILES
LUNERR = 107
LUNRPT = 108
LWKMN=LWORK
c
do I=1,N
do i1=1,M
WD(I,1,i1)=weitx(I,i1)
enddo
do i1=1,NQ
WE(I,1,i1)=weity(I,i1)
enddo
enddo
C READ PROBLEM DATA, AND SET NONDEFAULT VALUE FOR ARGUMENT IFIXX
DO 10 I=1,N
DO 15 J=1, M
IFIXX(I,J) = 1
15 CONTINUE
10 CONTINUE
60 CALL DODRC(FCN,
+ N,M,NP,NQ,
+ BETA,
+ Y,LDY,X,LDX,
+ WE,LDWE,LD2WE,WD,LDWD,LD2WD,
+ IFIXB,IFIXX,LDIFX,
+ JOB,NDIGIT,TAUFAC,
+ SSTOL,PARTOL,MAXIT,
+ IPRINT,LUNERR,LUNRPT,
+ STPB,STPD,LDSTPD,
+ SCLB,SCLD,LDSCLD,
+ WORK,LWORK,IWORK,LIWORK,
+ INFO)
i1=mod(INFO,10)
i2=(mod(INFO,100)-i1)/10
i3=(mod(INFO,1000)-mod(INFO,100))/100
i4=(mod(INFO,10000)-mod(INFO,1000))/1000
i5=(INFO-mod(INFO,10000))/10000
CALL DWINF
+ (N,M,NP,NQ,LDWE,LD2WE,ISODR,
+ DELTAI,EPSI,XPLUSI,FNI,SDI,VCVI,
+ RVARI,WSSI,WSSDEI,WSSEPI,RCONDI,ETAI,
+ OLMAVI,TAUI,ALPHAI,ACTRSI,PNORMI,RNORSI,PRERSI,
+ PARTLI,SSTOLI,TAUFCI,EPSMAI,
+ BETA0I,BETACI,BETASI,BETANI,SI,SSI,SSFI,QRAUXI,UI,
+ FSI,FJACBI,WE1I,DIFFI,
+ DELTSI,DELTNI,TI,TTI,OMEGAI,FJACDI,
+ WRK1I,WRK2I,WRK3I,WRK4I,WRK5I,WRK6I,WRK7I,
+ LWKMN)
fvalue=0.0d0
do I=1,N
do J=1,M
shortx(I,J)=WORK(XPLUSI-1+I+(J-1)*N)
fvalue=fvalue+weitx(I,J)*WORK(DELTAI-1+I+(J-1)*N)
+ *WORK(DELTAI-1+I+(J-1)*N)
enddo
do J=1,NQ
shorty(I,J)=WORK(FNI-1+I+(J-1)*N)
fvalue=fvalue+weity(I,J)*WORK(EPSI-1+I+(J-1)*N)
+*WORK(EPSI-1+I+(J-1)*N)
enddo
enddo
return
END
File diff suppressed because it is too large Load Diff
+497
View File
@@ -0,0 +1,497 @@
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
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
File diff suppressed because it is too large Load Diff
+52
View File
@@ -0,0 +1,52 @@
subroutine planarfit(nsamp,x,y,z,a,b,d,fatbeta)
!fit a plane in the form of ax+by+cz+d=0 where c is set to 1.
!Because we set c=1, we cannot fit for vertical planes in parallel to the
!x-z or y-z planes. But perfectly flat planes in parallel to the x-y plane can be included.
!no initial guess for a, b and d are needed
implicit none
integer nsamp,i
double precision x(nsamp),y(nsamp),z(nsamp),
& a,b,d,fatbeta,p1,p2,p3,q1,q2,q3,xmean,ymean,
& zmean,x2mean,y2mean,xymean,xzmean,yzmean
!--------------------------------------------------------
xmean=0.0d0
ymean=0.0d0
zmean=0.0d0
x2mean=0.0d0
y2mean=0.0d0
xymean=0.0d0
xzmean=0.0d0
yzmean=0.0d0
do i=1,nsamp
xmean=xmean+x(i)
ymean=ymean+y(i)
zmean=zmean+z(i)
x2mean=x2mean+x(i)*x(i)
y2mean=y2mean+y(i)*y(i)
xymean=xymean+x(i)*y(i)
xzmean=xzmean+x(i)*z(i)
yzmean=yzmean+y(i)*z(i)
enddo
xmean=xmean/dble(nsamp)
ymean=ymean/dble(nsamp)
zmean=zmean/dble(nsamp)
x2mean=x2mean/dble(nsamp)
y2mean=y2mean/dble(nsamp)
xymean=xymean/dble(nsamp)
xzmean=xzmean/dble(nsamp)
yzmean=yzmean/dble(nsamp)
p1=x2mean-xmean*xmean
p2=xymean-xmean*ymean
p3=xmean*zmean-xzmean
q1=xymean-xmean*ymean
q2=y2mean-ymean*ymean
q3=ymean*zmean-yzmean
call linearsys_dim2(p1,p2,p3,q1,q2,q3,a,b)
d=-(a*xmean+b*ymean+zmean)
fatbeta=0.0d0
do i=1,nsamp
fatbeta=fatbeta+(a*x(i)+b*y(i)+z(i)+d)*
& (a*x(i)+b*y(i)+z(i)+d)
enddo
return
end
+548
View File
@@ -0,0 +1,548 @@
SUBROUTINE powell(p,xi,n,np,ftol,fret,pmin,pmax,
& funkmin,f1dim,ITMAX)
! fret must be given on entry
implicit none
INTEGER iter,n,np,NMAX,ITMAX
double precision fret,ftol,p(np),xi(np,np),TINY,
& pmin(np),pmax(np)
PARAMETER (NMAX=1000,TINY=1.0d-25)
CU USES funkmin,linmin
INTEGER i,ibig,j
double precision del,fp,fptt,t,pt(NMAX),
& ptt(NMAX),xit(NMAX)
external funkmin,f1dim
do 11 j=1,n
pt(j)=p(j)
11 continue
iter=0
1 iter=iter+1
fp=fret
ibig=0
del=0.0d0
do 13 i=1,n
do 12 j=1,n
xit(j)=xi(j,i)
12 continue
fptt=fret
call linmin(p,pmin,pmax,xit,n,f1dim,fret)
if(fptt-fret.gt.del)then
del=fptt-fret
ibig=i
endif
13 continue
if(2.0d0*(fp-fret).le.ftol*(dabs(fp)+dabs(fret))+TINY)return
if(iter.eq.ITMAX)then
! write(*,*)'powell exceeding maximum iterations'
return
endif
do 14 j=1,n
ptt(j)=2.0d0*p(j)-pt(j)
xit(j)=p(j)-pt(j)
pt(j)=p(j)
14 continue
call funkmin(n,ptt,fptt)
if(fptt.ge.fp)goto 1
t=2.0d0*(fp-2.0d0*fret+fptt)*(fp-fret-del)**2-
& del*(fp-fptt)**2
if(t.ge.0.0d0)goto 1
call linmin(p,pmin,pmax,xit,n,f1dim,fret)
if(ibig.eq.0)return
do 15 j=1,n
xi(j,ibig)=xi(j,n)
xi(j,n)=xit(j)
15 continue
goto 1
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
SUBROUTINE linmin(p,pmin,pmax,xi,n,f1dim,fret)
implicit none
INTEGER n
double precision fret,p(n),xi(n),TOL,pmin(n),pmax(n)
PARAMETER (TOL=1.0d-8)
CU USES brent,f1dim,mnbrak
INTEGER j,k,ierr
double precision ax,bx,fa,fb,fx,xmin,xx,brent,xxmin,xxmax
!((((((((((((((((((((((((((((((((((((((((((((((((((((
!It is essential NMAX must be set to 1000 in f1dim!
integer NMAX,ncom
parameter(NMAX=1000)
double precision pcom(NMAX),xicom(NMAX)
COMMON /f1com/ pcom,xicom,ncom
save /f1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
EXTERNAL f1dim
ncom=n
do j=1,n
pcom(j)=p(j)
xicom(j)=xi(j)
enddo
xxmax=1.0d+100
xxmin=-1.0d+100
do j=1,n
if(xicom(j).gt.1.0d-100)then
! if(xicom(j).gt.0.0d0)then
xx=(pmax(j)-pcom(j))/xicom(j)
ax=(pmin(j)-pcom(j))/xicom(j)
else
if(xicom(j).lt.(-1.0d-100))then
! if(xicom(j).lt.0.0d0)then
ax=(pmax(j)-pcom(j))/xicom(j)
xx=(pmin(j)-pcom(j))/xicom(j)
else
xx=1.0d+100
ax=-1.0d+100
endif
endif
if(xxmax.gt.xx)then
xxmax=xx
endif
if(xxmin.lt.ax)then
xxmin=ax
endif
enddo
ax=0.0d0
if(dabs(xxmax).gt.dabs(xxmin))then
xx=0.25d0*xxmax
else
xx=0.25d0*xxmin
endif
call mnbrak(ax,xx,bx,fa,fx,fb,xxmin,xxmax,ierr,f1dim)
if(ierr.eq.0)then
fret=brent(ax,xx,bx,f1dim,TOL,xmin)
else
xmin=xx
fret=fx
endif
do 12 j=1,n
xi(j)=xmin*xi(j)
p(j)=p(j)+xi(j)
12 continue
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
!
!
double precision function brent(ax,bx,cx,f,tol,xmin)
INTEGER ITMAX
double precision ax,bx,cx,tol,xmin,f,CGOLD,ZEPS
EXTERNAL f
PARAMETER (ITMAX=10000,CGOLD=.381966d0,ZEPS=1.0d-10)
INTEGER iter
double precision a,b,d,e,etemp,fu,fv,fw,fx,p,q,r,tol1,
& tol2,u,v,w,x,xm
a=dmin1(ax,cx)
b=dmax1(ax,cx)
v=bx
w=v
x=v
e=0.0d0
fx=f(x)
fv=fx
fw=fx
do 11 iter=1,ITMAX
xm=0.5d0*(a+b)
tol1=tol*dabs(x)+ZEPS
tol2=2.0d0*tol1
if(dabs(x-xm).le.(tol2-.5d0*(b-a))) goto 3
if(dabs(e).gt.tol1) then
r=(x-w)*(fx-fv)
q=(x-v)*(fx-fw)
p=(x-v)*q-(x-w)*r
q=2.0d0*(q-r)
if(q.gt.0.0d0) p=-p
q=dabs(q)
etemp=e
e=d
if(dabs(p).ge.dabs(.5d0*q*etemp).or.
& p.le.q*(a-x).or.p.ge.q*(b-x))goto 1
d=p/q
u=x+d
if(u-a.lt.tol2.or.b-u.lt.tol2)d=dsign(tol1,xm-x)
goto 2
endif
1 if(x.ge.xm)then
e=a-x
else
e=b-x
endif
d=CGOLD*e
2 if(dabs(d).ge.tol1) then
u=x+d
else
u=x+dsign(tol1,d)
endif
fu=f(u)
if(fu.le.fx)then
if(u.ge.x)then
a=x
else
b=x
endif
v=w
fv=fw
w=x
fw=fx
x=u
fx=fu
else
if(u.lt.x) then
a=u
else
b=u
endif
if(fu.le.fw.or.w.eq.x)then
v=w
fv=fw
w=u
fw=fu
else if(fu.le.fv.or.v.eq.x.or.v.eq.w)then
v=u
fv=fu
endif
endif
11 continue
! write(*,*) 'brent exceed maximum iterations'
3 xmin=x
brent=fx
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
! double precision function f1dim(x)
! implicit none
! double precision x
!CU USES funkmin
! INTEGER j
!
!((((((((((((((((((((((((((((((((((((((((((((((((((((
! integer NMAX,ncom
! parameter(NMAX=1000)
! double precision pcom(NMAX),xicom(NMAX)
! COMMON /f1com/ pcom,xicom,ncom
! save /f1com/
!))))))))))))))))))))))))))))))))))))))))))))))))))))
! double precision xt(NMAX)
! do 11 j=1,ncom
! xt(j)=pcom(j)+x*xicom(j)
!11 continue
! call funkmin(ncom,xt,f1dim)
! return
! END
!C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
SUBROUTINE mnbrak(ax,bx,cx,fa,fb,fc,xxmin,xxmax,
& ierr,func)
implicit none
double precision ax,bx,cx,fa,fb,fc,
& func,GOLD,GLIMIT,TINY
EXTERNAL func
PARAMETER(GOLD=1.618034d0,GLIMIT=100.0d0,TINY=1.0d-20)
double precision dum,fu,q,r,u,ulim,xxmin,xxmax
integer ierr
ierr=0
fa=func(ax)
fb=func(bx)
if(fb.gt.fa)then
dum=ax
ax=bx
bx=dum
dum=fb
fb=fa
fa=dum
!from ax to bx, f decreases
endif
if(fa.eq.fb)then
cx=(bx+ax)/2.0d0
fc=func(cx)
if(fc.le.fa)return
endif
cx=bx+GOLD*(bx-ax)
if(cx.le.xxmin)then
cx=0.5d0*(dmin1(ax,bx)+xxmin)
endif
if(cx.ge.xxmax)then
cx=0.5d0*(dmax1(ax,bx)+xxmax)
endif
fc=func(cx)
1 if(fb.ge.fc)then
r=(bx-ax)*(fb-fc)
q=(bx-cx)*(fb-fa)
u=bx-((bx-cx)*q-(bx-ax)*r)/
& (2.0d0*dsign(dmax1(dabs(q-r),TINY),q-r))
ulim=bx+GLIMIT*(cx-bx)
if(ulim.ge.xxmax)then
ulim=xxmax-TINY
endif
if(ulim.le.xxmin)then
ulim=xxmin+TINY
endif
if((bx-u)*(u-cx).gt.0.0d0)then
fu=func(u)
if(fu.lt.fc)then
ax=bx
fa=fb
bx=u
fb=fu
return
elseif(fu.gt.fb)then
cx=u
fc=fu
return
endif
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fu=func(u)
elseif((cx-u)*(u-ulim).gt.0.0d0)then
fu=func(u)
if(fu.lt.fc)then
bx=cx
cx=u
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fb=fc
fc=fu
fu=func(u)
endif
else if((u-ulim)*(ulim-cx).ge.0.0d0)then
u=ulim
fu=func(u)
else
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fu=func(u)
endif
ax=bx
bx=cx
cx=u
fa=fb
fb=fc
fc=fu
r=dmin1(dabs(ax-bx),dabs(ax-cx))
r=dmin1(r,dabs(bx-cx))
if(r.lt.TINY)then
! bracketing failed
ierr=1
return
endif
goto 1
endif
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
SUBROUTINE leafmnbrak(ax,bx,cx,fa,fb,fc,xxmin,xxmax,
& ierr,func)
implicit none
double precision ax,bx,cx,fa,fb,fc,
& func,GOLD,GLIMIT,TINY
EXTERNAL func
PARAMETER(GOLD=1.618034d0,GLIMIT=100.0d0,TINY=1.0d-20)
double precision dum,fu,q,r,u,ulim,xxmin,xxmax
integer ierr
ierr=0
fa=func(ax)
fb=func(bx)
if(fb.gt.fa)then
dum=ax
ax=bx
bx=dum
dum=fb
fb=fa
fa=dum
!from ax to bx, f decreases
endif
if(fa.eq.fb)then
cx=(bx+ax)/2.0d0
fc=func(cx)
if(fc.le.fa)return
endif
cx=bx+GOLD*(bx-ax)
if(cx.le.xxmin)then
cx=0.5d0*(dmin1(ax,bx)+xxmin)
endif
if(cx.ge.xxmax)then
cx=0.5d0*(dmax1(ax,bx)+xxmax)
endif
fc=func(cx)
1 if(fb.ge.fc)then
r=(bx-ax)*(fb-fc)
q=(bx-cx)*(fb-fa)
u=bx-((bx-cx)*q-(bx-ax)*r)/
& (2.0d0*dsign(dmax1(dabs(q-r),TINY),q-r))
ulim=bx+GLIMIT*(cx-bx)
if(ulim.ge.xxmax)then
ulim=xxmax-TINY
endif
if(ulim.le.xxmin)then
ulim=xxmin+TINY
endif
if((bx-u)*(u-cx).gt.0.0d0)then
fu=func(u)
if(fu.lt.fc)then
ax=bx
fa=fb
bx=u
fb=fu
return
elseif(fu.gt.fb)then
cx=u
fc=fu
return
endif
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fu=func(u)
elseif((cx-u)*(u-ulim).gt.0.0d0)then
fu=func(u)
if(fu.lt.fc)then
bx=cx
cx=u
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fb=fc
fc=fu
fu=func(u)
endif
else if((u-ulim)*(ulim-cx).ge.0.0d0)then
u=ulim
fu=func(u)
else
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fu=func(u)
endif
ax=bx
bx=cx
cx=u
fa=fb
fb=fc
fc=fu
r=dmin1(dabs(ax-bx),dabs(ax-cx))
r=dmin1(r,dabs(bx-cx))
if(r.lt.TINY)then
! bracketing failed
ierr=1
return
endif
goto 1
endif
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
double precision function leafbrent(ax,bx,cx,f,tol,xmin)
INTEGER ITMAX
double precision ax,bx,cx,tol,xmin,f,CGOLD,ZEPS
EXTERNAL f
PARAMETER (ITMAX=10000,CGOLD=.381966d0,ZEPS=1.0d-10)
INTEGER iter
double precision a,b,d,e,etemp,fu,fv,fw,fx,p,q,r,tol1,
& tol2,u,v,w,x,xm
a=dmin1(ax,cx)
b=dmax1(ax,cx)
v=bx
w=v
x=v
e=0.0d0
fx=f(x)
fv=fx
fw=fx
do 11 iter=1,ITMAX
xm=0.5d0*(a+b)
tol1=tol*dabs(x)+ZEPS
tol2=2.0d0*tol1
if(dabs(x-xm).le.(tol2-.5d0*(b-a))) goto 3
if(dabs(e).gt.tol1) then
r=(x-w)*(fx-fv)
q=(x-v)*(fx-fw)
p=(x-v)*q-(x-w)*r
q=2.0d0*(q-r)
if(q.gt.0.0d0) p=-p
q=dabs(q)
etemp=e
e=d
if(dabs(p).ge.dabs(.5d0*q*etemp).or.
& p.le.q*(a-x).or.p.ge.q*(b-x))goto 1
d=p/q
u=x+d
if(u-a.lt.tol2.or.b-u.lt.tol2)d=dsign(tol1,xm-x)
goto 2
endif
1 if(x.ge.xm)then
e=a-x
else
e=b-x
endif
d=CGOLD*e
2 if(dabs(d).ge.tol1) then
u=x+d
else
u=x+dsign(tol1,d)
endif
fu=f(u)
if(fu.le.fx)then
if(u.ge.x)then
a=x
else
b=x
endif
v=w
fv=fw
w=x
fw=fx
x=u
fx=fu
else
if(u.lt.x) then
a=u
else
b=u
endif
if(fu.le.fw.or.w.eq.x)then
v=w
fv=fw
w=u
fw=fu
else if(fu.le.fv.or.v.eq.x.or.v.eq.w)then
v=u
fv=fu
endif
endif
11 continue
! write(*,*) 'brent exceed maximum iterations'
3 xmin=x
leafbrent=fx
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
+403
View File
@@ -0,0 +1,403 @@
SUBROUTINE powellann(p,xi,n,np,ftol,fret,pmin,pmax,
& funkmin,f1dim,ITMAX)
! fret must be given on entry
implicit none
INTEGER iter,n,np,NMAX,ITMAX
double precision fret,ftol,p(np),xi(np,np),TINY,
& pmin(np),pmax(np)
PARAMETER (NMAX=50,TINY=1.0d-25)
CU USES funkmin,annlinmin
INTEGER i,ibig,j
double precision del,fp,fptt,t,pt(NMAX),
& ptt(NMAX),xit(NMAX)
external funkmin,f1dim
do 11 j=1,n
pt(j)=p(j)
11 continue
iter=0
1 iter=iter+1
fp=fret
ibig=0
del=0.0d0
do 13 i=1,n
do 12 j=1,n
xit(j)=xi(j,i)
12 continue
fptt=fret
call annlinmin(p,pmin,pmax,xit,n,f1dim,fret)
if(fptt-fret.gt.del)then
del=fptt-fret
ibig=i
endif
13 continue
if(2.0d0*(fp-fret).le.ftol*(dabs(fp)+dabs(fret))+TINY)return
if(iter.eq.ITMAX)then
write(*,*)'powell exceeding maximum iterations'
return
endif
do 14 j=1,n
ptt(j)=2.0d0*p(j)-pt(j)
xit(j)=p(j)-pt(j)
pt(j)=p(j)
14 continue
call funkmin(n,ptt,fptt)
if(fptt.ge.fp)goto 1
t=2.0d0*(fp-2.0d0*fret+fptt)*(fp-fret-del)**2-
& del*(fp-fptt)**2
if(t.ge.0.0d0)goto 1
call annlinmin(p,pmin,pmax,xit,n,f1dim,fret)
do 15 j=1,n
xi(j,ibig)=xi(j,n)
xi(j,n)=xit(j)
15 continue
goto 1
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
SUBROUTINE annlinmin(p,pmin,pmax,xi,n,f1dim,fret)
implicit none
INTEGER n,NMAX
double precision fret,p(n),xi(n),ftol,pmin(n),pmax(n)
PARAMETER (NMAX=1000,ftol=1.0d-6)
CU USES brent,f1dim,mnbrak
INTEGER j,ncom,k,ierr
double precision ax,bx,fa,fb,fx,xmin,xx,pcom(NMAX),
& xicom(NMAX),xxmin,xxmax,term,w(2),bph(2),
& paramnormsk,paramnormsb,ynorm,q(2),bend,terma,
& termb,termc,delta,reducer,root,f1dim,postannfunc
parameter(reducer=0.25d0)
COMMON /f1com/ pcom,xicom,ncom
integer maxm1dsamp,m1dsamp
parameter(maxm1dsamp=1000)
common /intannlinmin/m1dsamp
double precision y1dsamp(maxm1dsamp),params1d(maxm1dsamp)
common /dbleannlinmin/y1dsamp,params1d
EXTERNAL f1dim
ncom=n
delta=0.5d0
do j=1,n
pcom(j)=p(j)
xicom(j)=xi(j)
enddo
xxmax=1.0d+100
xxmin=-1.0d+100
do j=1,n
if(xicom(j).gt.1.0d-100)then
! if(xicom(j).gt.0.0d0)then
xx=(pmax(j)-pcom(j))/xicom(j)
ax=(pmin(j)-pcom(j))/xicom(j)
else
if(xicom(j).lt.(-1.0d-100))then
! if(xicom(j).lt.0.0d0)then
ax=(pmax(j)-pcom(j))/xicom(j)
xx=(pmin(j)-pcom(j))/xicom(j)
else
xx=1.0d+100
ax=-1.0d+100
endif
endif
if(xxmax.gt.xx)then
xxmax=xx
endif
if(xxmin.lt.ax)then
xxmin=ax
endif
enddo
ax=0.0d0
if(dabs(xxmax).gt.dabs(xxmin))then
xx=0.25d0*xxmax
else
xx=0.25d0*xxmin
endif
m1dsamp=0
call mnbrak(ax,xx,bx,fa,fx,fb,xxmin,xxmax,ierr,f1dim)
if(ierr.ne.0)then
! bracketing failed
fret=fx
do j=1,n
xi(j)=xx*xi(j)
p(j)=p(j)+xi(j)
enddo
return
endif
if(ax.gt.xx)then
xxmax=ax
xxmin=bx
else
xxmax=bx
xxmin=ax
endif
write(*,*)m1dsamp
if(m1dsamp.lt.6)then
term=xx+(xxmax-xx)*(delta+1.0d0)/2.0d0
fret=f1dim(term)
if(fret.lt.fx)then
xxmin=xx
xx=term
fx=fret
else
xxmax=term
endif
term=xx+(xxmax-xx)*(1.0d0-delta)/2.0d0
fret=f1dim(term)
if(fret.lt.fx)then
xxmin=xx
xx=term
fx=fret
else
xxmax=term
endif
term=xx-(xx-xxmin)*(1.0d0+delta)/2.0d0
fret=f1dim(term)
if(fret.lt.fx)then
xxmax=xx
xx=term
fx=fret
else
xxmin=term
endif
term=xx-(xx-xxmin)*(1.0d0-delta)/2.0d0
fret=f1dim(term)
if(fret.lt.fx)then
xxmax=xx
xx=term
fx=fret
else
xxmin=term
endif
endif
w(1)=0.75334d0
w(2)=0.13425d0
bph(1)=0.01d0
bph(2)=-0.07d0
q(1)=1.2d0
q(2)=-2.0d0
100 call annfitting1d(m1dsamp,params1d,y1dsamp,paramnormsk,
& paramnormsb,ynorm,w,bph,q,bend)
term=q(1)*w(1)
fret=q(2)*w(2)
terma=term*w(2)*w(2)+fret*w(1)*w(1)
termb=2.0d0*(term*w(2)*bph(2)+fret*w(1)*bph(1))
termc=term*(1.0d0+bph(2)*bph(2))+
& fret*(1.0d0+bph(1)*bph(1))
if(terma.eq.0.0d0)then
if(termb.eq.0.0d0)goto 200
root=-termc/termb
goto 110
endif
fret=termb*termb-4.0d0*terma*termc
if(fret.lt.0.0d0)goto 200
term=-0.5d0*(termb+dsign(1.0d0,termb)*dsqrt(fret))
root=termc/term
root=(root-paramnormsb)/paramnormsk
if(root.lt.xxmax.and.root.gt.xxmin)then
if(dabs(root-xx).lt.ftol)goto 1000
fret=f1dim(root)
if(fret.lt.fx)then
if(root.lt.xx)then
xxmax=xx
else
xxmin=xx
endif
xx=root
fx=fret
goto 100
else
if(root.lt.xx)then
xxmin=root
else
xxmax=root
endif
endif
endif
root=term/terma
110 root=(root-paramnormsb)/paramnormsk
if(root.lt.xxmax.and.root.gt.xxmin)then
if(dabs(root-xx).lt.ftol)goto 1000
fret=f1dim(root)
if(fret.lt.fx)then
if(root.lt.xx)then
xxmax=xx
else
xxmin=xx
endif
xx=root
fx=fret
goto 100
else
if(root.lt.xx)then
xxmin=root
else
xxmax=root
endif
endif
endif
200 term=xx+delta*(xxmax-xx)
write(*,*)'ann failed'
fret=f1dim(term)
if(fret.lt.fx)then
xxmin=xx
fx=fret
xx=term
goto 100
endif
xxmax=term
term=xx-delta*(xx-xxmin)
fret=f1dim(term)
if(fret.lt.fx)then
xxmax=xx
fx=fret
xx=term
goto 100
endif
xxmin=term
delta=delta*reducer
if(delta.gt.ftol)goto 200
1000 fret=fx
do j=1,n
xi(j)=xx*xi(j)
p(j)=p(j)+xi(j)
enddo
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
SUBROUTINE mnbrak(ax,bx,cx,fa,fb,fc,xxmin,xxmax,
& ierr,func)
implicit none
double precision ax,bx,cx,fa,fb,fc,
& func,GOLD,GLIMIT,TINY
EXTERNAL func
PARAMETER(GOLD=1.618034d0,GLIMIT=100.0d0,TINY=1.0d-20)
double precision dum,fu,q,r,u,ulim,xxmin,xxmax
integer ierr
ierr=0
fa=func(ax)
fb=func(bx)
if(fb.gt.fa)then
dum=ax
ax=bx
bx=dum
dum=fb
fb=fa
fa=dum
endif
if(fa.eq.fb)then
cx=(bx+ax)/2.0d0
fc=func(cx)
if(fc.le.fa)return
endif
cx=bx+GOLD*(bx-ax)
if(cx.le.xxmin)then
cx=0.5d0*(dmin1(ax,bx)+xxmin)
endif
if(cx.ge.xxmax)then
cx=0.5d0*(dmax1(ax,bx)+xxmax)
endif
fc=func(cx)
1 if(fb.ge.fc)then
r=(bx-ax)*(fb-fc)
q=(bx-cx)*(fb-fa)
u=bx-((bx-cx)*q-(bx-ax)*r)/
& (2.0d0*dsign(dmax1(dabs(q-r),TINY),q-r))
ulim=bx+GLIMIT*(cx-bx)
if(ulim.ge.xxmax)then
ulim=xxmax-tiny
endif
if(ulim.le.xxmin)then
ulim=xxmin+tiny
endif
if((bx-u)*(u-cx).gt.0.0d0)then
fu=func(u)
if(fu.lt.fc)then
ax=bx
fa=fb
bx=u
fb=fu
return
elseif(fu.gt.fb)then
cx=u
fc=fu
return
endif
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fu=func(u)
elseif((cx-u)*(u-ulim).gt.0.0d0)then
fu=func(u)
if(fu.lt.fc)then
bx=cx
cx=u
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fb=fc
fc=fu
fu=func(u)
endif
else if((u-ulim)*(ulim-cx).ge.0.0d0)then
u=ulim
fu=func(u)
else
u=cx+GOLD*(cx-bx)
if(u.gt.xxmax)then
u=cx+0.5d0*(xxmax-cx)
endif
if(u.lt.xxmin)then
u=cx+0.5d0*(xxmin-cx)
endif
fu=func(u)
endif
ax=bx
bx=cx
cx=u
fa=fb
fb=fc
fc=fu
r=dmin1(dabs(ax-bx),dabs(ax-cx))
r=dmin1(r,dabs(bx-cx))
if(r.lt.tiny)then
! bracketing failed
ierr=1
return
endif
goto 1
endif
return
END
C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3.
@@ -0,0 +1,102 @@
subroutine randpermut_dim_samp(npoints,ndim,x)
implicit none
!
! conduct random permutation
integer npoints,ndim,i,j,k,iextreme,index,ibad,ngood,
& istore(npoints)
double precision x(ndim,npoints),xtemp(npoints),
& ran2_reset,temp,bmin(ndim),bmax(ndim)
do i=1,ndim
do j=1,npoints
xtemp(j)=x(i,j)
enddo
do j=1,npoints
index=int(dble(npoints-j+1)*ran2_reset()+1.0d0)
x(i,j)=xtemp(index)
xtemp(index)=xtemp(npoints-j+1)
enddo
enddo
if(ndim.eq.1)return
if(npoints.le.3)return
! now check to see if all extreme values are togather
do i=1,ndim
bmax(i)=x(i,1)
bmin(i)=x(i,1)
enddo
do i=2,npoints
do j=1,ndim
if(bmax(j).lt.x(j,i))then
bmax(j)=x(j,i)
endif
if(bmin(j).gt.x(j,i))then
bmin(j)=x(j,i)
endif
enddo
enddo
do i=1,npoints
iextreme=0
do j=1,ndim
if(dabs(x(j,i)-bmax(j)).lt.1.0d-9.or.
& dabs(x(j,i)-bmin(j)).lt.1.0d-9)then
iextreme=iextreme+1
endif
enddo
if(iextreme.ge.(ndim/2+1))then
! more than half take extreme values, need to change
! find ones without any extremes
ngood=0
do j=1,i
ibad=0
do k=1,ndim
if(dabs(x(k,j)-bmax(k)).lt.1.0d-9.or.
& dabs(x(k,j)-bmin(k)).lt.1.0d-9)then
ibad=1
endif
enddo
if(ibad.eq.0)then
ngood=ngood+1
istore(ngood)=j
endif
enddo
do j=1+i,npoints
ibad=0
do k=1,ndim
if(dabs(x(k,j)-bmax(k)).lt.1.0d-9.or.
& dabs(x(k,j)-bmin(k)).lt.1.0d-9)then
ibad=1
endif
enddo
if(ibad.eq.0)then
ngood=ngood+1
istore(ngood)=j
endif
enddo
if(ngood.ge.1)then
index=int(dble(ngood)*ran2_reset()+1.0d0)
index=istore(index)
else
! there is no single point that does not take any extremes
index=int(dble(npoints)*ran2_reset()+1.0d0)
if(index.eq.i)then
if(i.eq.1)then
index=npoints
else
index=1
endif
endif
endif
do j=1,ndim,2
temp=x(j,i)
x(j,i)=x(j,index)
x(j,index)=temp
enddo
endif
enddo
return
end
c&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
@@ -0,0 +1,144 @@
subroutine samplingscheme(sampfunc,nparams,msamp,
& bestguess,guessconfid0,bmax,bmin,params,ysamp)
!
! This subroutine conducts samples from a given function using both random and
! systematic strategies. In the random strategy, sampled points randomly scatter
! around the bestguess point. The closeness to the bestguess depends on the confidence
! on the bestguess. For any given parameter, the width of the last interval is
! guessconfid0 X the width of the first interval. In the systematic strategy, two values
! for each parameter are determined with the new bestguess after
! the random sampling in the middle. The two determined values of all parameters
! are systematically combined to form new additional sampling points.
!
! After the two sampling strategies, the latest best guess is the first point in params.
implicit none
integer nparams,msamp
double precision bestguess(nparams),guessconfid0,
& bmax(nparams),bmin(nparams),params(nparams,msamp),
& ysamp(msamp),guessconfid
integer i,nright,nleft,ibest,msamptemp
double precision accum,x1,delta,j,ybest,temp
external sampfunc
guessconfid=dmax1(1.0d0,guessconfid0)
do i=1,nparams
if(bestguess(i).lt.bmin(i).or.bestguess(i).gt.
& bmax(i))then
write(*,*)'best guess out of bounds, sampling stops'
stop
endif
enddo
msamptemp=msamp-1-2*nparams
if(msamptemp.lt.0)then
write(*,*)'sampling number must be larger than',
& (1+2*nparams)
stop
endif
if(msamptemp.gt.0)then
if(msamptemp.ge.3)then
if(mod(msamptemp,2).eq.0)then
nright=msamptemp/2
nleft=msamptemp/2
else
nright=msamptemp/2+1
nleft=msamptemp/2
endif
do i=1,nparams
!first divide the right
x1=2.0d0*(bmax(i)-bestguess(i))/
& (dble(nright)*(guessconfid+1.0d0))
delta=x1*(guessconfid-1.0d0)/dble(nright-1)
accum=0.0d0
do j=1,nright
accum=accum+x1+dble(j-1)*delta
params(i,j)=accum+bestguess(i)
enddo
!
!then divide the left
x1=2.0d0*(bestguess(i)-bmin(i))/
& (dble(nleft)*(guessconfid+1.0d0))
delta=x1*(guessconfid-1.0d0)/dble(nleft-1)
accum=0.0d0
do j=1,nleft
accum=accum+x1+dble(j-1)*delta
params(i,j+nright)=bestguess(i)-accum
enddo
enddo
else
if(msamptemp.eq.1)then
do i=1,nparams
! arbitrarily take one value
params(i,1)=bestguess(i)+(bmax(i)-bestguess(i))
& *0.339354235d0
enddo
endif
if(msamptemp.eq.2)then
do i=1,nparams
! arbitrarily take two values
params(i,1)=bestguess(i)+(bmax(i)-bestguess(i))
& *0.339354235d0
params(i,2)=bestguess(i)-(bestguess(i)-bmin(i))
& *0.339354235d0
enddo
endif
endif
call randpermut_dim_samp(msamptemp,nparams,
& params(1:nparams,1:msamptemp))
endif
msamptemp=msamptemp+1
do i=1,nparams
params(i,msamptemp)=bestguess(i)
enddo
do i=1,msamptemp
call sampfunc(nparams,params(1:nparams,i:i),ysamp(i))
enddo
ibest=1
ybest=ysamp(ibest)
do i=2,msamptemp
if(ysamp(i).lt.ybest)then
ibest=i
ybest=ysamp(i)
endif
enddo
do i=1,nparams
msamptemp=msamptemp+1
params(i,msamptemp)=params(i,ibest)+
& (bmax(i)-params(i,ibest))/(1.0d0+guessconfid)
msamptemp=msamptemp+1
params(i,msamptemp)=params(i,ibest)-
& (params(i,ibest)-bmin(i))/(1.0d0+guessconfid)
do j=1,i-1
params(j,msamptemp-1)=params(j,ibest)
params(j,msamptemp)=params(j,ibest)
enddo
do j=i+1,nparams
params(j,msamptemp-1)=params(j,ibest)
params(j,msamptemp)=params(j,ibest)
enddo
enddo
do i=msamptemp-2*nparams+1,msamptemp
call sampfunc(nparams,params(1:nparams,i:i),ysamp(i))
if(ysamp(i).lt.ybest)then
ibest=i
ybest=ysamp(i)
endif
enddo
do i=1,nparams
temp=params(i,1)
params(i,1)=params(i,ibest)
params(i,ibest)=temp
enddo
temp=ysamp(1)
ysamp(1)=ysamp(ibest)
ysamp(ibest)=temp
return
end
@@ -0,0 +1,51 @@
subroutine shortestdist(my0,nx,pointy,
& pointx,xmin,xmax,nparams0,params0,
& iknowder0,shorty,shortx)
!find the point on the surface that has the shortest distance from a given point
implicit none
include 'leastdistance.h'
integer my0,nx,nparams0,iknowder0
double precision pointy(my0),shorty(my0),pointx(nx),
& shortx(nx),xmin(nx),xmax(nx),params0(nparams0)
!------------------Locals----------------------------------
integer i,iwhichsolver,idowhat,notfound
parameter(notfound=-9999)
double precision s2,s2cp,
& f1dimsqsum_distcenter,f1dims2_distcenter,
& shortf(nx),dydxp(my0,(nx+nparams0)),xtol,ftol
parameter(xtol=1.0d-10,ftol=1.0d-10)
external distcentersys,fsqsum_distcenter,
& f1dimsqsum_distcenter,s2_distcenter,
& f1dims2_distcenter
!----------------------------------------------------------
my=my0
nparams=nparams0
iknowder=iknowder0
do i=1,nx
targetx(i)=pointx(i)
enddo
do i=1,my
targety(i)=pointy(i)
enddo
do i=1,nparams
params(i)=params0(i)
enddo
call cpnonsyssolver(distcentersys,fsqsum_distcenter,
& f1dimsqsum_distcenter,xmin,pointx,shortx,xmax,
& shortf,nx,iwhichsolver)
if(iwhichsolver.eq.notfound)then
call s2_distcenter(nx,shortx,s2)
s2cp=s2
call cpnongradopt(nx,s2_distcenter,
& f1dims2_distcenter,shortx,xmin,xmax,ftol,s2)
if(dabs(s2cp-s2).gt.ftol)then
call cpRepeatCompassSearch(nx,shortx,s2,xmin,
& xmax,s2_distcenter,f1dims2_distcenter,xtol)
endif
endif
idowhat=0
call surffunc(my,shorty,nx,shortx,nparams,
& params,dydxp(1:my,1:(nx+nparams)),idowhat)
return
end subroutine shortestdist
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+20
View File
@@ -0,0 +1,20 @@
program test
implicit none
integer npoints,i
double precision x(100),y(100),z(100),A,B,D,
& ran2,fatbeta
A=0.009d0
B=0.01d0
D=0.2d0
npoints=100
do i=1,npoints
x(i)=3000.0d0*ran2()
y(i)=20.0d0*ran2()
z(i)=-D-A*x(i)-B*y(i)
enddo
A=1.0d0
B=1.0d0
D=1.0d0
call planarfit(npoints,x,y,z,A,B,D,fatbeta)
write(*,*)A,B,D,fatbeta
end