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

334 lines
11 KiB
FortranFixed

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
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$