Commit 3fcdfffe authored by ofgeorg's avatar ofgeorg

! $Log: handleBounds.f90,v $

      !  Revision 1.12  2009/03/30 11:42:10  chrmuell
      !  corrected bug in the setting of the bnd%weights in the iniphase
      !
      !  Revision 1.11  2008/04/18 13:02:56  paulb
      !  repository update
      !
      !  Revision 1.9  2008/03/14 18:49:04  paulb
      !  Corrected wrong datatype in MPI_BCAST, split up variables of cmaesRun into
      !  modules to keep code readable
      !
      !  Revision 1.6  2008/02/06 11:27:55  paulb
      !  Integrated MPI, runs stable, though not verified results yet
      !
      !  Revision 1.5  2008/01/23 13:09:28  paulb
      !  Double Precision support integrated,
      !  corrected errors in boundary handling and test functions,
      !  new vector ranking routine mrgrnk used for sorting integrated
      !  got rid of MEDIAN.f,SORT.f and SORTC.f
      !
      !  Revision 1.4  2008/01/16 16:54:15  paulb
      !  wrong dimension of bnd%arpenalty corrected
      !
      !  Mon Dec 10 2007	paulb	First version completed
      !  Thu Dec 06 2007	paulb	Initial implementation	
parent 03988194
!-------------------------------------------------------------------------
! Subroutine : cmaes_handlebounds
!-------------------------------------------------------------------------
!
! Purpose : This Subroutine implements boundary handling as in
! cmaes.m lines 728-795, it 'penalizes' function fitness
! with an additional term if sample was out of bounds.
!
! Input : m (I) rows of arx/arxvalid
! n (I) columns of arx/arxvalid
! arxvalid(:,:) (R) matrix of valid sample points
! arx(:,:) (R) matrix of all sample points
!
! Remarks : The technical details of boundary handling are not
! completely understood yet, so this is just a 1:1
! translation of Matlab Code (cmaes.m lines 728ff).
! bnd.flgscale as it appears in Matlab code, is not imple-
! mented as it is once set to 0 and never changed afterw.
!
! References :
! @article{Hansen:2007,
! Author = {Hansen, Nikolaus},
! Keywords = {CMA},
! Title = {{The CMA Evolution Strategy: A Tutorial}},
! Year = {2007}}
!
! Revisions :
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Covariance Matrix Adaption Library (LIBCMA)
! Benedikt Baumgartner
! Computational Biophysics Lab, ETH Zurich, Switzerland
!-------------------------------------------------------------------------
SUBROUTINE cmaes_handlebounds(arxvalid,arx,m,n)
!-------------------------------------------------------------------------
! Modules
!-------------------------------------------------------------------------
USE cmaes_param_mod
USE cmaes_mod
USE cmaes_opts_mod
USE tool_mrgrnk_mod
IMPLICIT NONE
!-------------------------------------------------------------------------
! Parameters
!-------------------------------------------------------------------------
INTEGER,INTENT(in) :: m,n
REAL(MK),DIMENSION(m,n),INTENT(in) :: arxvalid
REAL(MK),DIMENSION(m,n),INTENT(in) :: arx
!-------------------------------------------------------------------------
! Local Variables
!-------------------------------------------------------------------------
REAL(MK),DIMENSION(2) :: val
REAL(MK) :: value ! temp
REAL(MK),DIMENSION(input%N) :: diag
REAL(MK) :: mean
INTEGER :: i,k,maxI
LOGICAL,DIMENSION(size(bnd%dfithist)) :: mask
LOGICAL,DIMENSION(input%N) :: idx
REAL(MK),DIMENSION(input%N) :: tx
INTEGER,DIMENSION(size(bnd%dfithist)) :: dfitidx
REAL(MK),DIMENSION(size(bnd%dfithist)) :: dfitsort
REAL(MK),DIMENSION(2) :: prct
dfitsort = 0.0_MK
dfitidx = 0
prct = (/ 25.0_MK,75.0_MK /)
maxI = 0
!-------------------------------------------------------------------------
! Initialize matrix mask
!-------------------------------------------------------------------------
DO i = 1, size(bnd%dfithist)
IF(bnd%dfithist(i) .NE. 0.) THEN
mask(i) = .TRUE.
maxI = maxI + 1 ! sum up non-zero elements of bnd%dfithist vector
ELSE
mask(i) = .FALSE.
END IF
END DO
!-------------------------------------------------------------------------
! Get main diagonal of Covariance matrix C
!-------------------------------------------------------------------------
DO i = 1, input%N
diag(i) = C(i,i)
END DO
!-------------------------------------------------------------------------
! ...and calculate mean value
!-------------------------------------------------------------------------
mean = sum(diag)/real(input%N)
!-------------------------------------------------------------------------
! Get delta fitness values
!-------------------------------------------------------------------------
CALL cmaes_myprctile(fitness%raw, lambda, prct, 2, val)
value = (val(2) - val(1)) / input%N / mean /sigma**2
!-------------------------------------------------------------------------
! Catch non-sensible values
!-------------------------------------------------------------------------
IF(value .GE. posInf) THEN
#ifdef __HAVE_MPI__
WRITE(*,*) 'Process ', MY_RANK, ' warning: Non-finite fitness range'
#else
WRITE(*,*) 'Warning: Non-finite fitness range'
#endif
value = maxval(bnd%dfithist)
ELSE IF(value .EQ. 0.) THEN ! Happens if all points are out of bounds
value = minval(bnd%dfithist,mask)
ELSE IF(bnd%validfitval .EQ. 0) THEN ! First sensible val
bnd%dfithist = 0.
bnd%validfitval = 1
END IF
!-------------------------------------------------------------------------
! Store delta fitness values
!-------------------------------------------------------------------------
bndd:DO i = 1, size(bnd%dfithist)
IF(bnd%dfithist(i) .EQ. 0) THEN ! Store at first unassigned position
bnd%dfithist(i) = value
EXIT bndd
ELSE IF(i .EQ. size(bnd%dfithist)) THEN ! If all positions are
DO k = 1, (size(bnd%dfithist)-1) ! assigned, then shift
bnd%dfithist(k) = bnd%dfithist(k+1) ! values to the left
END DO ! and store new value at last position
bnd%dfithist(i) = value
END IF
END DO bndd
CALL cmaes_xintobounds(options%LBounds,options%Ubounds,input%N,xmean,tx,idx)
!-------------------------------------------------------------------------
! Set initial weights
!-------------------------------------------------------------------------
IF(bnd%iniphase) THEN
IF(any(idx)) THEN
! Set i to the number of non-zero elements of the bnd%dfithist vector
i = maxI
IF(i .EQ. 1) THEN
value = bnd%dfithist(1)
ELSE ! Median is saved in 'value'
!sort bnd%dfithist in ascending order
CALL mrgrnk(bnd%dfithist(1:i),dfitidx)
DO k = 1, i
dfitsort(k) = bnd%dfithist(dfitidx(k))
END DO
!and get median value
IF(mod(i,2) .EQ. 0) THEN
value = (dfitsort(i/2)+dfitsort(i/2+1))/2.0_MK
ELSE
value = dfitsort((i-1)/2+1)
END IF
END IF
WHERE(bnd%isbounded)
diag = diag/mean
bnd%weights = 2.0002_MK * value / diag
END WHERE
IF((bnd%validfitval+countIter) .GT. 2) bnd%iniphase = .FALSE.
END IF
END IF
!-------------------------------------------------------------------------
! Increase weights
!-------------------------------------------------------------------------
IF(any(idx)) THEN
!-----------------------------------------------------------------------
! Judge distance of xmean to boundary
!-----------------------------------------------------------------------
tx = xmean - tx
DO i = 1, input%N
idx(i) = ((idx(i)) .AND. (abs(tx(i)) .GT. 3.0_MK* &
max(1.0_MK,sqrt(real(input%N))/mueff) * sigma * sqrt(diag(i))))
idx(i) = ( idx(i) .AND. &
(sign(1.0_MK,tx(i)) .EQ. sign(1.0_MK,(xmean(i)-xold(i)))) )
END DO
!-----------------------------------------------------------------------
! Only increase if xmean is moving away
!-----------------------------------------------------------------------
WHERE(idx)
bnd%weights = 1.2_MK**(max(1.0_MK,mueff/10.0_MK/real(input%N))) &
* bnd%weights
END WHERE
END IF
!-------------------------------------------------------------------------
! Calculate scaling biased to unity, product is one
!-------------------------------------------------------------------------
!mean = sum(log(diag))/real(input%N)
!bnd%scales = exp(0.9*(log(diag)) - mean)
!-------------------------------------------------------------------------
! Assigned penalized fitness
!-------------------------------------------------------------------------
bnd%arpenalty = matmul( (bnd%weights / bnd%scales), (arxvalid - arx)**2 )
fitness%sel = fitness%raw + bnd%arpenalty
RETURN
END SUBROUTINE cmaes_handlebounds
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment