LCOV - code coverage report
Current view: top level - rdmft - bfgs_b2.f90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 0 212 0.0 %
Date: 2024-04-27 04:44:07 Functions: 0 1 0.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------
       2             : ! Copyright (c) 2019 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       3             : ! This file is part of FLEUR and available as free software under the conditions
       4             : ! of the MIT license as expressed in the LICENSE file in more detail.
       5             : !--------------------------------------------------------------------------------
       6             : 
       7             : MODULE m_bfgs_b2
       8             : 
       9             : CONTAINS
      10             : 
      11             : ! The subroutine bfgs_b2 is an implementation of a BFGS algorithm with
      12             : ! box constraints. It is motivated by the paper:
      13             : ! Byrd et al., "A Limited Memory Algorithm for Bound Constrained Optimization", 
      14             : ! SIAM Journal on Scientific Computing 16, 1190 (1995)
      15             : ! However, it is substantially different from that paper.
      16             : !
      17             : !                            GM'2019
      18             : 
      19             : ! Note: lastGradient and lastParameters have to be 0.0 if this is the first call to the subroutine and these
      20             : !       vectors don't exist yet. Also historyLength has to be 0 in that case.
      21             : 
      22           0 : SUBROUTINE bfgs_b2(vecLength,gradient,lastGradient,minConstraints,maxConstraints,enabledConstraints,parameters,&
      23           0 :                    lastParameters,equalityLinCombi,equalityCriterion,maxHistoryLength,paramCorrections,&
      24           0 :                    gradientCorrections,iStep,mixParam,l_converged,convCrit)
      25             : 
      26             :    USE m_constants
      27             : 
      28             :    IMPLICIT NONE
      29             : 
      30             :    INTEGER,        INTENT(IN)    :: vecLength
      31             :    INTEGER,        INTENT(IN)    :: maxHistoryLength
      32             :    INTEGER,        INTENT(INOUT) :: iStep ! The index of the bfgs_b iteration
      33             :    REAL,           INTENT(IN)    :: mixParam
      34             :    REAL,           INTENT(IN)    :: equalityCriterion
      35             :    REAL,           INTENT(INOUT)    :: gradient(vecLength)
      36             :    REAL,           INTENT(INOUT) :: lastGradient(vecLength)
      37             :    REAL,           INTENT(IN)    :: minConstraints(vecLength)
      38             :    REAL,           INTENT(IN)    :: maxConstraints(vecLength)
      39             :    LOGICAL,        INTENT(IN)    :: enabledConstraints(vecLength)
      40             :    REAL,           INTENT(INOUT) :: parameters(vecLength)
      41             :    REAL,           INTENT(INOUT) :: lastParameters(vecLength)
      42             :    REAL,           INTENT(IN)    :: equalityLinCombi(vecLength)
      43             :    REAL,           INTENT(INOUT) :: paramCorrections(vecLength,maxHistoryLength)
      44             :    REAL,           INTENT(INOUT) :: gradientCorrections(vecLength,maxHistoryLength)
      45             :    LOGICAL,        INTENT(OUT)   :: l_converged
      46             :    REAL,           INTENT(IN)    :: convCrit
      47             : 
      48             :    INTEGER                :: i, j, stepIndex, numFreeParams, numFixedParams
      49             :    INTEGER                :: historyLength
      50             :    REAL, PARAMETER        :: eps = 1.0e-10
      51             :    REAL, PARAMETER        :: largeEps = 1.0e-6
      52             :    REAL                   :: temp, norm, subspaceEqualityCrit, maxDisp, dampingFactor
      53             :    REAL                   :: ddot
      54             : 
      55             :    LOGICAL                :: converged
      56             : 
      57           0 :    REAL                   :: lastGradCorrection(vecLength)
      58           0 :    REAL                   :: lastParamCorrection(vecLength)
      59           0 :    REAL                   :: prelimNextPoint(vecLength)
      60           0 :    REAL                   :: prelimGradient(vecLength)
      61           0 :    REAL                   :: tempVecA(vecLength)
      62           0 :    REAL                   :: subspaceGrad(vecLength)
      63           0 :    REAL                   :: subspaceNextPoint(vecLength)
      64           0 :    REAL                   :: subspaceLinCombi(vecLength)
      65           0 :    REAL                   :: diffPoint(vecLength)
      66           0 :    REAL                   :: diffGrad(vecLength)
      67             : 
      68           0 :    LOGICAL                :: freeParams(vecLength)
      69             : 
      70           0 :    REAL, ALLOCATABLE      :: hessMat(:,:), invHessMat(:,:)
      71           0 :    REAL, ALLOCATABLE      :: tempMatB(:,:), tempMatC(:,:)
      72           0 :    REAL, ALLOCATABLE      :: subspaceBasis(:,:)
      73           0 :    REAL, ALLOCATABLE      :: subspaceInvHessMat(:,:)
      74             : 
      75           0 :    WRITE(*,*) 'bfgs_b2 (input): parameters(:vecLength): ', parameters(:vecLength)
      76           0 :    WRITE(*,*) 'bfgs_b2 (input): gradient(:vecLength): ', gradient(:vecLength)
      77             : 
      78           0 :    WRITE(5000,*) '========================================================================='
      79           0 :    WRITE(5000,*) 'ENTERED BFGS_B2: '
      80             : 
      81             :    !!! Test start
      82             : !   DO i = 1, vecLength - 1
      83             : !      IF(ABS(gradient(i)).LT.eps) CYCLE
      84             : !      gradient(i) = sqrt(ABS(gradient(i)))*2.0*ATAN(gradient(i))/pi_const
      85             : !   END DO
      86             :    !!! Test end
      87             : 
      88           0 :    l_converged = .FALSE.
      89             : 
      90             :    ! 0. Add last data pair to history iff it is not obviously destructive for the positive definiteness of the Hessian matrix
      91             : 
      92           0 :    IF(ANY(lastGradient(:).NE.0.0).OR.ANY(lastParameters(:).NE.0.0)) THEN
      93             : 
      94           0 :       WRITE(2501,'(a,12f10.6)') '    gradient: ', gradient(:)
      95           0 :       WRITE(2501,'(a,12f10.6)') 'lastGradient: ', lastGradient(:)
      96           0 :       WRITE(2502,'(a,12f10.6)') '    parameters: ', parameters(:)
      97           0 :       WRITE(2502,'(a,12f10.6)') 'lastParameters: ', lastParameters(:)
      98             : 
      99           0 :       lastGradCorrection(:) = gradient(:) - lastGradient(:)
     100           0 :       lastParamCorrection(:) = parameters(:) - lastParameters(:)
     101           0 :       temp = ddot(vecLength,lastParamCorrection(:),1,lastGradCorrection(:),1)
     102           0 :       IF (temp.GT.eps) THEN
     103             :          ! Add data pair to history
     104           0 :          istep = istep + 1
     105           0 :          stepIndex = MOD(iStep - 1,maxHistoryLength) + 1
     106           0 :          paramCorrections(:,stepIndex) = lastParamCorrection(:)
     107           0 :          gradientCorrections(:,stepIndex) = lastGradCorrection(:)
     108             :       END IF
     109             : 
     110             :       ! Check for convergence and return if converged
     111           0 :       WRITE(*,*) 'MAXVAL(ABS(lastGradCorrection(:))): ', MAXVAL(ABS(lastGradCorrection(:)))
     112           0 :       WRITE(*,*) 'MAXVAL(ABS(lastParamCorrection(:))): ', MAXVAL(ABS(lastParamCorrection(:)))
     113           0 :       WRITE(*,*) 'MAXVAL(ABS(lastGradCorrection(:vecLength-1))): ', MAXVAL(ABS(lastGradCorrection(:vecLength-1)))
     114           0 :       WRITE(*,*) 'MAXVAL(ABS(lastParamCorrection(:vecLength-1))): ', MAXVAL(ABS(lastParamCorrection(:vecLength-1)))
     115             : !      IF(ALL(ABS(lastGradCorrection(:)).LT.convCrit).AND.ALL(ABS(lastParamCorrection(:)).LT.convCrit)) THEN
     116           0 :       IF(ALL(ABS(lastParamCorrection(:vecLength-1)).LT.convCrit)) THEN
     117           0 :          l_converged = .TRUE.
     118             :          RETURN
     119             :       END IF
     120             :    END IF
     121             : 
     122             :    ! 1. Construct Hessian matrix and its inverse.
     123             : 
     124           0 :    historyLength = MIN(istep,maxHistoryLength)
     125             : 
     126           0 :    ALLOCATE(hessMat(vecLength,vecLength))
     127           0 :    ALLOCATE(invHessMat(vecLength,vecLength))
     128           0 :    ALLOCATE(tempMatB(vecLength,vecLength))
     129             : 
     130           0 :    hessMat(:,:) = 0.0
     131           0 :    invHessMat(:,:) = 0.0
     132           0 :    tempMatB(:,:) = 0.0
     133             : 
     134           0 :    DO i = 1, vecLength
     135           0 :       hessMat(i,i) = 1.0
     136           0 :       invHessMat(i,i) = 1.0
     137             :    END DO
     138             : 
     139           0 :    IF(historyLength.EQ.0) THEN
     140           0 :       DO i = 1, vecLength
     141           0 :          hessMat(i,i) = 1.0 / mixParam
     142           0 :          invHessMat(i,i) = mixParam
     143             :       END DO
     144             :    END IF
     145             : 
     146           0 :    DO i = 1, historyLength
     147           0 :       stepIndex = MOD(iStep - historyLength + i - 1,maxHistoryLength) + 1
     148             : 
     149             :       ! First the Hessian matrix
     150             :       ! second correction term
     151           0 :       tempMatB(:,:) = 0.0
     152           0 :       tempVecA(:) = 0.0
     153           0 :       CALL dgemv('N',vecLength,vecLength,1.0,hessMat(:,:),vecLength,paramCorrections(:,stepIndex),1,0.0,tempVecA(:),1)
     154           0 :       norm = ddot(vecLength,paramCorrections(:,stepIndex),1,tempVecA(:),1)
     155           0 :       CALL dgemm('N','N',vecLength,vecLength,1,-1.0/norm,tempVecA(:),vecLength,tempVecA(:),1,0.0,tempMatB,vecLength)
     156             : 
     157             :       ! first correction term
     158           0 :       norm = ddot(vecLength,gradientCorrections(:,stepIndex),1,paramCorrections(:,stepIndex),1)
     159           0 :       CALL dgemm('N','N',vecLength,vecLength,1,1.0/norm,gradientCorrections(:,stepIndex),vecLength,gradientCorrections(:,stepIndex),1,1.0,tempMatB,vecLength)
     160           0 :       hessMat(:,:) = hessMat(:,:) + tempMatB(:,:)
     161             : 
     162             :       ! Now the inverse of the Hessian matrix
     163           0 :       tempMatB(:,:) = 0.0
     164           0 :       tempVecA(:) = 0.0
     165           0 :       CALL dgemv('N',vecLength,vecLength,1.0,invHessMat(:,:),vecLength,gradientCorrections(:,stepIndex),1,0.0,tempVecA(:),1)
     166           0 :       norm = ddot(vecLength,paramCorrections(:,stepIndex),1,gradientCorrections(:,stepIndex),1)
     167             : 
     168             :       ! second correction term
     169           0 :       CALL dgemm('N','N',vecLength,vecLength,1,1.0,tempVecA(:),vecLength,paramCorrections(:,stepIndex),1,0.0,tempMatB,vecLength)
     170             : 
     171           0 :       tempMatB(:,:) = tempMatB(:,:) + TRANSPOSE(tempMatB(:,:))
     172           0 :       tempMatB(:,:) = -tempMatB(:,:) / norm
     173             : 
     174             :       ! first correction term
     175           0 :       temp = norm + ddot(vecLength,gradientCorrections(:,stepIndex),1,tempVecA(:),1)
     176           0 :       CALL dgemm('N','N',vecLength,vecLength,1,temp/(norm*norm),paramCorrections(:,stepIndex),vecLength,paramCorrections(:,stepIndex),1,1.0,tempMatB,vecLength)
     177           0 :       invHessMat(:,:) = invHessMat(:,:) + tempMatB(:,:)
     178             : 
     179             :       !Check whether invHessMat is the inverse of hessMat (for debugging only)
     180           0 :       tempMatB(:,:) = 0.0
     181           0 :       CALL dgemm('N','N',vecLength,vecLength,vecLength,1.0,hessMat(:,:),vecLength,invHessMat(:,:),vecLength,0.0,tempMatB,vecLength)      
     182             : 
     183             :    END DO
     184             : 
     185             :    ! 2. Determine next point based on the gradient, the inverse of the Hessian, and the box constraints
     186             : 
     187           0 :    freeParams(:) = .TRUE.
     188           0 :    prelimNextPoint(:) = parameters(:)
     189           0 :    prelimGradient(:) = gradient(:)
     190             : 
     191           0 :    WRITE(5300,*) '=========================================================='
     192           0 :    WRITE(5300,*) 'bfgs_b2: Starting next point search: '
     193           0 :    WRITE(5300,*) '=========================================================='
     194             : 
     195           0 :    converged = .FALSE.
     196           0 :    DO WHILE (.NOT.converged)
     197             : 
     198           0 :       WRITE(5300,*) 'Point A: '
     199           0 :       WRITE(5300,*) 'prelimNextPoint: '
     200           0 :       WRITE(5300,'(5f20.10)') prelimNextPoint(:)
     201           0 :       WRITE(5300,*) 'prelimGradient: '
     202           0 :       WRITE(5300,'(5f20.10)') prelimGradient(:)
     203             : 
     204             : 
     205             :       ! Determine free parameters (parameters not on boundaries with a gradient pointing outwards)
     206           0 :       numFixedParams = 0
     207           0 :       DO i = 1, vecLength
     208           0 :          IF(enabledConstraints(i)) THEN
     209           0 :             IF((prelimNextPoint(i).LE.minConstraints(i)+eps).AND.(prelimGradient(i).GT.0.0)) THEN
     210           0 :                freeParams(i) = .FALSE.
     211           0 :                numFixedParams = numFixedParams + 1
     212             :             END IF
     213           0 :             IF((prelimNextPoint(i).GE.maxConstraints(i)-eps).AND.(prelimGradient(i).LT.0.0)) THEN
     214           0 :                freeParams(i) = .FALSE.
     215           0 :                numFixedParams = numFixedParams + 1
     216             :             END IF
     217             :          END IF
     218             :       END DO
     219           0 :       numFreeParams = vecLength - numFixedParams
     220             : 
     221             :       ! Perform basis transformation to obtain inverse Hessian matrix for the free parameter subspace
     222             : 
     223           0 :       ALLOCATE (subspaceBasis(vecLength,numFreeParams))
     224           0 :       subspaceBasis = 0.0
     225           0 :       subspaceGrad = 0.0
     226             :       j = 1
     227           0 :       DO i = 1, vecLength
     228           0 :          IF(freeParams(i)) THEN
     229           0 :             subspaceBasis(i,j) = 1.0
     230           0 :             subspaceGrad(j) = prelimGradient(i)
     231           0 :             j = j + 1
     232             :          END IF
     233             :       END DO
     234             : 
     235           0 :       ALLOCATE (tempMatC(vecLength,numFreeParams))
     236           0 :       ALLOCATE (subspaceInvHessMat(numFreeParams,numFreeParams))
     237           0 :       tempMatC(:,:) = 0.0
     238           0 :       subspaceInvHessMat(:,:) = 0.0
     239             : 
     240           0 :       WRITE(5000,*) '========================================================================='
     241           0 :       WRITE(5000,*) 'prelimNextPoint: '
     242           0 :       WRITE(5000,'(5f20.10)') prelimNextPoint(:)
     243           0 :       WRITE(5000,*) 'prelimGradient: '
     244           0 :       WRITE(5000,'(5f20.10)') prelimGradient(:)
     245           0 :       WRITE(5000,*) 'subspaceBasis: '
     246           0 :       DO i = 1, SIZE(subspaceBasis,2)
     247           0 :          WRITE(5000,'(5f20.10)') subspaceBasis(:,i)
     248             :       END DO
     249             : 
     250           0 :       CALL dgemm('N','N',vecLength,numFreeParams,vecLength,1.0,invHessMat(:,:),vecLength,subspaceBasis(:,:),vecLength,0.0,tempMatC(:,:),vecLength)
     251           0 :       CALL dgemm('N','N',numFreeParams,numFreeParams,vecLength,1.0,TRANSPOSE(subspaceBasis(:,:)),numFreeParams,tempMatC(:,:),vecLength,0.0,subspaceInvHessMat(:,:),numFreeParams)
     252             :       
     253           0 :       DEALLOCATE(tempMatC)
     254           0 :       DEALLOCATE(subspaceBasis)
     255             : 
     256             :       ! Calculate next point (ignoring constraints)
     257             : 
     258           0 :       tempVecA(:) = 0.0
     259             : 
     260           0 :       WRITE(5000,*) 'numFreeParams: ', numFreeParams
     261           0 :       WRITE(5000,*) 'subspaceInvHessMat: '
     262           0 :       DO i = 1, SIZE(subspaceInvHessMat,2)
     263           0 :          WRITE(5000,'(5f20.10)') subspaceInvHessMat(:,i)
     264             :       END DO
     265           0 :       WRITE(5000,*) '-subspaceGrad: '
     266           0 :       WRITE(5000,'(5f20.10)') -subspaceGrad(:numFreeParams)
     267           0 :       WRITE(5000,*) 'tempVecA: '
     268           0 :       WRITE(5000,'(5f20.10)') tempVecA(:numFreeParams)
     269             : 
     270           0 :       CALL dgemv('N',numFreeParams,numFreeParams,1.0,subspaceInvHessMat(:,:),numFreeParams,-subspaceGrad(:numFreeParams),1,0.0,tempVecA(:numFreeParams),1)
     271             : 
     272           0 :       WRITE(5000,*) '----------------------------'
     273           0 :       WRITE(5000,*) 'tempVecA: '
     274           0 :       WRITE(5000,'(5f20.10)') tempVecA(:numFreeParams)
     275           0 :       WRITE(5000,*) 'prelimNextPoint: '
     276           0 :       WRITE(5000,'(5f20.10)') prelimNextPoint(:)
     277             : 
     278             :       !!! TEST START
     279             : !      temp = SQRT(ddot(numFreeParams,tempVecA(:numFreeParams),1,tempVecA(:numFreeParams),1))
     280           0 :       temp = MAXVAL(ABS(tempVecA(:numFreeParams-1)))
     281           0 :       maxDisp = 0.05
     282           0 :       IF (temp.GT.maxDisp) tempVecA(:numFreeParams) = tempVecA(:numFreeParams) / (temp/maxDisp)
     283             :       dampingFactor = 0.5
     284             :       !!! TEST END
     285             : 
     286             :       j = 1
     287           0 :       DO i = 1, vecLength
     288           0 :          IF(freeParams(i)) THEN
     289           0 :             prelimNextPoint(i) = prelimNextPoint(i) + dampingFactor * tempVecA(j)
     290             : !            prelimNextPoint(i) = prelimNextPoint(i) + tempVecA(j)
     291           0 :             j = j + 1
     292             :          END IF
     293             :       END DO
     294             : 
     295           0 :       WRITE(5000,*) 'prelimNextPoint: '
     296           0 :       WRITE(5000,'(5f20.10)') prelimNextPoint(:)
     297             : 
     298           0 :       DEALLOCATE(subspaceInvHessMat)
     299             : 
     300             :       ! Constrain next point to box and check convergence
     301           0 :       converged = .TRUE.
     302           0 :       DO i = 1, vecLength
     303           0 :          IF (enabledConstraints(i).AND.freeParams(i)) THEN
     304             :             IF(prelimNextPoint(i).LT.minConstraints(i)-eps) THEN
     305             : !               converged = .FALSE.
     306             :             END IF
     307             :             IF(prelimNextPoint(i).GT.maxConstraints(i)+eps) THEN
     308             : !               converged = .FALSE.
     309             :             END IF
     310           0 :             IF(prelimNextPoint(i).LT.minConstraints(i)) THEN
     311           0 :                prelimNextPoint(i) = minConstraints(i)
     312             :             END IF
     313           0 :             IF(prelimNextPoint(i).GT.maxConstraints(i)) THEN
     314           0 :                prelimNextPoint(i) = maxConstraints(i)
     315             :             END IF
     316             :          END IF
     317             :       END DO
     318             : 
     319           0 :       WRITE(5000,*) 'prelimNextPoint: '
     320           0 :       WRITE(5000,'(5f20.10)') prelimNextPoint(:)
     321           0 :       WRITE(5000,*) 'prelimGradient: '
     322           0 :       WRITE(5000,'(5f20.10)') prelimGradient(:)
     323             : 
     324             :       ! If not converged calculate prelimGradient for next point according to quadratic model
     325             :       IF(.NOT.converged) THEN
     326             :          diffPoint(:) = prelimNextPoint(:) - parameters(:)
     327             :          diffGrad(:) = 0.0
     328             :          CALL dgemv('N',vecLength,vecLength,1.0,hessMat(:,:),vecLength,diffPoint(:),1,0.0,diffGrad(:),1)
     329             :          prelimGradient(:) = prelimGradient(:) + diffGrad(:)
     330             :       END IF
     331             : 
     332             :       ! Test: Set the gradient entry for the Lagrange multiplier explicitly
     333             :       ! (I hope this makes the approach more stable. The here introduced data is not automatically obtained)
     334           0 :       temp = ddot(vecLength,equalityLinCombi(:vecLength),1,prelimNextPoint(:vecLength),1)
     335           0 :       prelimGradient(vecLength) = temp - equalityCriterion   ! derivative with respect to the Lagrange parameter
     336             : 
     337           0 :       WRITE(5000,*) 'prelimGradient: '
     338           0 :       WRITE(5000,'(5f20.10)') prelimGradient(:)
     339             : 
     340             :    END DO
     341             : 
     342             :    ! 3. Project prelimNextPoint onto the allowed subspace given by the equality constraints
     343             :    ! Note: I only consider a single equality constraint so this part becomes simpler
     344             : 
     345             :    ! Determine free parameters (parameters not on boundaries with a gradient pointing outwards)
     346             : 
     347             : !   WRITE(5200,*) '=========================================================='
     348             : !   WRITE(5200,*) 'bfgs_b2: Starting charge constraint ensurance: '
     349             : !   WRITE(5200,*) '=========================================================='
     350             : 
     351             :    converged = .FALSE.
     352           0 :    DO WHILE (.NOT.converged)
     353             : 
     354             : !      WRITE(5200,*) 'Point A: '
     355             : !      WRITE(5200,*) 'prelimNextPoint: '
     356             : !      WRITE(5200,'(5f20.10)') prelimNextPoint(:)
     357             : 
     358           0 :       freeParams(:) = .TRUE.
     359           0 :       numFixedParams = 0
     360           0 :       DO i = 1, vecLength
     361           0 :          IF(enabledConstraints(i)) THEN
     362           0 :             IF(prelimNextPoint(i).LT.minConstraints(i) - eps) THEN
     363           0 :                freeParams(i) = .FALSE.
     364           0 :                numFixedParams = numFixedParams + 1
     365             :             END IF
     366           0 :             IF(prelimNextPoint(i).GT.maxConstraints(i) + eps) THEN
     367           0 :                freeParams(i) = .FALSE.
     368           0 :                numFixedParams = numFixedParams + 1
     369             :             END IF
     370           0 :             IF(prelimNextPoint(i).LT.minConstraints(i)) THEN
     371           0 :                prelimNextPoint(i) = minConstraints(i)
     372             :             END IF
     373           0 :             IF(prelimNextPoint(i).GT.maxConstraints(i)) THEN
     374           0 :                prelimNextPoint(i) = maxConstraints(i)
     375             :             END IF
     376             :          END IF
     377             :       END DO
     378           0 :       numFreeParams = vecLength - numFixedParams
     379             : 
     380           0 :       subspaceNextPoint(:) = 0.0
     381           0 :       subspaceLinCombi(:) = 0.0
     382           0 :       subspaceEqualityCrit = equalityCriterion
     383           0 :       j = 1
     384           0 :       DO i = 1, vecLength
     385           0 :          IF(freeParams(i)) THEN
     386           0 :             subspaceNextPoint(j) = prelimNextPoint(i)
     387           0 :             subspaceLinCombi(j) = equalityLinCombi(i)
     388           0 :             j = j + 1
     389             :          ELSE
     390           0 :             subspaceEqualityCrit = subspaceEqualityCrit - prelimNextPoint(i) * equalityLinCombi(i)
     391             :          END IF
     392             :       END DO
     393             : 
     394           0 :       temp = ddot(numFreeParams,subspaceLinCombi(:),1,subspaceNextPoint(:),1)
     395           0 :       converged = .TRUE.
     396           0 :       IF(ABS(temp - subspaceEqualityCrit).GT.largeEps) THEN
     397           0 :          converged = .FALSE.
     398             : 
     399             : !         WRITE(5100,*) 'subspaceNextPoint(:): '
     400             : !         WRITE(5100,*) subspaceNextPoint(:)
     401             : !         WRITE(5100,*) 'subspaceEqualityCrit: ', subspaceEqualityCrit
     402             : !         WRITE(5100,*) 'temp: ', temp
     403             : 
     404           0 :          subspaceNextPoint(:) = subspaceNextPoint(:) * subspaceEqualityCrit / temp
     405             :       END IF
     406           0 :       j = 1
     407           0 :       DO i = 1, vecLength
     408           0 :          IF(freeParams(i)) THEN
     409           0 :             prelimNextPoint(i) = subspaceNextPoint(j)
     410           0 :             j = j + 1
     411             :          END IF
     412             :       END DO
     413             : 
     414             :       ! Also ensure that the equality criterion is fulfilled for the whole space.
     415             :       ! (This is only for pathological cases)
     416             : 
     417           0 :       temp = ddot(vecLength,equalityLinCombi(:vecLength),1,prelimNextPoint(:vecLength),1)
     418           0 :       IF(ABS(temp - equalityCriterion).GT.largeEps) THEN
     419           0 :          converged = .FALSE.
     420           0 :          prelimNextPoint(:vecLength) = prelimNextPoint(:vecLength) * equalityCriterion / temp
     421             :       END IF
     422             : 
     423             :    END DO
     424             : 
     425             :    ! 4. Update lastParameters, lastGradient, parameters
     426             : 
     427           0 :    lastParameters(:) = parameters(:)
     428           0 :    lastGradient(:) = gradient(:)
     429           0 :    parameters(:) = prelimNextPoint(:)
     430             : !   parameters(:) = 0.25*(prelimNextPoint(:) - lastParameters(:)) + lastParameters(:)
     431             : 
     432           0 :    DEALLOCATE(tempMatB)
     433           0 :    DEALLOCATE(invHessMat)
     434           0 :    DEALLOCATE(hessMat)
     435             : 
     436           0 :    WRITE(*,*) 'bfgs_b2 (output): parameters(:vecLength): ', parameters(:vecLength)
     437             : 
     438             : END SUBROUTINE bfgs_b2
     439             : 
     440             : END MODULE m_bfgs_b2

Generated by: LCOV version 1.14