LCOV - code coverage report
Current view: top level - src/common - powell.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:21ef868) Lines: 94.2 % 1099 1035
Test Date: 2026-08-14 07:04:57 Functions: 94.1 % 17 16

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : !******************************************************************************
       9              : MODULE powell
      10              :    USE kinds,                           ONLY: dp
      11              :    USE mathconstants,                   ONLY: twopi
      12              : #include "../base/base_uses.f90"
      13              : 
      14              :    IMPLICIT NONE
      15              : 
      16              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'powell'
      17              : 
      18              :    TYPE opt_state_type
      19              :       INTEGER            :: state = -1
      20              :       INTEGER            :: nvar = -1
      21              :       INTEGER            :: iprint = -1
      22              :       INTEGER            :: unit = -1
      23              :       INTEGER            :: maxfun = -1
      24              :       REAL(dp)           :: rhobeg = 0.0_dp, rhoend = 0.0_dp
      25              :       REAL(dp), DIMENSION(:), POINTER  :: w => NULL()
      26              :       REAL(dp), DIMENSION(:), POINTER  :: xopt => NULL()
      27              :       ! local variables
      28              :       INTEGER            :: np = -1, nh = -1, nptm = -1, nftest = -1, idz = -1, itest = -1, nf = -1, nfm = -1, nfmm = -1, &
      29              :                             nfsav = -1, knew = -1, kopt = -1, ksave = -1, ktemp = -1
      30              :       REAL(dp)           :: rhosq = 0.0_dp, recip = 0.0_dp, reciq = 0.0_dp, fbeg = 0.0_dp, &
      31              :                             fopt = 0.0_dp, diffa = 0.0_dp, xoptsq = 0.0_dp, &
      32              :                             rho = 0.0_dp, delta = 0.0_dp, dsq = 0.0_dp, dnorm = 0.0_dp, &
      33              :                             ratio = 0.0_dp, temp = 0.0_dp, tempq = 0.0_dp, beta = 0.0_dp, &
      34              :                             dx = 0.0_dp, vquad = 0.0_dp, diff = 0.0_dp, diffc = 0.0_dp, &
      35              :                             diffb = 0.0_dp, fsave = 0.0_dp, detrat = 0.0_dp, hdiag = 0.0_dp, &
      36              :                             distsq = 0.0_dp, gisq = 0.0_dp, gqsq = 0.0_dp, f = 0.0_dp, &
      37              :                             bstep = 0.0_dp, alpha = 0.0_dp, dstep = 0.0_dp
      38              :    END TYPE opt_state_type
      39              : 
      40              :    PRIVATE
      41              :    PUBLIC      :: powell_optimize, opt_state_type
      42              : 
      43              : CONTAINS
      44              : 
      45              : ! **************************************************************************************************
      46              : !> \brief ...
      47              : !> \param n ...
      48              : !> \param x ...
      49              : !> \param optstate ...
      50              : ! **************************************************************************************************
      51     60386695 :    SUBROUTINE powell_optimize(n, x, optstate)
      52              :       INTEGER, INTENT(IN)                                :: n
      53              :       REAL(dp), DIMENSION(*), INTENT(INOUT)              :: x
      54              :       TYPE(opt_state_type), INTENT(INOUT)                :: optstate
      55              : 
      56              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'powell_optimize'
      57              : 
      58              :       INTEGER                                            :: handle, npt
      59              : 
      60     60386695 :       CALL timeset(routineN, handle)
      61              : 
      62     61151520 :       SELECT CASE (optstate%state)
      63              :       CASE (0)
      64       764825 :          npt = 2*n + 1
      65      2294475 :          ALLOCATE (optstate%w((npt + 13)*(npt + n) + 3*n*(n + 3)/2))
      66      2294475 :          ALLOCATE (optstate%xopt(n))
      67              :          ! Initialize w
      68    108742927 :          optstate%w = 0.0_dp
      69       764825 :          optstate%state = 1
      70       764825 :          CALL newuoa(n, x, optstate)
      71              :       CASE (1, 2)
      72     58092223 :          CALL newuoa(n, x, optstate)
      73              :       CASE (3)
      74            9 :          IF (optstate%unit > 0) THEN
      75            6 :             WRITE (optstate%unit, *) "POWELL| Exceeding maximum number of steps"
      76              :          END IF
      77            9 :          optstate%state = -1
      78              :       CASE (4)
      79            4 :          IF (optstate%unit > 0) THEN
      80            4 :             WRITE (optstate%unit, *) "POWELL| Error in trust region"
      81              :          END IF
      82            4 :          optstate%state = -1
      83              :       CASE (5)
      84            0 :          IF (optstate%unit > 0) THEN
      85            0 :             WRITE (optstate%unit, *) "POWELL| N out of range"
      86              :          END IF
      87            0 :          optstate%state = -1
      88              :       CASE (6, 7)
      89       764809 :          optstate%state = -1
      90              :       CASE (8)
      91      2294797 :          x(1:n) = optstate%xopt(1:n)
      92       764825 :          DEALLOCATE (optstate%w)
      93       764825 :          DEALLOCATE (optstate%xopt)
      94       764825 :          optstate%state = -1
      95              :       CASE DEFAULT
      96     60386695 :          CPABORT("Unknown optimization state")
      97              :       END SELECT
      98              : 
      99     60386695 :       CALL timestop(handle)
     100              : 
     101     60386695 :    END SUBROUTINE powell_optimize
     102              : ! **************************************************************************************************
     103              : !> \brief ...
     104              : !> \param n ...
     105              : !> \param x ...
     106              : !> \param optstate ...
     107              : ! **************************************************************************************************
     108     58857048 :    SUBROUTINE newuoa(n, x, optstate)
     109              : 
     110              :       INTEGER, INTENT(IN)                                :: n
     111              :       REAL(dp), DIMENSION(*), INTENT(INOUT)              :: x
     112              :       TYPE(opt_state_type), INTENT(INOUT)                :: optstate
     113              : 
     114              :       INTEGER                                            :: ibmat, id, ifv, igq, ihq, ipq, ivl, iw, &
     115              :                                                             ixb, ixn, ixo, ixp, izmat, maxfun, &
     116              :                                                             ndim, np, npt, nptm
     117              :       REAL(dp)                                           :: rhobeg, rhoend
     118              : 
     119     58857048 :       maxfun = optstate%maxfun
     120     58857048 :       rhobeg = optstate%rhobeg
     121     58857048 :       rhoend = optstate%rhoend
     122              : 
     123              :       !
     124              :       !     This subroutine seeks the least value of a function of many variab
     125              :       !     by a trust region method that forms quadratic models by interpolat
     126              :       !     There can be some freedom in the interpolation conditions, which i
     127              :       !     taken up by minimizing the Frobenius norm of the change to the sec
     128              :       !     derivative of the quadratic model, beginning with a zero matrix. T
     129              :       !     arguments of the subroutine are as follows.
     130              :       !
     131              :       !     N must be set to the number of variables and must be at least two.
     132              :       !     NPT is the number of interpolation conditions. Its value must be i
     133              :       !       interval [N+2,(N+1)(N+2)/2].
     134              :       !     Initial values of the variables must be set in X(1),X(2),...,X(N).
     135              :       !       will be changed to the values that give the least calculated F.
     136              :       !     RHOBEG and RHOEND must be set to the initial and final values of a
     137              :       !       region radius, so both must be positive with RHOEND<=RHOBEG. Typ
     138              :       !       RHOBEG should be about one tenth of the greatest expected change
     139              :       !       variable, and RHOEND should indicate the accuracy that is requir
     140              :       !       the final values of the variables.
     141              :       !     The value of IPRINT should be set to 0, 1, 2 or 3, which controls
     142              :       !       amount of printing. Specifically, there is no output if IPRINT=0
     143              :       !       there is output only at the return if IPRINT=1. Otherwise, each
     144              :       !       value of RHO is printed, with the best vector of variables so fa
     145              :       !       the corresponding value of the objective function. Further, each
     146              :       !       value of F with its variables are output if IPRINT=3.
     147              :       !     MAXFUN must be set to an upper bound on the number of calls of CAL
     148              :       !     The array W will be used for working space. Its length must be at
     149              :       !     (NPT+13)*(NPT+N)+3*N*(N+3)/2.
     150              :       !
     151              :       !     SUBROUTINE CALFUN (N,X,F) must be provided by the user. It must se
     152              :       !     the value of the objective function for the variables X(1),X(2),..
     153              :       !
     154              :       !     Partition the working space array, so that different parts of it c
     155              :       !     treated separately by the subroutine that performs the main calcul
     156              :       !
     157     58857048 :       np = n + 1
     158     58857048 :       npt = 2*n + 1
     159     58857048 :       nptm = npt - np
     160     58857048 :       IF (npt < n + 2 .OR. npt > ((n + 2)*np)/2) THEN
     161            0 :          optstate%state = 5
     162            0 :          RETURN
     163              :       END IF
     164     58857048 :       ndim = npt + n
     165     58857048 :       ixb = 1
     166     58857048 :       ixo = ixb + n
     167     58857048 :       ixn = ixo + n
     168     58857048 :       ixp = ixn + n
     169     58857048 :       ifv = ixp + n*npt
     170     58857048 :       igq = ifv + npt
     171     58857048 :       ihq = igq + n
     172     58857048 :       ipq = ihq + (n*np)/2
     173     58857048 :       ibmat = ipq + npt
     174     58857048 :       izmat = ibmat + ndim*n
     175     58857048 :       id = izmat + npt*nptm
     176     58857048 :       ivl = id + n
     177     58857048 :       iw = ivl + ndim
     178              :       !
     179              :       !     The above settings provide a partition of W for subroutine NEWUOB.
     180              :       !     The partition requires the first NPT*(NPT+N)+5*N*(N+3)/2 elements
     181              :       !     W plus the space that is needed by the last array of NEWUOB.
     182              :       !
     183              :       CALL newuob(n, npt, x, rhobeg, rhoend, maxfun, optstate%w(ixb:), optstate%w(ixo:), &
     184              :                   optstate%w(ixn:), optstate%w(ixp:), optstate%w(ifv:), optstate%w(igq:), optstate%w(ihq:), &
     185              :                   optstate%w(ipq:), optstate%w(ibmat:), optstate%w(izmat:), ndim, optstate%w(id:), &
     186     58857048 :                   optstate%w(ivl:), optstate%w(iw:), optstate)
     187              : 
     188    176582780 :       optstate%xopt(1:n) = optstate%w(ixb:ixb + n - 1) + optstate%w(ixo:ixo + n - 1)
     189              : 
     190              :    END SUBROUTINE newuoa
     191              : 
     192              : ! **************************************************************************************************
     193              : !> \brief ...
     194              : !> \param n ...
     195              : !> \param npt ...
     196              : !> \param x ...
     197              : !> \param rhobeg ...
     198              : !> \param rhoend ...
     199              : !> \param maxfun ...
     200              : !> \param xbase ...
     201              : !> \param xopt ...
     202              : !> \param xnew ...
     203              : !> \param xpt ...
     204              : !> \param fval ...
     205              : !> \param gq ...
     206              : !> \param hq ...
     207              : !> \param pq ...
     208              : !> \param bmat ...
     209              : !> \param zmat ...
     210              : !> \param ndim ...
     211              : !> \param d ...
     212              : !> \param vlag ...
     213              : !> \param w ...
     214              : !> \param opt ...
     215              : ! **************************************************************************************************
     216     58857048 :    SUBROUTINE newuob(n, npt, x, rhobeg, rhoend, maxfun, xbase, &
     217     58857048 :                      xopt, xnew, xpt, fval, gq, hq, pq, bmat, zmat, ndim, d, vlag, w, opt)
     218              : 
     219              :       INTEGER, INTENT(in)                   :: n, npt
     220              :       REAL(dp), DIMENSION(1:n), INTENT(inout)  :: x
     221              :       REAL(dp), INTENT(in)                  :: rhobeg, rhoend
     222              :       INTEGER, INTENT(in)                   :: maxfun
     223              :       REAL(dp), DIMENSION(*), INTENT(inout)    :: xbase, xopt, xnew
     224              :       REAL(dp), DIMENSION(npt, *), &
     225              :          INTENT(inout)                          :: xpt
     226              :       REAL(dp), DIMENSION(*), INTENT(inout)    :: fval, gq, hq, pq
     227              :       INTEGER, INTENT(in)                   :: ndim
     228              :       REAL(dp), DIMENSION(npt, *), &
     229              :          INTENT(inout)                          :: zmat
     230              :       REAL(dp), DIMENSION(ndim, *), &
     231              :          INTENT(inout)                          :: bmat
     232              :       REAL(dp), DIMENSION(*), INTENT(inout)    :: d, vlag, w
     233              :       TYPE(opt_state_type)                     :: opt
     234              : 
     235              :       INTEGER                                  :: i, idz, ih, ip, ipt, itemp, &
     236              :                                                   itest, j, jp, jpt, k, knew, &
     237              :                                                   kopt, ksave, ktemp, nf, nfm, &
     238              :                                                   nfmm, nfsav, nftest, nh, np, &
     239              :                                                   nptm
     240              :       LOGICAL :: do_return, skip_check
     241              :       REAL(dp) :: alpha, beta, bstep, bsum, crvmin, delta, detrat, diff, diffa, &
     242              :                   diffb, diffc, distsq, dnorm, dsq, dstep, dx, f, fbeg, fopt, fsave, &
     243              :                   gisq, gqsq, half, hdiag, one, ratio, recip, reciq, rho, rhosq, sum, &
     244              :                   suma, sumb, sumz, temp, tempq, tenth, vquad, xipt, xjpt, xoptsq, zero
     245              : 
     246              : !
     247              : !     The arguments N, NPT, X, RHOBEG, RHOEND, IPRINT and MAXFUN are ide
     248              : !       to the corresponding arguments in SUBROUTINE NEWUOA.
     249              : !     XBASE will hold a shift of origin that should reduce the contribut
     250              : !       from rounding errors to values of the model and Lagrange functio
     251              : !     XOPT will be set to the displacement from XBASE of the vector of
     252              : !       variables that provides the least calculated F so far.
     253              : !     XNEW will be set to the displacement from XBASE of the vector of
     254              : !       variables for the current calculation of F.
     255              : !     XPT will contain the interpolation point coordinates relative to X
     256              : !     FVAL will hold the values of F at the interpolation points.
     257              : !     GQ will hold the gradient of the quadratic model at XBASE.
     258              : !     HQ will hold the explicit second derivatives of the quadratic mode
     259              : !     PQ will contain the parameters of the implicit second derivatives
     260              : !       the quadratic model.
     261              : !     BMAT will hold the last N columns of H.
     262              : !     ZMAT will hold the factorization of the leading NPT by NPT submatr
     263              : !       H, this factorization being ZMAT times Diag(DZ) times ZMAT^T, wh
     264              : !       the elements of DZ are plus or minus one, as specified by IDZ.
     265              : !     NDIM is the first dimension of BMAT and has the value NPT+N.
     266              : !     D is reserved for trial steps from XOPT.
     267              : !     VLAG will contain the values of the Lagrange functions at a new po
     268              : !       They are part of a product that requires VLAG to be of length ND
     269              : !     The array W will be used for working space. Its length must be at
     270              : !       10*NDIM = 10*(NPT+N).
     271              : 
     272     58857048 :       skip_check = .FALSE.
     273     58857048 :       do_return = .FALSE.
     274              : 
     275     58857048 :       IF (opt%state == 1) THEN
     276              :          ! initialize all variable that will be stored
     277              :          np = 0
     278              :          nh = 0
     279              :          nptm = 0
     280              :          nftest = 0
     281       764825 :          idz = 0
     282       764825 :          itest = 0
     283       764825 :          nf = 0
     284       764825 :          nfm = 0
     285       764825 :          nfmm = 0
     286       764825 :          nfsav = 0
     287       764825 :          knew = 0
     288       764825 :          kopt = 0
     289       764825 :          ksave = 0
     290       764825 :          ktemp = 0
     291       764825 :          rhosq = 0._dp
     292       764825 :          recip = 0._dp
     293       764825 :          reciq = 0._dp
     294       764825 :          fbeg = 0._dp
     295       764825 :          fopt = 0._dp
     296       764825 :          diffa = 0._dp
     297       764825 :          xoptsq = 0._dp
     298       764825 :          rho = 0._dp
     299       764825 :          delta = 0._dp
     300       764825 :          dsq = 0._dp
     301       764825 :          dnorm = 0._dp
     302       764825 :          ratio = 0._dp
     303       764825 :          temp = 0._dp
     304       764825 :          tempq = 0._dp
     305       764825 :          beta = 0._dp
     306       764825 :          dx = 0._dp
     307       764825 :          vquad = 0._dp
     308       764825 :          diff = 0._dp
     309       764825 :          diffc = 0._dp
     310       764825 :          diffb = 0._dp
     311       764825 :          fsave = 0._dp
     312       764825 :          detrat = 0._dp
     313       764825 :          hdiag = 0._dp
     314       764825 :          distsq = 0._dp
     315       764825 :          gisq = 0._dp
     316       764825 :          gqsq = 0._dp
     317       764825 :          f = 0._dp
     318       764825 :          bstep = 0._dp
     319       764825 :          alpha = 0._dp
     320       764825 :          dstep = 0._dp
     321              :          !
     322              :       END IF
     323              : 
     324     58857048 :       ipt = 0
     325     58857048 :       jpt = 0
     326     58857048 :       xipt = 0._dp
     327     58857048 :       xjpt = 0._dp
     328              : 
     329     58857048 :       half = 0.5_dp
     330     58857048 :       one = 1.0_dp
     331     58857048 :       tenth = 0.1_dp
     332     58857048 :       zero = 0.0_dp
     333     58857048 :       np = n + 1
     334     58857048 :       nh = (n*np)/2
     335     58857048 :       nptm = npt - np
     336     58857048 :       nftest = MAX(maxfun, 1)
     337              : 
     338     58857048 :       IF (opt%state /= 2) THEN
     339              :          !
     340              :          !     Set the initial elements of XPT, BMAT, HQ, PQ and ZMAT to zero.
     341              :          !
     342      2294797 :          DO j = 1, n
     343      1529972 :             xbase(j) = x(j)
     344      9211120 :             DO k = 1, npt
     345      9211120 :                xpt(k, j) = zero
     346              :             END DO
     347     13051533 :             DO i = 1, ndim
     348     12286708 :                bmat(i, j) = zero
     349              :             END DO
     350              :          END DO
     351      3067605 :          DO ih = 1, nh
     352      3067605 :             hq(ih) = zero
     353              :          END DO
     354      4589594 :          DO k = 1, npt
     355      3824769 :             pq(k) = zero
     356     12270742 :             DO j = 1, nptm
     357     11505917 :                zmat(k, j) = zero
     358              :             END DO
     359              :          END DO
     360              :          !
     361              :          !     Begin the initialization procedure. NF becomes one more than the n
     362              :          !     of function values so far. The coordinates of the displacement of
     363              :          !     next initial interpolation point from XBASE are set in XPT(NF,.).
     364              :          !
     365       764825 :          rhosq = rhobeg*rhobeg
     366       764825 :          recip = one/rhosq
     367       764825 :          reciq = SQRT(half)/rhosq
     368       764825 :          nf = 0
     369       764825 :          CALL begin_initialization_of_interpolation
     370     24194113 :          RETURN
     371              :       END IF
     372              : 
     373     58092223 :       CALL set_state
     374              : 
     375     58092223 :       preparation: IF (nf <= npt) THEN
     376      3824292 :          fval(nf) = f
     377      3824292 :          IF (nf == 1) THEN
     378       764825 :             fbeg = f
     379       764825 :             fopt = f
     380       764825 :             kopt = 1
     381      3059467 :          ELSE IF (f < fopt) THEN
     382       853903 :             fopt = f
     383       853903 :             kopt = nf
     384              :          END IF
     385              :          !
     386              :          !     Set the nonzero initial elements of BMAT and the quadratic model i
     387              :          !     the cases when NF is at most 2*N+1.
     388              :          !
     389      3824292 :          IF (NFM <= 2*N) THEN
     390      3824292 :             IF (nfm >= 1 .AND. nfm <= n) THEN
     391      1529766 :                gq(nfm) = (f - fbeg)/rhobeg
     392      1529766 :                IF (npt < nf + n) THEN
     393            0 :                   bmat(1, nfm) = -one/rhobeg
     394            0 :                   bmat(nf, nfm) = one/rhobeg
     395            0 :                   bmat(npt + nfm, nfm) = -half*rhosq
     396              :                END IF
     397      2294526 :             ELSE IF (nfm > n) THEN
     398      1529701 :                bmat(nf - n, nfmm) = half/rhobeg
     399      1529701 :                bmat(nf, nfmm) = -half/rhobeg
     400      1529701 :                zmat(1, nfmm) = -reciq - reciq
     401      1529701 :                zmat(nf - n, nfmm) = reciq
     402      1529701 :                zmat(nf, nfmm) = reciq
     403      1529701 :                ih = (nfmm*(nfmm + 1))/2
     404      1529701 :                temp = (fbeg - f)/rhobeg
     405      1529701 :                hq(ih) = (gq(nfmm) - temp)/rhobeg
     406      1529701 :                gq(nfmm) = half*(gq(nfmm) + temp)
     407              :             END IF
     408              :             !
     409              :             !     Set the off-diagonal second derivatives of the Lagrange functions
     410              :             !     the initial quadratic model.
     411              :             !
     412              :          ELSE
     413            0 :             ih = (ipt*(ipt - 1))/2 + jpt
     414              :             IF (xipt < zero) ipt = ipt + n
     415              :             IF (xjpt < zero) jpt = jpt + n
     416            0 :             zmat(1, nfmm) = recip
     417            0 :             zmat(nf, nfmm) = recip
     418            0 :             zmat(ipt + 1, nfmm) = -recip
     419              :             zmat(jpt + 1, nfmm) = -recip
     420            0 :             hq(ih) = (fbeg - fval(ipt + 1) - fval(jpt + 1) + f)/(xipt*xjpt)
     421              :          END IF
     422      3824292 :          IF (nf < npt) THEN
     423      3059476 :             CALL begin_initialization_of_interpolation
     424      3059476 :             RETURN
     425              :          END IF
     426              :          !
     427              :          !     Begin the iterative procedure, because the initial model is comple
     428              :          !
     429       764816 :          rho = rhobeg
     430       764816 :          delta = rho
     431       764816 :          idz = 1
     432       764816 :          diffa = zero
     433       764816 :          diffb = zero
     434       764816 :          itest = 0
     435       764816 :          xoptsq = zero
     436      2294517 :          DO i = 1, n
     437      1529701 :             xopt(i) = xpt(kopt, i)
     438      2294517 :             xoptsq = xoptsq + xopt(i)**2
     439              :          END DO
     440       764816 :          nfsav = nf
     441              :          !
     442              :          !     Generate the next trust region step and test its length. Set KNEW
     443              :          !     to -1 if the purpose of the next F will be to improve the model.
     444              :          !
     445       764816 :          skip_check = .TRUE.
     446              :          ELSE preparation
     447     54267931 :          IF (knew == -1) THEN
     448       638430 :             opt%state = 6
     449       638430 :             CALL get_state
     450       638430 :             CALL finalize_optimization_after_failure
     451       638430 :             RETURN
     452              :          END IF
     453              :          !
     454              :          !     Use the quadratic model to predict the change in F due to the step
     455              :          !     and set DIFF to the error of this prediction.
     456              :          !
     457     53629501 :          vquad = zero
     458     53629501 :          ih = 0
     459    160894356 :          DO j = 1, n
     460    107264855 :             vquad = vquad + d(j)*gq(j)
     461    321807118 :             DO i = 1, j
     462    160912762 :                ih = ih + 1
     463    160912762 :                temp = d(i)*xnew(j) + d(j)*xopt(i)
     464    160912762 :                IF (i == j) temp = half*temp
     465    268177617 :                vquad = vquad + temp*hq(ih)
     466              :             END DO
     467              :          END DO
     468    321788712 :          DO k = 1, npt
     469    321788712 :             vquad = vquad + pq(k)*w(k)
     470              :          END DO
     471     53629501 :          diff = f - fopt - vquad
     472     53629501 :          diffc = diffb
     473     53629501 :          diffb = diffa
     474     53629501 :          diffa = ABS(diff)
     475     53629501 :          IF (dnorm > rho) nfsav = nf
     476              :          !
     477              :          !     Update FOPT and XOPT if the new F is the least value of the object
     478              :          !     function so far. The branch when KNEW is positive occurs if D is n
     479              :          !     a trust region step.
     480              :          !
     481     53629501 :          fsave = fopt
     482     53629501 :          IF (f < fopt) THEN
     483     27399973 :             fopt = f
     484     27399973 :             xoptsq = zero
     485     82201822 :             DO i = 1, n
     486     54801849 :                xopt(i) = xnew(i)
     487     82201822 :                xoptsq = xoptsq + xopt(i)**2
     488              :             END DO
     489              :          END IF
     490     53629501 :          ksave = knew
     491     53629501 :          IF (knew <= 0) THEN
     492              :             !
     493              :             !     Pick the next value of DELTA after a trust region step.
     494              :             !
     495     34662934 :             IF (vquad >= zero) THEN
     496              :                ! Return because a trust region step has failed to reduce Q
     497            4 :                opt%state = 4
     498            4 :                CALL get_state
     499            4 :                CALL finalize_optimization_after_failure
     500            4 :                RETURN
     501              :             END IF
     502     34662930 :             ratio = (f - fsave)/vquad
     503     34662930 :             IF (ratio <= tenth) THEN
     504     12837415 :                delta = half*dnorm
     505     21825515 :             ELSE IF (ratio <= 0.7_dp) THEN
     506      3775267 :                delta = MAX(half*delta, dnorm)
     507              :             ELSE
     508     18050248 :                delta = MAX(half*delta, dnorm + dnorm)
     509              :             END IF
     510     34662930 :             IF (delta <= 1.5_dp*rho) delta = rho
     511              :             !
     512              :             !     Set KNEW to the index of the next interpolation point to be delete
     513              :             !
     514     34662930 :             rhosq = MAX(tenth*delta, rho)**2
     515     34662930 :             ktemp = 0
     516     34662930 :             detrat = zero
     517     34662930 :             IF (f >= fsave) THEN
     518     11021104 :                ktemp = kopt
     519     11021104 :                detrat = one
     520              :             END IF
     521    207984594 :             DO k = 1, npt
     522    173321664 :                hdiag = zero
     523    520005361 :                DO j = 1, nptm
     524    346683697 :                   temp = one
     525    346683697 :                   IF (j < idz) temp = -one
     526    520005361 :                   hdiag = hdiag + temp*zmat(k, j)**2
     527              :                END DO
     528    173321664 :                temp = ABS(beta*hdiag + vlag(k)**2)
     529    173321664 :                distsq = zero
     530    520005361 :                DO j = 1, n
     531    520005361 :                   distsq = distsq + (xpt(k, j) - xopt(j))**2
     532              :                END DO
     533    173321664 :                IF (distsq > rhosq) temp = temp*(distsq/rhosq)**3
     534    207984594 :                IF (temp > detrat .AND. k /= ktemp) THEN
     535     74634776 :                   detrat = temp
     536     74634776 :                   knew = k
     537              :                END IF
     538              :             END DO
     539     34662930 :             IF (knew == 0) EXIT preparation
     540              :             !
     541              :             !     Update BMAT, ZMAT and IDZ, so that the KNEW-th interpolation point
     542              :             !     can be moved. Begin the updating of the quadratic model, starting
     543              :             !     with the explicit second derivative term.
     544              :             !
     545              :          END IF
     546     53176237 :          CALL update(n, npt, bmat, zmat, idz, ndim, vlag, beta, knew, w)
     547     53176237 :          fval(knew) = f
     548     53176237 :          ih = 0
     549    159534510 :          DO i = 1, n
     550    106358273 :             temp = pq(knew)*xpt(knew, i)
     551    319087252 :             DO j = 1, i
     552    159552742 :                ih = ih + 1
     553    265911015 :                hq(ih) = hq(ih) + temp*xpt(knew, j)
     554              :             END DO
     555              :          END DO
     556     53176237 :          pq(knew) = zero
     557              :          !
     558              :          !     Update the other second derivative parameters, and then the gradie
     559              :          !     vector of the model. Also include the new interpolation point.
     560              :          !
     561    159534510 :          DO j = 1, nptm
     562    106358273 :             temp = diff*zmat(knew, j)
     563    106358273 :             IF (j < idz) temp = -temp
     564    691387205 :             DO k = 1, npt
     565    638210968 :                pq(k) = pq(k) + temp*zmat(k, j)
     566              :             END DO
     567              :          END DO
     568     53176237 :          gqsq = zero
     569    159534510 :          DO i = 1, n
     570    106358273 :             gq(i) = gq(i) + diff*bmat(knew, i)
     571    106358273 :             gqsq = gqsq + gq(i)**2
     572    159534510 :             xpt(knew, i) = xnew(i)
     573              :          END DO
     574              :          !
     575              :          !     If a trust region step makes a small change to the objective funct
     576              :          !     then calculate the gradient of the least Frobenius norm interpolan
     577              :          !     XBASE, and store it in W, using VLAG for a vector of right hand si
     578              :          !
     579     53176237 :          IF (ksave == 0 .AND. delta == rho) THEN
     580      6876833 :             IF (ABS(ratio) > 1.0e-2_dp) THEN
     581      4623844 :                itest = 0
     582              :             ELSE
     583     13517976 :                DO k = 1, npt
     584     13517976 :                   vlag(k) = fval(k) - fval(kopt)
     585              :                END DO
     586      2252989 :                gisq = zero
     587      6758988 :                DO i = 1, n
     588      4505999 :                   sum = zero
     589     27036208 :                   DO k = 1, npt
     590     27036208 :                      sum = sum + bmat(k, i)*vlag(k)
     591              :                   END DO
     592      4505999 :                   gisq = gisq + sum*sum
     593      6758988 :                   w(i) = sum
     594              :                END DO
     595              :                !
     596              :                !     Test whether to replace the new quadratic model by the least Frobe
     597              :                !     norm interpolant, making the replacement if the test is satisfied.
     598              :                !
     599      2252989 :                itest = itest + 1
     600      2252989 :                IF (gqsq < 1.0e2_dp*gisq) itest = 0
     601      2252989 :                IF (itest >= 3) THEN
     602       376974 :                   DO i = 1, n
     603       376974 :                      gq(i) = w(i)
     604              :                   END DO
     605       502632 :                   DO ih = 1, nh
     606       502632 :                      hq(ih) = zero
     607              :                   END DO
     608       376974 :                   DO j = 1, nptm
     609       251316 :                      w(j) = zero
     610      1507896 :                      DO k = 1, npt
     611      1507896 :                         w(j) = w(j) + vlag(k)*zmat(k, j)
     612              :                      END DO
     613       376974 :                      IF (j < idz) w(j) = -w(j)
     614              :                   END DO
     615       753948 :                   DO k = 1, npt
     616       628290 :                      pq(k) = zero
     617      2010528 :                      DO j = 1, nptm
     618      1884870 :                         pq(k) = pq(k) + zmat(k, j)*w(j)
     619              :                      END DO
     620              :                   END DO
     621       125658 :                   itest = 0
     622              :                END IF
     623              :             END IF
     624              :          END IF
     625     53176237 :          IF (f < fsave) kopt = knew
     626              :          !
     627              :          !     If a trust region step has provided a sufficient decrease in F, th
     628              :          !     branch for another trust region calculation. The case KSAVE>0 occu
     629              :          !     when the new function value was calculated by a model step.
     630              :          !
     631     53176237 :          IF (f <= fsave + tenth*vquad .OR. ksave > 0) THEN
     632              :             skip_check = .TRUE.
     633              :          ELSE
     634     12384149 :             knew = 0
     635              :          END IF
     636              :       END IF preparation
     637              :       !
     638              :       !     Alternatively, find out if the interpolation points are close enough
     639              :       !     to the best point so far.
     640              :       !
     641              :       outer: DO
     642     63960943 :          IF (.NOT. skip_check) THEN
     643     22404039 :             skip_check = .FALSE.
     644     22404039 :             distsq = 4.0_dp*delta*delta
     645    134429542 :             DO k = 1, npt
     646    112025503 :                sum = zero
     647    336107763 :                DO j = 1, n
     648    336107763 :                   sum = sum + (xpt(k, j) - xopt(j))**2
     649              :                END DO
     650    134429542 :                IF (sum > distsq) THEN
     651     30625552 :                   knew = k
     652     30625552 :                   distsq = sum
     653              :                END IF
     654              :             END DO
     655              :             !
     656              :             !     If KNEW is positive, then set DSTEP, and branch back for the next
     657              :             !     iteration, which will generate a "model step".
     658              :             !
     659     22404039 :             IF (knew > 0) THEN
     660     18966569 :                dstep = MAX(MIN(tenth*SQRT(distsq), half*delta), rho)
     661     18966569 :                dsq = dstep*dstep
     662     18966569 :                CALL generate_next_model_step
     663     18966569 :                RETURN
     664              :             END IF
     665      3437470 :             IF (ratio <= zero .AND. MAX(delta, dnorm) <= rho) THEN
     666              :                !
     667              :                !     The calculations with the current value of RHO are complete. Pick
     668              :                !     next values of RHO and DELTA.
     669              :                !
     670      2995176 :                CALL update_rho()
     671      2995176 :                IF (do_return) RETURN
     672              :             END IF
     673              :          END IF
     674              : 
     675     45823474 :          skip_check = .FALSE.
     676              :          inner: DO
     677     45823474 :             knew = 0
     678     45823474 :             CALL trsapp(n, npt, xopt, xpt, gq, hq, pq, delta, d, w, w(np), w(np + n), w(np + 2*n), crvmin)
     679     45823474 :             dsq = zero
     680    137474763 :             DO i = 1, n
     681    137474763 :                dsq = dsq + d(i)**2
     682              :             END DO
     683     45823474 :             dnorm = MIN(delta, SQRT(dsq))
     684     45823474 :             IF (dnorm < half*rho) THEN
     685     11160539 :                knew = -1
     686     11160539 :                delta = tenth*delta
     687     11160539 :                ratio = -1.0_dp
     688     11160539 :                IF (delta <= 1.5_dp*rho) delta = rho
     689     11160539 :                IF (nf <= nfsav + 2) CYCLE outer
     690      3091409 :                temp = 0.125_dp*crvmin*rho*rho
     691      3091409 :                IF (temp <= MAX(diffa, diffb, diffc)) CYCLE outer
     692      1593909 :                CALL update_rho()
     693      1593909 :                IF (do_return) RETURN
     694              :                CYCLE inner
     695              :             END IF
     696              :             EXIT inner
     697              :          END DO inner
     698      9566630 :          EXIT outer
     699              :       END DO outer
     700              :       !
     701              :       !     Shift XBASE if XOPT may be too far from XBASE. First make the chan
     702              :       !     to BMAT that do not depend on ZMAT.
     703     34662935 :       CALL generate_next_model_step
     704              : 
     705              :    CONTAINS
     706              : ! **************************************************************************************************
     707              : !> \brief ...
     708              : ! **************************************************************************************************
     709      4589085 :       SUBROUTINE update_rho()
     710      4589085 :          IF (rho > rhoend) THEN
     711      3824276 :             delta = half*rho
     712      3824276 :             ratio = rho/rhoend
     713      3824276 :             IF (ratio <= 16.0_dp) THEN
     714       764803 :                rho = rhoend
     715      3059473 :             ELSE IF (ratio <= 250.0_dp) THEN
     716       764803 :                rho = SQRT(ratio)*rhoend
     717              :             ELSE
     718      2294670 :                rho = tenth*rho
     719              :             END IF
     720      3824276 :             delta = MAX(delta, rho)
     721      3824276 :             nfsav = nf
     722              :          ELSE
     723              :             !
     724              :             !     Return from the calculation, after another Newton-Raphson step, if
     725              :             !     it is too short to have been tried before.
     726              :             !
     727       764809 :             IF (knew == -1) THEN
     728       638430 :                CALL calc_next_value_of_objective_func
     729              :             ELSE
     730       126379 :                opt%state = 7
     731       126379 :                CALL get_state
     732              : 
     733       126379 :                CALL finalize_optimization_after_failure
     734              :             END IF
     735       764809 :             do_return = .TRUE.
     736              :          END IF
     737      4589085 :       END SUBROUTINE update_rho
     738              : ! **************************************************************************************************
     739              : !> \brief ...
     740              : ! **************************************************************************************************
     741      3824301 :       SUBROUTINE begin_initialization_of_interpolation()
     742      3824301 :          nfm = nf
     743      3824301 :          nfmm = nf - n
     744      3824301 :          nf = nf + 1
     745      3824301 :          IF (nfm <= 2*n) THEN
     746      3824301 :             IF (nfm >= 1 .AND. nfm <= N) THEN
     747      1529775 :                xpt(nf, nfm) = rhobeg
     748      2294526 :             ELSE IF (nfm > n) THEN
     749      1529701 :                xpt(nf, nfmm) = -rhobeg
     750              :             END IF
     751              :          ELSE
     752            0 :             itemp = (nfmm - 1)/n
     753            0 :             jpt = nfm - itemp*n - n
     754            0 :             ipt = jpt + itemp
     755            0 :             IF (ipt > n) THEN
     756            0 :                itemp = jpt
     757            0 :                jpt = ipt - n
     758            0 :                ipt = itemp
     759              :             END IF
     760            0 :             xipt = rhobeg
     761            0 :             IF (fval(ipt + np) < fval(ipt + 1)) xipt = -xipt
     762            0 :             XJPT = RHOBEG
     763            0 :             IF (fval(jpt + np) < fval(jpt + 1)) xjpt = -xjpt
     764            0 :             xpt(nf, ipt) = xipt
     765            0 :             xpt(nf, jpt) = xjpt
     766              :          END IF
     767              :          !
     768              :          !     Calculate the next value of F, label 70 being reached immediately
     769              :          !     after this calculation. The least function value so far and its in
     770              :          !     are required.
     771              :          !
     772     11478579 :          DO j = 1, n
     773     11478579 :             x(j) = xpt(nf, j) + xbase(j)
     774              :          END DO
     775      3824301 :          CALL check_number_of_steps
     776      3824301 :       END SUBROUTINE begin_initialization_of_interpolation
     777              : ! **************************************************************************************************
     778              : !> \brief ...
     779              : ! **************************************************************************************************
     780     53629504 :       SUBROUTINE generate_next_model_step()
     781     53629504 :          IF (dsq <= 1.0e-3_dp*xoptsq) THEN
     782      3285953 :             tempq = 0.25_dp*xoptsq
     783     19716006 :             DO k = 1, npt
     784     16430053 :                sum = zero
     785     49291775 :                DO i = 1, n
     786     49291775 :                   sum = sum + xpt(k, i)*xopt(i)
     787              :                END DO
     788     16430053 :                temp = pq(k)*sum
     789     16430053 :                sum = sum - half*xoptsq
     790     16430053 :                w(npt + k) = sum
     791     52577728 :                DO i = 1, n
     792     32861722 :                   gq(i) = gq(i) + temp*xpt(k, i)
     793     32861722 :                   xpt(k, i) = xpt(k, i) - half*xopt(i)
     794     32861722 :                   vlag(i) = bmat(k, i)
     795     32861722 :                   w(i) = sum*xpt(k, i) + tempq*xopt(i)
     796     32861722 :                   ip = npt + i
     797     98588558 :                   DO j = 1, i
     798     82158505 :                      bmat(ip, j) = bmat(ip, j) + vlag(i)*w(j) + w(i)*vlag(j)
     799              :                   END DO
     800              :                END DO
     801              :             END DO
     802              :             !
     803              :             !     Then the revisions of BMAT that depend on ZMAT are calculated.
     804              :             !
     805      9858003 :             DO k = 1, nptm
     806      6572050 :                sumz = zero
     807     39433772 :                DO i = 1, npt
     808     32861722 :                   sumz = sumz + zmat(i, k)
     809     39433772 :                   w(i) = w(npt + i)*zmat(i, k)
     810              :                END DO
     811     19716886 :                DO j = 1, n
     812     13144836 :                   sum = tempq*sumz*xopt(j)
     813     78876680 :                   DO i = 1, npt
     814     65731844 :                      sum = sum + w(i)*xpt(i, j)
     815     65731844 :                      vlag(j) = sum
     816     78876680 :                      IF (k < idz) sum = -sum
     817              :                   END DO
     818     85448730 :                   DO i = 1, npt
     819     78876680 :                      bmat(i, j) = bmat(i, j) + sum*zmat(i, k)
     820              :                   END DO
     821              :                END DO
     822     23002839 :                DO i = 1, n
     823     13144836 :                   ip = i + npt
     824     13144836 :                   temp = vlag(i)
     825     13144836 :                   IF (k < idz) temp = -temp
     826     39436056 :                   DO j = 1, i
     827     32864006 :                      bmat(ip, j) = bmat(ip, j) + temp*vlag(j)
     828              :                   END DO
     829              :                END DO
     830              :             END DO
     831              :             !
     832              :             !     The following instructions complete the shift of XBASE, including
     833              :             !     the changes to the parameters of the quadratic model.
     834              :             !
     835      3285953 :             ih = 0
     836      9858003 :             DO j = 1, n
     837      6572050 :                w(j) = zero
     838     39433772 :                DO k = 1, npt
     839     32861722 :                   w(j) = w(j) + pq(k)*xpt(k, j)
     840     39433772 :                   xpt(k, j) = xpt(k, j) - half*xopt(j)
     841              :                END DO
     842     19716446 :                DO i = 1, j
     843      9858443 :                   ih = ih + 1
     844      9858443 :                   IF (i < j) gq(j) = gq(j) + hq(ih)*xopt(i)
     845      9858443 :                   gq(i) = gq(i) + hq(ih)*xopt(j)
     846      9858443 :                   hq(ih) = hq(ih) + w(i)*xopt(j) + xopt(i)*w(j)
     847     16430493 :                   bmat(npt + i, j) = bmat(npt + j, i)
     848              :                END DO
     849              :             END DO
     850      9858003 :             DO j = 1, n
     851      6572050 :                xbase(j) = xbase(j) + xopt(j)
     852      9858003 :                xopt(j) = zero
     853              :             END DO
     854      3285953 :             xoptsq = zero
     855              :          END IF
     856              :          !
     857              :          !     Pick the model step if KNEW is positive. A different choice of D
     858              :          !     may be made later, if the choice of D by BIGLAG causes substantial
     859              :          !     cancellation in DENOM.
     860              :          !
     861     53629504 :          IF (knew > 0) THEN
     862              :             CALL biglag(n, npt, xopt, xpt, bmat, zmat, idz, ndim, knew, dstep, &
     863     18966569 :                         d, alpha, vlag, vlag(npt + 1), w, w(np), w(np + n))
     864              :          END IF
     865              :          !
     866              :          !     Calculate VLAG and BETA for the current choice of D. The first NPT
     867              :          !     components of W_check will be held in W.
     868              :          !
     869    321788740 :          DO k = 1, npt
     870    268159236 :             suma = zero
     871    268159236 :             sumb = zero
     872    268159236 :             sum = zero
     873    804545554 :             DO j = 1, n
     874    536386318 :                suma = suma + xpt(k, j)*d(j)
     875    536386318 :                sumb = sumb + xpt(k, j)*xopt(j)
     876    804545554 :                sum = sum + bmat(k, j)*d(j)
     877              :             END DO
     878    268159236 :             w(k) = suma*(half*suma + sumb)
     879    321788740 :             vlag(k) = sum
     880              :          END DO
     881     53629504 :          beta = zero
     882    160894370 :          DO k = 1, nptm
     883    107264866 :             sum = zero
     884    643651184 :             DO i = 1, npt
     885    643651184 :                sum = sum + zmat(i, k)*w(i)
     886              :             END DO
     887    107264866 :             IF (k < idz) THEN
     888            0 :                beta = beta + sum*sum
     889            0 :                sum = -sum
     890              :             ELSE
     891    107264866 :                beta = beta - sum*sum
     892              :             END IF
     893    697280688 :             DO i = 1, npt
     894    643651184 :                vlag(i) = vlag(i) + sum*zmat(i, k)
     895              :             END DO
     896              :          END DO
     897     53629504 :          bsum = zero
     898     53629504 :          dx = zero
     899    160894370 :          DO j = 1, n
     900    107264866 :             sum = zero
     901    643651184 :             DO i = 1, npt
     902    643651184 :                sum = sum + w(i)*bmat(i, j)
     903              :             END DO
     904    107264866 :             bsum = bsum + sum*d(j)
     905    107264866 :             jp = npt + j
     906    321825592 :             DO k = 1, n
     907    321825592 :                sum = sum + bmat(jp, k)*d(k)
     908              :             END DO
     909    107264866 :             vlag(jp) = sum
     910    107264866 :             bsum = bsum + sum*d(j)
     911    160894370 :             dx = dx + d(j)*xopt(j)
     912              :          END DO
     913     53629504 :          beta = dx*dx + dsq*(xoptsq + dx + dx + half*dsq) + beta - bsum
     914     53629504 :          vlag(kopt) = vlag(kopt) + one
     915              :          !
     916              :          !     If KNEW is positive and if the cancellation in DENOM is unacceptab
     917              :          !     then BIGDEN calculates an alternative model step, XNEW being used
     918              :          !     working space.
     919              :          !
     920     53629504 :          IF (knew > 0) THEN
     921     18966569 :             temp = one + alpha*beta/vlag(knew)**2
     922     18966569 :             IF (ABS(temp) <= 0.8_dp) THEN
     923              :                CALL bigden(n, npt, xopt, xpt, bmat, zmat, idz, ndim, kopt, &
     924          110 :                            knew, d, w, vlag, beta, xnew, w(ndim + 1), w(6*ndim + 1))
     925              :             END IF
     926              :          END IF
     927              :          !
     928              :          !     Calculate the next value of the objective function.
     929              :          !
     930     53629504 :          CALL calc_next_value_of_objective_func
     931     53629504 :       END SUBROUTINE generate_next_model_step
     932              : ! **************************************************************************************************
     933              : !> \brief ...
     934              : ! **************************************************************************************************
     935     54267934 :       SUBROUTINE calc_next_value_of_objective_func()
     936    162809698 :          DO i = 1, n
     937    108541764 :             xnew(i) = xopt(i) + d(i)
     938    162809698 :             x(i) = xbase(i) + xnew(i)
     939              :          END DO
     940     54267934 :          nf = nf + 1
     941     54267934 :          CALL check_number_of_steps
     942     54267934 :       END SUBROUTINE calc_next_value_of_objective_func
     943              : ! **************************************************************************************************
     944              : !> \brief ...
     945              : ! **************************************************************************************************
     946     58092235 :       SUBROUTINE check_number_of_steps()
     947     58092235 :          IF (nf > nftest) THEN
     948              :             !         return to many steps
     949           11 :             nf = nf - 1
     950           11 :             opt%state = 3
     951           11 :             CALL get_state
     952           11 :             CALL finalize_optimization_after_failure
     953              :          ELSE
     954              : 
     955     58092224 :             CALL get_state
     956              : 
     957     58092224 :             opt%state = 2
     958              :          END IF
     959     58092235 :       END SUBROUTINE check_number_of_steps
     960              : ! **************************************************************************************************
     961              : !> \brief ...
     962              : ! **************************************************************************************************
     963       764824 :       SUBROUTINE finalize_optimization_after_failure()
     964       764824 :          IF (fopt <= f) THEN
     965       714084 :             DO i = 1, n
     966       714084 :                x(i) = xbase(i) + xopt(i)
     967              :             END DO
     968       237921 :             f = fopt
     969              :          END IF
     970              : 
     971       764824 :          CALL get_state
     972       764824 :       END SUBROUTINE finalize_optimization_after_failure
     973              : ! **************************************************************************************************
     974              : !> \brief ...
     975              : ! **************************************************************************************************
     976     59621872 :       SUBROUTINE get_state()
     977     59621872 :          opt%np = np
     978     59621872 :          opt%nh = nh
     979     59621872 :          opt%nptm = nptm
     980     59621872 :          opt%nftest = nftest
     981     59621872 :          opt%idz = idz
     982     59621872 :          opt%itest = itest
     983     59621872 :          opt%nf = nf
     984     59621872 :          opt%nfm = nfm
     985     59621872 :          opt%nfmm = nfmm
     986     59621872 :          opt%nfsav = nfsav
     987     59621872 :          opt%knew = knew
     988     59621872 :          opt%kopt = kopt
     989     59621872 :          opt%ksave = ksave
     990     59621872 :          opt%ktemp = ktemp
     991     59621872 :          opt%rhosq = rhosq
     992     59621872 :          opt%recip = recip
     993     59621872 :          opt%reciq = reciq
     994     59621872 :          opt%fbeg = fbeg
     995     59621872 :          opt%fopt = fopt
     996     59621872 :          opt%diffa = diffa
     997     59621872 :          opt%xoptsq = xoptsq
     998     59621872 :          opt%rho = rho
     999     59621872 :          opt%delta = delta
    1000     59621872 :          opt%dsq = dsq
    1001     59621872 :          opt%dnorm = dnorm
    1002     59621872 :          opt%ratio = ratio
    1003     59621872 :          opt%temp = temp
    1004     59621872 :          opt%tempq = tempq
    1005     59621872 :          opt%beta = beta
    1006     59621872 :          opt%dx = dx
    1007     59621872 :          opt%vquad = vquad
    1008     59621872 :          opt%diff = diff
    1009     59621872 :          opt%diffc = diffc
    1010     59621872 :          opt%diffb = diffb
    1011     59621872 :          opt%fsave = fsave
    1012     59621872 :          opt%detrat = detrat
    1013     59621872 :          opt%hdiag = hdiag
    1014     59621872 :          opt%distsq = distsq
    1015     59621872 :          opt%gisq = gisq
    1016     59621872 :          opt%gqsq = gqsq
    1017     59621872 :          opt%f = f
    1018     59621872 :          opt%bstep = bstep
    1019     59621872 :          opt%alpha = alpha
    1020     59621872 :          opt%dstep = dstep
    1021     59621872 :       END SUBROUTINE get_state
    1022              : ! **************************************************************************************************
    1023              : !> \brief ...
    1024              : ! **************************************************************************************************
    1025     58092223 :       SUBROUTINE set_state()
    1026     58092223 :          np = opt%np
    1027     58092223 :          nh = opt%nh
    1028     58092223 :          nptm = opt%nptm
    1029     58092223 :          nftest = opt%nftest
    1030     58092223 :          idz = opt%idz
    1031     58092223 :          itest = opt%itest
    1032     58092223 :          nf = opt%nf
    1033     58092223 :          nfm = opt%nfm
    1034     58092223 :          nfmm = opt%nfmm
    1035     58092223 :          nfsav = opt%nfsav
    1036     58092223 :          knew = opt%knew
    1037     58092223 :          kopt = opt%kopt
    1038     58092223 :          ksave = opt%ksave
    1039     58092223 :          ktemp = opt%ktemp
    1040     58092223 :          rhosq = opt%rhosq
    1041     58092223 :          recip = opt%recip
    1042     58092223 :          reciq = opt%reciq
    1043     58092223 :          fbeg = opt%fbeg
    1044     58092223 :          fopt = opt%fopt
    1045     58092223 :          diffa = opt%diffa
    1046     58092223 :          xoptsq = opt%xoptsq
    1047     58092223 :          rho = opt%rho
    1048     58092223 :          delta = opt%delta
    1049     58092223 :          dsq = opt%dsq
    1050     58092223 :          dnorm = opt%dnorm
    1051     58092223 :          ratio = opt%ratio
    1052     58092223 :          temp = opt%temp
    1053     58092223 :          tempq = opt%tempq
    1054     58092223 :          beta = opt%beta
    1055     58092223 :          dx = opt%dx
    1056     58092223 :          vquad = opt%vquad
    1057     58092223 :          diff = opt%diff
    1058     58092223 :          diffc = opt%diffc
    1059     58092223 :          diffb = opt%diffb
    1060     58092223 :          fsave = opt%fsave
    1061     58092223 :          detrat = opt%detrat
    1062     58092223 :          hdiag = opt%hdiag
    1063     58092223 :          distsq = opt%distsq
    1064     58092223 :          gisq = opt%gisq
    1065     58092223 :          gqsq = opt%gqsq
    1066     58092223 :          f = opt%f
    1067     58092223 :          bstep = opt%bstep
    1068     58092223 :          alpha = opt%alpha
    1069     58092223 :          dstep = opt%dstep
    1070     58092223 :       END SUBROUTINE set_state
    1071              : 
    1072              :    END SUBROUTINE newuob
    1073              : 
    1074              : ! **************************************************************************************************
    1075              : !> \brief ...
    1076              : !> \param n ...
    1077              : !> \param npt ...
    1078              : !> \param xopt ...
    1079              : !> \param xpt ...
    1080              : !> \param bmat ...
    1081              : !> \param zmat ...
    1082              : !> \param idz ...
    1083              : !> \param ndim ...
    1084              : !> \param kopt ...
    1085              : !> \param knew ...
    1086              : !> \param d ...
    1087              : !> \param w ...
    1088              : !> \param vlag ...
    1089              : !> \param beta ...
    1090              : !> \param s ...
    1091              : !> \param wvec ...
    1092              : !> \param prod ...
    1093              : ! **************************************************************************************************
    1094          110 :    SUBROUTINE bigden(n, npt, xopt, xpt, bmat, zmat, idz, ndim, kopt, &
    1095          110 :                      knew, d, w, vlag, beta, s, wvec, prod)
    1096              : 
    1097              :       INTEGER, INTENT(in)                             :: n, npt
    1098              :       REAL(dp), DIMENSION(*), INTENT(in)              :: xopt
    1099              :       REAL(dp), DIMENSION(npt, *), INTENT(in)         :: xpt
    1100              :       INTEGER, INTENT(in)                             :: ndim, idz
    1101              :       REAL(dp), DIMENSION(npt, *), INTENT(inout)         :: zmat
    1102              :       REAL(dp), DIMENSION(ndim, *), INTENT(inout)        :: bmat
    1103              :       INTEGER, INTENT(inout)                             :: kopt, knew
    1104              :       REAL(dp), DIMENSION(*), INTENT(inout)              :: d, w, vlag
    1105              :       REAL(dp), INTENT(inout)                            :: beta
    1106              :       REAL(dp), DIMENSION(*), INTENT(inout)              :: s
    1107              :       REAL(dp), DIMENSION(ndim, *), INTENT(inout)        :: wvec, prod
    1108              : 
    1109              :       REAL(dp), PARAMETER                                :: half = 0.5_dp, one = 1._dp, &
    1110              :                                                             quart = 0.25_dp, two = 2._dp, &
    1111              :                                                             zero = 0._dp
    1112              : 
    1113              :       INTEGER                                            :: i, ip, isave, iterc, iu, j, jc, k, ksav, &
    1114              :                                                             nptm, nw
    1115              :       REAL(dp) :: alpha, angle, dd, denmax, denold, densav, diff, ds, dstemp, dtest, ss, ssden, &
    1116              :                   sstemp, step, sum, sumold, tau, temp, tempa, tempb, tempc, xoptd, xopts, xoptsq
    1117              :       REAL(dp), DIMENSION(9)                             :: den, denex, par
    1118              : 
    1119              : !
    1120              : !     N is the number of variables.
    1121              : !     NPT is the number of interpolation equations.
    1122              : !     XOPT is the best interpolation point so far.
    1123              : !     XPT contains the coordinates of the current interpolation points.
    1124              : !     BMAT provides the last N columns of H.
    1125              : !     ZMAT and IDZ give a factorization of the first NPT by NPT submatri
    1126              : !     NDIM is the first dimension of BMAT and has the value NPT+N.
    1127              : !     KOPT is the index of the optimal interpolation point.
    1128              : !     KNEW is the index of the interpolation point that is going to be m
    1129              : !     D will be set to the step from XOPT to the new point, and on entry
    1130              : !       should be the D that was calculated by the last call of BIGLAG.
    1131              : !       length of the initial D provides a trust region bound on the fin
    1132              : !     W will be set to Wcheck for the final choice of D.
    1133              : !     VLAG will be set to Theta*Wcheck+e_b for the final choice of D.
    1134              : !     BETA will be set to the value that will occur in the updating form
    1135              : !       when the KNEW-th interpolation point is moved to its new positio
    1136              : !     S, WVEC, PROD and the private arrays DEN, DENEX and PAR will be us
    1137              : !       for working space.
    1138              : !
    1139              : !     D is calculated in a way that should provide a denominator with a
    1140              : !     modulus in the updating formula when the KNEW-th interpolation poi
    1141              : !     shifted to the new position XOPT+D.
    1142              : !
    1143              : 
    1144          110 :       nptm = npt - n - 1
    1145              :       !
    1146              :       !     Store the first NPT elements of the KNEW-th column of H in W(N+1)
    1147              :       !     to W(N+NPT).
    1148              :       !
    1149          660 :       DO k = 1, npt
    1150          660 :          w(n + k) = zero
    1151              :       END DO
    1152          330 :       DO j = 1, nptm
    1153          220 :          temp = zmat(knew, j)
    1154          220 :          IF (j < idz) temp = -temp
    1155         1430 :          DO k = 1, npt
    1156         1320 :             w(n + k) = w(n + k) + temp*zmat(k, j)
    1157              :          END DO
    1158              :       END DO
    1159          110 :       alpha = w(n + knew)
    1160              :       !
    1161              :       !     The initial search direction D is taken from the last call of BIGL
    1162              :       !     and the initial S is set below, usually to the direction from X_OP
    1163              :       !     to X_KNEW, but a different direction to an interpolation point may
    1164              :       !     be chosen, in order to prevent S from being nearly parallel to D.
    1165              :       !
    1166          110 :       dd = zero
    1167          110 :       ds = zero
    1168          110 :       ss = zero
    1169          110 :       xoptsq = zero
    1170          330 :       DO i = 1, n
    1171          220 :          dd = dd + d(i)**2
    1172          220 :          s(i) = xpt(knew, i) - xopt(i)
    1173          220 :          ds = ds + d(i)*s(i)
    1174          220 :          ss = ss + s(i)**2
    1175          330 :          xoptsq = xoptsq + xopt(i)**2
    1176              :       END DO
    1177          110 :       IF (ds*ds > 0.99_dp*dd*ss) THEN
    1178            0 :          ksav = knew
    1179            0 :          dtest = ds*ds/ss
    1180            0 :          DO k = 1, npt
    1181            0 :             IF (k /= kopt) THEN
    1182              :                dstemp = zero
    1183              :                sstemp = zero
    1184            0 :                DO i = 1, n
    1185            0 :                   diff = xpt(k, i) - xopt(i)
    1186            0 :                   dstemp = dstemp + d(i)*diff
    1187            0 :                   sstemp = sstemp + diff*diff
    1188              :                END DO
    1189            0 :                IF (dstemp*dstemp/sstemp < dtest) THEN
    1190            0 :                   ksav = k
    1191            0 :                   dtest = dstemp*dstemp/sstemp
    1192            0 :                   ds = dstemp
    1193            0 :                   ss = sstemp
    1194              :                END IF
    1195              :             END IF
    1196              :          END DO
    1197            0 :          DO i = 1, n
    1198            0 :             s(i) = xpt(ksav, i) - xopt(i)
    1199              :          END DO
    1200              :       END IF
    1201          110 :       ssden = dd*ss - ds*ds
    1202          110 :       iterc = 0
    1203          110 :       densav = zero
    1204              :       !
    1205              :       !     Begin the iteration by overwriting S with a vector that has the
    1206              :       !     required length and direction.
    1207              :       !
    1208              :       mainloop: DO
    1209          176 :          iterc = iterc + 1
    1210          176 :          temp = one/SQRT(ssden)
    1211          176 :          xoptd = zero
    1212          176 :          xopts = zero
    1213          528 :          DO i = 1, n
    1214          352 :             s(i) = temp*(dd*s(i) - ds*d(i))
    1215          352 :             xoptd = xoptd + xopt(i)*d(i)
    1216          528 :             xopts = xopts + xopt(i)*s(i)
    1217              :          END DO
    1218              :          !
    1219              :          !     Set the coefficients of the first two terms of BETA.
    1220              :          !
    1221          176 :          tempa = half*xoptd*xoptd
    1222          176 :          tempb = half*xopts*xopts
    1223          176 :          den(1) = dd*(xoptsq + half*dd) + tempa + tempb
    1224          176 :          den(2) = two*xoptd*dd
    1225          176 :          den(3) = two*xopts*dd
    1226          176 :          den(4) = tempa - tempb
    1227          176 :          den(5) = xoptd*xopts
    1228          880 :          DO i = 6, 9
    1229          880 :             den(i) = zero
    1230              :          END DO
    1231              :          !
    1232              :          !     Put the coefficients of Wcheck in WVEC.
    1233              :          !
    1234         1056 :          DO k = 1, npt
    1235              :             tempa = zero
    1236              :             tempb = zero
    1237              :             tempc = zero
    1238         2640 :             DO i = 1, n
    1239         1760 :                tempa = tempa + xpt(k, i)*d(i)
    1240         1760 :                tempb = tempb + xpt(k, i)*s(i)
    1241         2640 :                tempc = tempc + xpt(k, i)*xopt(i)
    1242              :             END DO
    1243          880 :             wvec(k, 1) = quart*(tempa*tempa + tempb*tempb)
    1244          880 :             wvec(k, 2) = tempa*tempc
    1245          880 :             wvec(k, 3) = tempb*tempc
    1246          880 :             wvec(k, 4) = quart*(tempa*tempa - tempb*tempb)
    1247         1056 :             wvec(k, 5) = half*tempa*tempb
    1248              :          END DO
    1249          528 :          DO i = 1, n
    1250          352 :             ip = i + npt
    1251          352 :             wvec(ip, 1) = zero
    1252          352 :             wvec(ip, 2) = d(i)
    1253          352 :             wvec(ip, 3) = s(i)
    1254          352 :             wvec(ip, 4) = zero
    1255          528 :             wvec(ip, 5) = zero
    1256              :          END DO
    1257              :          !
    1258              :          !     Put the coefficients of THETA*Wcheck in PROD.
    1259              :          !
    1260         1056 :          DO jc = 1, 5
    1261          880 :             nw = npt
    1262          880 :             IF (jc == 2 .OR. jc == 3) nw = ndim
    1263         5280 :             DO k = 1, npt
    1264         5280 :                prod(k, jc) = zero
    1265              :             END DO
    1266         2640 :             DO j = 1, nptm
    1267              :                sum = zero
    1268        10560 :                DO k = 1, npt
    1269        10560 :                   sum = sum + zmat(k, j)*wvec(k, jc)
    1270              :                END DO
    1271         1760 :                IF (j < idz) sum = -sum
    1272        11440 :                DO k = 1, npt
    1273        10560 :                   prod(k, jc) = prod(k, jc) + sum*zmat(k, j)
    1274              :                END DO
    1275              :             END DO
    1276          880 :             IF (nw == ndim) THEN
    1277         2112 :                DO k = 1, npt
    1278              :                   sum = zero
    1279         5280 :                   DO j = 1, n
    1280         5280 :                      sum = sum + bmat(k, j)*wvec(npt + j, jc)
    1281              :                   END DO
    1282         2112 :                   prod(k, jc) = prod(k, jc) + sum
    1283              :                END DO
    1284              :             END IF
    1285         2816 :             DO j = 1, n
    1286              :                sum = zero
    1287        11968 :                DO i = 1, nw
    1288        11968 :                   sum = sum + bmat(i, j)*wvec(i, jc)
    1289              :                END DO
    1290         2640 :                prod(npt + j, jc) = sum
    1291              :             END DO
    1292              :          END DO
    1293              :          !
    1294              :          !     Include in DEN the part of BETA that depends on THETA.
    1295              :          !
    1296         1408 :          DO k = 1, ndim
    1297              :             sum = zero
    1298         7392 :             DO I = 1, 5
    1299         6160 :                par(i) = half*prod(k, i)*wvec(k, i)
    1300         7392 :                sum = sum + par(i)
    1301              :             END DO
    1302         1232 :             den(1) = den(1) - par(1) - sum
    1303         1232 :             tempa = prod(k, 1)*wvec(k, 2) + prod(k, 2)*wvec(k, 1)
    1304         1232 :             tempb = prod(k, 2)*wvec(k, 4) + prod(k, 4)*wvec(k, 2)
    1305         1232 :             tempc = prod(k, 3)*wvec(k, 5) + prod(k, 5)*wvec(k, 3)
    1306         1232 :             den(2) = den(2) - tempa - half*(tempb + tempc)
    1307         1232 :             den(6) = den(6) - half*(tempb - tempc)
    1308         1232 :             tempa = prod(k, 1)*wvec(k, 3) + prod(k, 3)*wvec(k, 1)
    1309         1232 :             tempb = prod(k, 2)*wvec(k, 5) + prod(k, 5)*wvec(k, 2)
    1310         1232 :             tempc = prod(k, 3)*wvec(k, 4) + prod(k, 4)*wvec(k, 3)
    1311         1232 :             den(3) = den(3) - tempa - half*(tempb - tempc)
    1312         1232 :             den(7) = den(7) - half*(tempb + tempc)
    1313         1232 :             tempa = prod(k, 1)*wvec(k, 4) + prod(k, 4)*wvec(k, 1)
    1314         1232 :             den(4) = den(4) - tempa - par(2) + par(3)
    1315         1232 :             tempa = prod(k, 1)*wvec(k, 5) + prod(k, 5)*wvec(k, 1)
    1316         1232 :             tempb = prod(k, 2)*wvec(k, 3) + prod(k, 3)*wvec(k, 2)
    1317         1232 :             den(5) = den(5) - tempa - half*tempb
    1318         1232 :             den(8) = den(8) - par(4) + par(5)
    1319         1232 :             tempa = prod(k, 4)*wvec(k, 5) + prod(k, 5)*wvec(k, 4)
    1320         1408 :             den(9) = den(9) - half*tempa
    1321              :          END DO
    1322              :          !
    1323              :          !     Extend DEN so that it holds all the coefficients of DENOM.
    1324              :          !
    1325              :          sum = zero
    1326         1056 :          DO i = 1, 5
    1327          880 :             par(i) = half*prod(knew, i)**2
    1328         1056 :             sum = sum + par(i)
    1329              :          END DO
    1330          176 :          denex(1) = alpha*den(1) + par(1) + sum
    1331          176 :          tempa = two*prod(knew, 1)*prod(knew, 2)
    1332          176 :          tempb = prod(knew, 2)*prod(knew, 4)
    1333          176 :          tempc = prod(knew, 3)*prod(knew, 5)
    1334          176 :          denex(2) = alpha*den(2) + tempa + tempb + tempc
    1335          176 :          denex(6) = alpha*den(6) + tempb - tempc
    1336          176 :          tempa = two*prod(knew, 1)*prod(knew, 3)
    1337          176 :          tempb = prod(knew, 2)*prod(knew, 5)
    1338          176 :          tempc = prod(knew, 3)*prod(knew, 4)
    1339          176 :          denex(3) = alpha*den(3) + tempa + tempb - tempc
    1340          176 :          denex(7) = alpha*den(7) + tempb + tempc
    1341          176 :          tempa = two*prod(knew, 1)*prod(knew, 4)
    1342          176 :          denex(4) = alpha*den(4) + tempa + par(2) - par(3)
    1343          176 :          tempa = two*prod(knew, 1)*prod(knew, 5)
    1344          176 :          denex(5) = alpha*den(5) + tempa + prod(knew, 2)*prod(knew, 3)
    1345          176 :          denex(8) = alpha*den(8) + par(4) - par(5)
    1346          176 :          denex(9) = alpha*den(9) + prod(knew, 4)*prod(knew, 5)
    1347              :          !
    1348              :          !     Seek the value of the angle that maximizes the modulus of DENOM.
    1349              :          !
    1350          176 :          sum = denex(1) + denex(2) + denex(4) + denex(6) + denex(8)
    1351          176 :          denold = sum
    1352          176 :          denmax = sum
    1353          176 :          isave = 0
    1354          176 :          iu = 49
    1355          176 :          temp = twopi/REAL(IU + 1, dp)
    1356          176 :          par(1) = one
    1357         8800 :          DO i = 1, iu
    1358         8624 :             angle = REAL(i, dp)*temp
    1359         8624 :             par(2) = COS(angle)
    1360         8624 :             par(3) = SIN(angle)
    1361         8624 :             DO j = 4, 8, 2
    1362        25872 :                par(j) = par(2)*par(j - 2) - par(3)*par(j - 1)
    1363        25872 :                par(j + 1) = par(2)*par(j - 1) + par(3)*par(j - 2)
    1364              :             END DO
    1365              :             sumold = sum
    1366              :             sum = zero
    1367        86240 :             DO j = 1, 9
    1368        86240 :                sum = sum + denex(j)*par(j)
    1369              :             END DO
    1370         8800 :             IF (ABS(sum) > ABS(denmax)) THEN
    1371              :                denmax = sum
    1372              :                isave = i
    1373              :                tempa = sumold
    1374         8020 :             ELSE IF (i == isave + 1) THEN
    1375          326 :                tempb = sum
    1376              :             END IF
    1377              :          END DO
    1378          176 :          IF (isave == 0) tempa = sum
    1379           86 :          IF (isave == iu) tempb = denold
    1380          176 :          step = zero
    1381          176 :          IF (tempa /= tempb) THEN
    1382          176 :             tempa = tempa - denmax
    1383          176 :             tempb = tempb - denmax
    1384          176 :             step = half*(tempa - tempb)/(tempa + tempb)
    1385              :          END IF
    1386          176 :          angle = temp*(REAL(isave, dp) + step)
    1387              :          !
    1388              :          !     Calculate the new parameters of the denominator, the new VLAG vect
    1389              :          !     and the new D. Then test for convergence.
    1390              :          !
    1391          176 :          par(2) = COS(angle)
    1392          176 :          par(3) = SIN(angle)
    1393          176 :          DO j = 4, 8, 2
    1394          528 :             par(j) = par(2)*par(j - 2) - par(3)*par(j - 1)
    1395          528 :             par(j + 1) = par(2)*par(j - 1) + par(3)*par(j - 2)
    1396              :          END DO
    1397          176 :          beta = zero
    1398          176 :          denmax = zero
    1399         1760 :          DO j = 1, 9
    1400         1584 :             beta = beta + den(j)*par(j)
    1401         1760 :             denmax = denmax + denex(j)*par(j)
    1402              :          END DO
    1403         1408 :          DO k = 1, ndim
    1404         1232 :             vlag(k) = zero
    1405         7568 :             DO j = 1, 5
    1406         7392 :                vlag(k) = vlag(k) + prod(k, j)*par(j)
    1407              :             END DO
    1408              :          END DO
    1409          176 :          tau = vlag(knew)
    1410          176 :          dd = zero
    1411          176 :          tempa = zero
    1412          176 :          tempb = zero
    1413          528 :          DO i = 1, n
    1414          352 :             d(i) = par(2)*d(i) + par(3)*s(i)
    1415          352 :             w(i) = xopt(i) + d(i)
    1416          352 :             dd = dd + d(i)**2
    1417          352 :             tempa = tempa + d(i)*w(i)
    1418          528 :             tempb = tempb + w(i)*w(i)
    1419              :          END DO
    1420          176 :          IF (iterc >= n) EXIT mainloop
    1421          110 :          IF (iterc >= 1) densav = MAX(densav, denold)
    1422          110 :          IF (ABS(denmax) <= 1.1_dp*ABS(densav)) EXIT mainloop
    1423          198 :          densav = denmax
    1424              :          !
    1425              :          !     Set S to half the gradient of the denominator with respect to D.
    1426              :          !     Then branch for the next iteration.
    1427              :          !
    1428          198 :          DO i = 1, n
    1429          132 :             temp = tempa*xopt(i) + tempb*d(i) - vlag(npt + i)
    1430          198 :             s(i) = tau*bmat(knew, i) + alpha*temp
    1431              :          END DO
    1432          396 :          DO k = 1, npt
    1433              :             sum = zero
    1434          990 :             DO j = 1, n
    1435          990 :                sum = sum + xpt(k, j)*w(j)
    1436              :             END DO
    1437          330 :             temp = (tau*w(n + k) - alpha*vlag(k))*sum
    1438         1056 :             DO i = 1, n
    1439          990 :                s(i) = s(i) + temp*xpt(k, i)
    1440              :             END DO
    1441              :          END DO
    1442              :          ss = zero
    1443              :          ds = zero
    1444          198 :          DO i = 1, n
    1445          132 :             ss = ss + s(i)**2
    1446          198 :             ds = ds + d(i)*s(i)
    1447              :          END DO
    1448           66 :          ssden = dd*ss - ds*ds
    1449          176 :          IF (ssden < 1.0e-8_dp*dd*ss) EXIT mainloop
    1450              :       END DO mainloop
    1451              :       !
    1452              :       !     Set the vector W before the RETURN from the subroutine.
    1453              :       !
    1454          880 :       DO k = 1, ndim
    1455          770 :          w(k) = zero
    1456         4730 :          DO j = 1, 5
    1457         4620 :             w(k) = w(k) + wvec(k, j)*par(j)
    1458              :          END DO
    1459              :       END DO
    1460          110 :       vlag(kopt) = vlag(kopt) + one
    1461              : 
    1462          110 :    END SUBROUTINE bigden
    1463              : 
    1464              : ! **************************************************************************************************
    1465              : !> \brief ...
    1466              : !> \param n ...
    1467              : !> \param npt ...
    1468              : !> \param xopt ...
    1469              : !> \param xpt ...
    1470              : !> \param bmat ...
    1471              : !> \param zmat ...
    1472              : !> \param idz ...
    1473              : !> \param ndim ...
    1474              : !> \param knew ...
    1475              : !> \param delta ...
    1476              : !> \param d ...
    1477              : !> \param alpha ...
    1478              : !> \param hcol ...
    1479              : !> \param gc ...
    1480              : !> \param gd ...
    1481              : !> \param s ...
    1482              : !> \param w ...
    1483              : ! **************************************************************************************************
    1484     18966569 :    SUBROUTINE biglag(n, npt, xopt, xpt, bmat, zmat, idz, ndim, knew, &
    1485              :                      delta, d, alpha, hcol, gc, gd, s, w)
    1486              :       INTEGER, INTENT(in)                                :: n, npt
    1487              :       REAL(dp), DIMENSION(*), INTENT(in)                 :: xopt
    1488              :       REAL(dp), DIMENSION(npt, *), INTENT(in)            :: xpt
    1489              :       INTEGER, INTENT(in)                                :: ndim, idz
    1490              :       REAL(dp), DIMENSION(npt, *), INTENT(inout)         :: zmat
    1491              :       REAL(dp), DIMENSION(ndim, *), INTENT(inout)        :: bmat
    1492              :       INTEGER, INTENT(inout)                             :: knew
    1493              :       REAL(dp), INTENT(inout)                            :: delta
    1494              :       REAL(dp), DIMENSION(*), INTENT(inout)              :: d
    1495              :       REAL(dp), INTENT(inout)                            :: alpha
    1496              :       REAL(dp), DIMENSION(*), INTENT(inout)              :: hcol, gc, gd, s, w
    1497              : 
    1498              :       REAL(dp), PARAMETER                                :: half = 0.5_dp, one = 1._dp, zero = 0._dp
    1499              : 
    1500              :       INTEGER                                            :: i, isave, iterc, iu, j, k, nptm
    1501              :       REAL(dp)                                           :: angle, cf1, cf2, cf3, cf4, cf5, cth, dd, &
    1502              :                                                             delsq, denom, dhd, gg, scale, sp, ss, &
    1503              :                                                             step, sth, sum, tau, taubeg, taumax, &
    1504              :                                                             tauold, temp, tempa, tempb
    1505              : 
    1506              : !
    1507              : !
    1508              : !     N is the number of variables.
    1509              : !     NPT is the number of interpolation equations.
    1510              : !     XOPT is the best interpolation point so far.
    1511              : !     XPT contains the coordinates of the current interpolation points.
    1512              : !     BMAT provides the last N columns of H.
    1513              : !     ZMAT and IDZ give a factorization of the first NPT by NPT submatrix
    1514              : !     NDIM is the first dimension of BMAT and has the value NPT+N.
    1515              : !     KNEW is the index of the interpolation point that is going to be m
    1516              : !     DELTA is the current trust region bound.
    1517              : !     D will be set to the step from XOPT to the new point.
    1518              : !     ALPHA will be set to the KNEW-th diagonal element of the H matrix.
    1519              : !     HCOL, GC, GD, S and W will be used for working space.
    1520              : !
    1521              : !     The step D is calculated in a way that attempts to maximize the mo
    1522              : !     of LFUNC(XOPT+D), subject to the bound ||D|| <= DELTA, where LFU
    1523              : !     the KNEW-th Lagrange function.
    1524              : !
    1525              : 
    1526     18966569 :       delsq = delta*delta
    1527     18966569 :       nptm = npt - n - 1
    1528              :       !
    1529              :       !     Set the first NPT components of HCOL to the leading elements of th
    1530              :       !     KNEW-th column of H.
    1531              :       !
    1532     18966569 :       iterc = 0
    1533    113804106 :       DO k = 1, npt
    1534    113804106 :          hcol(k) = zero
    1535              :       END DO
    1536     56902053 :       DO j = 1, nptm
    1537     37935484 :          temp = zmat(knew, j)
    1538     37935484 :          IF (j < idz) temp = -temp
    1539    246604529 :          DO k = 1, npt
    1540    227637960 :             hcol(k) = hcol(k) + temp*zmat(k, j)
    1541              :          END DO
    1542              :       END DO
    1543     18966569 :       alpha = hcol(knew)
    1544              :       !
    1545              :       !     Set the unscaled initial direction D. Form the gradient of LFUNC a
    1546              :       !     XOPT, and multiply D by the second derivative matrix of LFUNC.
    1547              :       !
    1548     18966569 :       dd = zero
    1549     56902053 :       DO i = 1, n
    1550     37935484 :          d(i) = xpt(knew, i) - xopt(i)
    1551     37935484 :          gc(i) = bmat(knew, i)
    1552     37935484 :          gd(i) = zero
    1553     56902053 :          dd = dd + d(i)**2
    1554              :       END DO
    1555    113804106 :       DO k = 1, npt
    1556              :          temp = zero
    1557              :          sum = zero
    1558    284540013 :          DO j = 1, n
    1559    189702476 :             temp = temp + xpt(k, j)*xopt(j)
    1560    284540013 :             sum = sum + xpt(k, j)*d(j)
    1561              :          END DO
    1562     94837537 :          temp = hcol(k)*temp
    1563     94837537 :          sum = hcol(k)*sum
    1564    303506582 :          DO i = 1, n
    1565    189702476 :             gc(i) = gc(i) + temp*xpt(k, i)
    1566    284540013 :             gd(i) = gd(i) + sum*xpt(k, i)
    1567              :          END DO
    1568              :       END DO
    1569              :       !
    1570              :       !     Scale D and GD, with a sign change if required. Set S to another
    1571              :       !     vector in the initial two dimensional subspace.
    1572              :       !
    1573              :       gg = zero
    1574              :       sp = zero
    1575              :       dhd = zero
    1576     56902053 :       DO i = 1, n
    1577     37935484 :          gg = gg + gc(i)**2
    1578     37935484 :          sp = sp + d(i)*gc(i)
    1579     56902053 :          dhd = dhd + d(i)*gd(i)
    1580              :       END DO
    1581     18966569 :       scale = delta/SQRT(dd)
    1582     18966569 :       IF (sp*dhd < zero) scale = -scale
    1583     18966569 :       temp = zero
    1584     18966569 :       IF (sp*sp > 0.99_dp*dd*gg) temp = one
    1585     18966569 :       tau = scale*(ABS(sp) + half*scale*ABS(dhd))
    1586     18966569 :       IF (gg*delsq < 0.01_dp*tau*tau) temp = one
    1587     56902053 :       DO i = 1, n
    1588     37935484 :          d(i) = scale*d(i)
    1589     37935484 :          gd(i) = scale*gd(i)
    1590     56902053 :          s(i) = gc(i) + temp*gd(i)
    1591              :       END DO
    1592              :       !
    1593              :       !     Begin the iteration by overwriting S with a vector that has the
    1594              :       !     required length and direction, except that termination occurs if
    1595              :       !     the given D and S are nearly parallel.
    1596              :       !
    1597              :       mainloop: DO
    1598     26854239 :          iterc = iterc + 1
    1599     26854239 :          dd = zero
    1600     26854239 :          sp = zero
    1601     26854239 :          ss = zero
    1602     80566399 :          DO i = 1, n
    1603     53712160 :             dd = dd + d(i)**2
    1604     53712160 :             sp = sp + d(i)*s(i)
    1605     80566399 :             ss = ss + s(i)**2
    1606              :          END DO
    1607     26854239 :          temp = dd*ss - sp*sp
    1608     26854239 :          IF (temp <= 1.0e-8_dp*dd*ss) EXIT mainloop
    1609     25686236 :          denom = SQRT(temp)
    1610     77062116 :          DO i = 1, n
    1611     51375880 :             s(i) = (dd*s(i) - sp*d(i))/denom
    1612     77062116 :             w(i) = zero
    1613              :          END DO
    1614              :          !
    1615              :          !     Calculate the coefficients of the objective function on the circle
    1616              :          !     beginning with the multiplication of S by the second derivative ma
    1617              :          !
    1618    154124232 :          DO k = 1, npt
    1619              :             sum = zero
    1620    385353776 :             DO j = 1, n
    1621    385353776 :                sum = sum + xpt(k, j)*s(j)
    1622              :             END DO
    1623    128437996 :             sum = hcol(k)*sum
    1624    411040012 :             DO i = 1, n
    1625    385353776 :                w(i) = w(i) + sum*xpt(k, i)
    1626              :             END DO
    1627              :          END DO
    1628              :          cf1 = zero
    1629              :          cf2 = zero
    1630              :          cf3 = zero
    1631              :          cf4 = zero
    1632              :          cf5 = zero
    1633     77062116 :          DO i = 1, n
    1634     51375880 :             cf1 = cf1 + s(i)*w(i)
    1635     51375880 :             cf2 = cf2 + d(i)*gc(i)
    1636     51375880 :             cf3 = cf3 + s(i)*gc(i)
    1637     51375880 :             cf4 = cf4 + d(i)*gd(i)
    1638     77062116 :             cf5 = cf5 + s(i)*gd(i)
    1639              :          END DO
    1640     25686236 :          cf1 = half*cf1
    1641     25686236 :          cf4 = half*cf4 - cf1
    1642              :          !
    1643              :          !     Seek the value of the angle that maximizes the modulus of TAU.
    1644              :          !
    1645     25686236 :          taubeg = cf1 + cf2 + cf4
    1646     25686236 :          taumax = taubeg
    1647     25686236 :          tauold = taubeg
    1648     25686236 :          isave = 0
    1649     25686236 :          iu = 49
    1650     25686236 :          temp = twopi/REAL(iu + 1, DP)
    1651   1284311800 :          DO i = 1, iu
    1652   1258625564 :             angle = REAL(i, dp)*temp
    1653   1258625564 :             cth = COS(angle)
    1654   1258625564 :             sth = SIN(angle)
    1655   1258625564 :             tau = cf1 + (cf2 + cf4*cth)*cth + (cf3 + cf5*cth)*sth
    1656   1258625564 :             IF (ABS(tau) > ABS(taumax)) THEN
    1657              :                taumax = tau
    1658              :                isave = i
    1659              :                tempa = tauold
    1660   1192879501 :             ELSE IF (i == isave + 1) THEN
    1661     27926669 :                tempb = taU
    1662              :             END IF
    1663   1284311800 :             tauold = tau
    1664              :          END DO
    1665     25686236 :          IF (isave == 0) tempa = tau
    1666     15085913 :          IF (isave == iu) tempb = taubeg
    1667     25686236 :          step = zero
    1668     25686236 :          IF (tempa /= tempb) THEN
    1669     25686236 :             tempa = tempa - taumax
    1670     25686236 :             tempb = tempb - taumax
    1671     25686236 :             step = half*(tempa - tempb)/(tempa + tempb)
    1672              :          END IF
    1673     25686236 :          angle = temp*(REAL(isave, DP) + step)
    1674              :          !
    1675              :          !     Calculate the new D and GD. Then test for convergence.
    1676              :          !
    1677     25686236 :          cth = COS(angle)
    1678     25686236 :          sth = SIN(angle)
    1679     25686236 :          tau = cf1 + (cf2 + cf4*cth)*cth + (cf3 + cf5*cth)*sth
    1680     77062116 :          DO i = 1, n
    1681     51375880 :             d(i) = cth*d(i) + sth*s(i)
    1682     51375880 :             gd(i) = cth*gd(i) + sth*w(i)
    1683     77062116 :             s(i) = gc(i) + gd(i)
    1684              :          END DO
    1685     25686236 :          IF (ABS(tau) <= 1.1_dp*ABS(taubeg)) EXIT mainloop
    1686     26854239 :          IF (iterc >= n) EXIT mainloop
    1687              :       END DO mainloop
    1688              : 
    1689     18966569 :    END SUBROUTINE biglag
    1690              : 
    1691              : ! **************************************************************************************************
    1692              : !> \brief ...
    1693              : !> \param n ...
    1694              : !> \param npt ...
    1695              : !> \param xopt ...
    1696              : !> \param xpt ...
    1697              : !> \param gq ...
    1698              : !> \param hq ...
    1699              : !> \param pq ...
    1700              : !> \param delta ...
    1701              : !> \param step ...
    1702              : !> \param d ...
    1703              : !> \param g ...
    1704              : !> \param hd ...
    1705              : !> \param hs ...
    1706              : !> \param crvmin ...
    1707              : ! **************************************************************************************************
    1708     45823474 :    SUBROUTINE trsapp(n, npt, xopt, xpt, gq, hq, pq, delta, step, d, g, hd, hs, crvmin)
    1709              : 
    1710              :       INTEGER, INTENT(IN)                   :: n, npt
    1711              :       REAL(dp), DIMENSION(*), INTENT(IN)    :: xopt
    1712              :       REAL(dp), DIMENSION(npt, *), &
    1713              :          INTENT(IN)                          :: xpt
    1714              :       REAL(dp), DIMENSION(*), INTENT(INOUT)    :: gq, hq, pq
    1715              :       REAL(dp), INTENT(IN)                  :: delta
    1716              :       REAL(dp), DIMENSION(*), INTENT(INOUT)    :: step, d, g, hd, hs
    1717              :       REAL(dp), INTENT(INOUT)                  :: crvmin
    1718              : 
    1719              :       REAL(dp), PARAMETER                      :: half = 0.5_dp, zero = 0.0_dp
    1720              : 
    1721              :       INTEGER                                  :: i, isave, iterc, itermax, &
    1722              :                                                   itersw, iu, j
    1723              :       LOGICAL                                  :: jump1, jump2
    1724              :       REAL(dp) :: alpha, angle, angtest, bstep, cf, cth, dd, delsq, dg, dhd, &
    1725              :                   dhs, ds, gg, ggbeg, ggsav, qadd, qbeg, qmin, qnew, qred, qsav, ratio, &
    1726              :                   reduc, sg, sgk, shs, ss, sth, temp, tempa, tempb
    1727              : 
    1728              : !
    1729              : !   N is the number of variables of a quadratic objective function, Q
    1730              : !   The arguments NPT, XOPT, XPT, GQ, HQ and PQ have their usual meani
    1731              : !     in order to define the current quadratic model Q.
    1732              : !   DELTA is the trust region radius, and has to be positive.
    1733              : !   STEP will be set to the calculated trial step.
    1734              : !   The arrays D, G, HD and HS will be used for working space.
    1735              : !   CRVMIN will be set to the least curvature of H along the conjugate
    1736              : !     directions that occur, except that it is set to zero if STEP goe
    1737              : !     all the way to the trust region boundary.
    1738              : !
    1739              : !   The calculation of STEP begins with the truncated conjugate gradient
    1740              : !   method. If the boundary of the trust region is reached, then further
    1741              : !   changes to STEP may be made, each one being in the 2D space spanned
    1742              : !   by the current STEP and the corresponding gradient of Q. Thus STEP
    1743              : !   should provide a substantial reduction to Q within the trust region
    1744              : !
    1745              : !   Initialization, which includes setting HD to H times XOPT.
    1746              : !
    1747              : 
    1748     45823474 :       delsq = delta*delta
    1749     45823474 :       iterc = 0
    1750     45823474 :       itermax = n
    1751     45823474 :       itersw = itermax
    1752    137474763 :       DO i = 1, n
    1753    137474763 :          d(i) = xopt(i)
    1754              :       END DO
    1755     45823474 :       CALL updatehd
    1756              :       !
    1757              :       !   Prepare for the first line search.
    1758              :       !
    1759     45823474 :       qred = zero
    1760     45823474 :       dd = zero
    1761    137474763 :       DO i = 1, n
    1762     91651289 :          step(i) = zero
    1763     91651289 :          hs(i) = zero
    1764     91651289 :          g(i) = gq(i) + hd(i)
    1765     91651289 :          d(i) = -g(i)
    1766    137474763 :          dd = dd + d(i)**2
    1767              :       END DO
    1768     45823474 :       crvmin = zero
    1769     45823474 :       IF (dd == zero) RETURN
    1770              :       ds = zero
    1771              :       ss = zero
    1772              :       gg = dd
    1773              :       ggbeg = gg
    1774              :       !
    1775              :       !   Calculate the step to the trust region boundary and the product HD
    1776              :       !
    1777              :       jump1 = .FALSE.
    1778              :       jump2 = .FALSE.
    1779              :       mainloop: DO
    1780     77350711 :          IF (.NOT. jump2) THEN
    1781     77349944 :             IF (.NOT. jump1) THEN
    1782     77349944 :                iterc = iterc + 1
    1783     77349944 :                temp = delsq - ss
    1784     77349944 :                bstep = temp/(ds + SQRT(ds*ds + dd*temp))
    1785     77349944 :                CALL updatehd
    1786              :             END IF
    1787     77349944 :             jump1 = .FALSE.
    1788     77349944 :             IF (iterc <= itersw) THEN
    1789     77349944 :                dhd = zero
    1790    232063028 :                DO j = 1, n
    1791    232063028 :                   dhd = dhd + d(j)*hd(j)
    1792              :                END DO
    1793              :                !
    1794              :                !     Update CRVMIN and set the step-length ALPHA.
    1795              :                !
    1796     77349944 :                alpha = bstep
    1797     77349944 :                IF (dhd > zero) THEN
    1798     68358138 :                   temp = dhd/dd
    1799     68358138 :                   IF (iterc == 1) crvmin = temp
    1800     68358138 :                   crvmin = MIN(crvmin, temp)
    1801     68358138 :                   alpha = MIN(alpha, gg/dhd)
    1802              :                END IF
    1803     77349944 :                qadd = alpha*(gg - half*alpha*dhd)
    1804     77349944 :                qred = qred + qadd
    1805              :                !
    1806              :                !     Update STEP and HS.
    1807              :                !
    1808     77349944 :                ggsav = gg
    1809     77349944 :                gg = zero
    1810    232063028 :                DO i = 1, n
    1811    154713084 :                   step(i) = step(i) + alpha*d(i)
    1812    154713084 :                   hs(i) = hs(i) + alpha*hd(i)
    1813    232063028 :                   gg = gg + (g(i) + hs(i))**2
    1814              :                END DO
    1815              :                !
    1816              :                !     Begin another conjugate direction iteration if required.
    1817              :                !
    1818     77349944 :                IF (alpha < bstep) THEN
    1819     50847910 :                   IF (qadd <= 0.01_dp*qred) EXIT mainloop
    1820     50076577 :                   IF (gg <= 1.0e-4_dp*ggbeg) EXIT mainloop
    1821     31526675 :                   IF (iterc == itermax) EXIT mainloop
    1822     31526623 :                   temp = gg/ggsav
    1823     31526623 :                   dd = zero
    1824     31526623 :                   ds = zero
    1825     31526623 :                   ss = zero
    1826     94589055 :                   DO i = 1, n
    1827     63062432 :                      d(i) = temp*d(i) - g(i) - hs(i)
    1828     63062432 :                      dd = dd + d(i)**2
    1829     63062432 :                      ds = ds + d(i)*step(I)
    1830     94589055 :                      ss = ss + step(i)**2
    1831              :                   END DO
    1832     31526623 :                   IF (ds <= zero) EXIT mainloop
    1833     31526623 :                   IF (ss < delsq) CYCLE mainloop
    1834              :                END IF
    1835     26502034 :                crvmin = zero
    1836     26502034 :                itersw = iterc
    1837     26502034 :                jump2 = .TRUE.
    1838     26502034 :                IF (gg <= 1.0e-4_dp*ggbeg) EXIT mainloop
    1839              :             ELSE
    1840              :                jump2 = .FALSE.
    1841              :             END IF
    1842              :          END IF
    1843              :          !
    1844              :          !     Test whether an alternative iteration is required.
    1845              :          !
    1846              : !!!!  IF (gg <= 1.0e-4_dp*ggbeg) EXIT mainloop
    1847              :          IF (jump2) THEN
    1848     26106955 :             sg = zero
    1849     26106955 :             shs = zero
    1850     78326318 :             DO i = 1, n
    1851     52219363 :                sg = sg + step(i)*g(i)
    1852     78326318 :                shs = shs + step(i)*hs(i)
    1853              :             END DO
    1854     26106955 :             sgk = sg + shs
    1855     26106955 :             angtest = sgk/SQRT(gg*delsq)
    1856     26106955 :             IF (angtest <= -0.99_dp) EXIT mainloop
    1857              :             !
    1858              :             !     Begin the alternative iteration by calculating D and HD and some
    1859              :             !     scalar products.
    1860              :             !
    1861     22794760 :             iterc = iterc + 1
    1862     22794760 :             temp = SQRT(delsq*gg - sgk*sgk)
    1863     22794760 :             tempa = delsq/temp
    1864     22794760 :             tempb = sgk/temp
    1865     68389297 :             DO i = 1, n
    1866     68389297 :                d(i) = tempa*(g(i) + hs(i)) - tempb*step(i)
    1867              :             END DO
    1868     22794760 :             CALL updatehd
    1869     22794760 :             IF (iterc <= itersw) THEN
    1870              :                jump1 = .TRUE.
    1871              :                CYCLE mainloop
    1872              :             END IF
    1873              :          END IF
    1874     22794760 :          dg = zero
    1875     22794760 :          dhd = zero
    1876     22794760 :          dhs = zero
    1877     68389297 :          DO i = 1, n
    1878     45594537 :             dg = dg + d(i)*g(i)
    1879     45594537 :             dhd = dhd + hd(i)*d(i)
    1880     68389297 :             dhs = dhs + hd(i)*step(i)
    1881              :          END DO
    1882              :          !
    1883              :          !     Seek the value of the angle that minimizes Q.
    1884              :          !
    1885     22794760 :          cf = half*(shs - dhd)
    1886     22794760 :          qbeg = sg + cf
    1887     22794760 :          qsav = qbeg
    1888     22794760 :          qmin = qbeg
    1889     22794760 :          isave = 0
    1890     22794760 :          iu = 49
    1891              :          temp = twopi/REAL(iu + 1, dp)
    1892   1139738000 :          DO i = 1, iu
    1893   1116943240 :             angle = REAL(i, dp)*temp
    1894   1116943240 :             cth = COS(angle)
    1895   1116943240 :             sth = SIN(angle)
    1896   1116943240 :             qnew = (sg + cf*cth)*cth + (dg + dhs*cth)*sth
    1897   1116943240 :             IF (qnew < qmin) THEN
    1898              :                qmin = qnew
    1899              :                isave = i
    1900              :                tempa = qsav
    1901   1093200935 :             ELSE IF (i == isave + 1) THEN
    1902     28439255 :                tempb = qnew
    1903              :             END IF
    1904   1139738000 :             qsav = qnew
    1905              :          END DO
    1906     22794760 :          IF (isave == zero) tempa = qnew
    1907      9879702 :          IF (isave == iu) tempb = qbeg
    1908     22794760 :          angle = zero
    1909     22794760 :          IF (tempa /= tempb) THEN
    1910     22794760 :             tempa = tempa - qmin
    1911     22794760 :             tempb = tempb - qmin
    1912     22794760 :             angle = half*(tempa - tempb)/(tempa + tempb)
    1913              :          END IF
    1914     22794760 :          angle = temp*(REAL(isave, DP) + angle)
    1915              :          !
    1916              :          !     Calculate the new STEP and HS. Then test for convergence.
    1917              :          !
    1918     22794760 :          cth = COS(angle)
    1919     22794760 :          sth = SIN(angle)
    1920     22794760 :          reduc = qbeg - (sg + cf*cth)*cth - (dg + dhs*cth)*sth
    1921     22794760 :          gg = zero
    1922     68389297 :          DO i = 1, n
    1923     45594537 :             step(i) = cth*step(i) + sth*d(i)
    1924     45594537 :             hs(i) = cth*hs(i) + sth*hd(i)
    1925     68389297 :             gg = gg + (g(i) + hs(i))**2
    1926              :          END DO
    1927     22794760 :          qred = qred + reduc
    1928     22794760 :          ratio = reduc/qred
    1929     22794760 :          IF (iterc < itermax .AND. ratio > 0.01_dp) THEN
    1930          767 :             jump2 = .TRUE.
    1931              :          ELSE
    1932              :             EXIT mainloop
    1933              :          END IF
    1934              : 
    1935     45824088 :          IF (gg <= 1.0e-4_dp*ggbeg) EXIT mainloop
    1936              : 
    1937              :       END DO mainloop
    1938              : 
    1939              :    CONTAINS
    1940              : ! **************************************************************************************************
    1941              : !> \brief ...
    1942              : ! **************************************************************************************************
    1943    145968178 :       SUBROUTINE updatehd
    1944              :       INTEGER                                            :: i, ih, j, k
    1945              : 
    1946    437927088 :          DO i = 1, n
    1947    437927088 :             hd(i) = zero
    1948              :          END DO
    1949    875854176 :          DO k = 1, npt
    1950    729885998 :             temp = zero
    1951   2189923376 :             DO j = 1, n
    1952   2189923376 :                temp = temp + xpt(k, j)*d(j)
    1953              :             END DO
    1954    729885998 :             temp = temp*pq(k)
    1955   2335891554 :             DO i = 1, n
    1956   2189923376 :                hd(i) = hd(i) + temp*xpt(k, i)
    1957              :             END DO
    1958              :          END DO
    1959    145968178 :          ih = 0
    1960    437927088 :          DO j = 1, n
    1961    875926160 :             DO i = 1, j
    1962    437999072 :                ih = ih + 1
    1963    437999072 :                IF (i < j) hd(j) = hd(j) + hq(ih)*d(i)
    1964    729957982 :                hd(i) = hd(i) + hq(ih)*d(j)
    1965              :             END DO
    1966              :          END DO
    1967    145968178 :       END SUBROUTINE updatehd
    1968              : 
    1969              :    END SUBROUTINE trsapp
    1970              : 
    1971              : ! **************************************************************************************************
    1972              : !> \brief ...
    1973              : !> \param n ...
    1974              : !> \param npt ...
    1975              : !> \param bmat ...
    1976              : !> \param zmat ...
    1977              : !> \param idz ...
    1978              : !> \param ndim ...
    1979              : !> \param vlag ...
    1980              : !> \param beta ...
    1981              : !> \param knew ...
    1982              : !> \param w ...
    1983              : ! **************************************************************************************************
    1984     53176237 :    SUBROUTINE update(n, npt, bmat, zmat, idz, ndim, vlag, beta, knew, w)
    1985              : 
    1986              :       INTEGER, INTENT(IN)                                :: n, npt, ndim
    1987              :       INTEGER, INTENT(INOUT)                             :: idz
    1988              :       REAL(dp), DIMENSION(npt, *), INTENT(INOUT)         :: zmat
    1989              :       REAL(dp), DIMENSION(ndim, *), INTENT(INOUT)        :: bmat
    1990              :       REAL(dp), DIMENSION(*), INTENT(INOUT)              :: vlag
    1991              :       REAL(dp), INTENT(INOUT)                            :: beta
    1992              :       INTEGER, INTENT(INOUT)                             :: knew
    1993              :       REAL(dp), DIMENSION(*), INTENT(INOUT)              :: w
    1994              : 
    1995              :       REAL(dp), PARAMETER                                :: one = 1.0_dp, zero = 0.0_dp
    1996              : 
    1997              :       INTEGER                                            :: i, iflag, j, ja, jb, jl, jp, nptm
    1998              :       REAL(dp)                                           :: alpha, denom, scala, scalb, tau, tausq, &
    1999              :                                                             temp, tempa, tempb
    2000              : 
    2001              : !   The arrays BMAT and ZMAT with IDZ are updated, in order to shift the
    2002              : !   interpolation point that has index KNEW. On entry, VLAG contains the
    2003              : !   components of the vector Theta*Wcheck+e_b of the updating formula
    2004              : !   (6.11), and BETA holds the value of the parameter that has this na
    2005              : !   The vector W is used for working space.
    2006              : !
    2007              : 
    2008     53176237 :       nptm = npt - n - 1
    2009              :       !
    2010              :       !     Apply the rotations that put zeros in the KNEW-th row of ZMAT.
    2011              :       !
    2012     53176237 :       jl = 1
    2013    106358273 :       DO j = 2, nptm
    2014    106358273 :          IF (j == idz) THEN
    2015              :             jl = idz
    2016     53182036 :          ELSE IF (zmat(knew, j) /= zero) THEN
    2017     51737992 :             temp = SQRT(zmat(knew, jl)**2 + zmat(knew, j)**2)
    2018     51737992 :             tempa = zmat(knew, jl)/temp
    2019     51737992 :             tempb = zmat(knew, j)/temp
    2020    310474944 :             DO I = 1, NPT
    2021    258736952 :                temp = tempa*zmat(i, jl) + tempb*zmat(i, j)
    2022    258736952 :                zmat(i, j) = tempa*zmat(i, j) - tempb*zmat(i, jl)
    2023    310474944 :                zmat(i, jl) = temp
    2024              :             END DO
    2025     51737992 :             zmat(knew, j) = zero
    2026              :          END IF
    2027              :       END DO
    2028              :       !
    2029              :       !   Put the first NPT components of the KNEW-th column of HLAG into W,
    2030              :       !   and calculate the parameters of the updating formula.
    2031              :       !
    2032     53176237 :       tempa = zmat(knew, 1)
    2033     53176237 :       IF (idz >= 2) tempa = -tempa
    2034     53176237 :       IF (jl > 1) tempb = zmat(knew, jl)
    2035    319069020 :       DO i = 1, npt
    2036    265892783 :          w(i) = tempa*zmat(i, 1)
    2037    319069020 :          IF (jl > 1) w(i) = w(i) + tempb*zmat(i, jl)
    2038              :       END DO
    2039     53176237 :       alpha = w(knew)
    2040     53176237 :       tau = vlag(knew)
    2041     53176237 :       tausq = tau*tau
    2042     53176237 :       denom = alpha*beta + tausq
    2043     53176237 :       vlag(knew) = vlag(knew) - one
    2044              :       !
    2045              :       !   Complete the updating of ZMAT when there is only one nonzero eleme
    2046              :       !   in the KNEW-th row of the new matrix ZMAT, but, if IFLAG is set to
    2047              :       !   then the first column of ZMAT will be exchanged with another one l
    2048              :       !
    2049     53176237 :       iflag = 0
    2050     53176237 :       IF (JL == 1) THEN
    2051     53176237 :          temp = SQRT(ABS(denom))
    2052     53176237 :          tempb = tempa/temp
    2053     53176237 :          tempa = tau/temp
    2054    319069020 :          DO i = 1, npt
    2055    319069020 :             zmat(i, 1) = tempa*zmat(i, 1) - tempb*vlag(i)
    2056              :          END DO
    2057     53176237 :          IF (idz == 1 .AND. temp < zero) idz = 2
    2058     53176237 :          IF (idz >= 2 .AND. temp >= zero) iflag = 1
    2059              :       ELSE
    2060              :          !
    2061              :          !   Complete the updating of ZMAT in the alternative case.
    2062              :          !
    2063            0 :          ja = 1
    2064            0 :          IF (beta >= zero) ja = jl
    2065            0 :          jb = jl + 1 - ja
    2066            0 :          temp = zmat(knew, jb)/denom
    2067            0 :          tempa = temp*beta
    2068            0 :          tempb = temp*tau
    2069            0 :          temp = zmat(knew, ja)
    2070            0 :          scala = one/SQRT(ABS(beta)*temp*temp + tausq)
    2071            0 :          scalb = scala*SQRT(ABS(denom))
    2072            0 :          DO i = 1, npt
    2073            0 :             zmat(i, ja) = scala*(tau*zmat(i, ja) - temp*vlag(i))
    2074            0 :             zmat(i, jb) = scalb*(zmat(i, jb) - tempa*w(i) - tempb*vlag(i))
    2075              :          END DO
    2076            0 :          IF (denom <= zero) THEN
    2077            0 :             IF (beta < zero) idz = idz + 1
    2078            0 :             IF (beta >= zero) iflag = 1
    2079              :          END IF
    2080              :       END IF
    2081              :       !
    2082              :       !   IDZ is reduced in the following case, and usually the first column
    2083              :       !   of ZMAT is exchanged with a later one.
    2084              :       !
    2085              :       IF (iflag == 1) THEN
    2086            0 :          idz = idz - 1
    2087            0 :          DO i = 1, npt
    2088            0 :             temp = zmat(i, 1)
    2089            0 :             zmat(i, 1) = zmat(i, idz)
    2090            0 :             zmat(i, idz) = temp
    2091              :          END DO
    2092              :       END IF
    2093              :       !
    2094              :       !   Finally, update the matrix BMAT.
    2095              :       !
    2096    159534510 :       DO j = 1, n
    2097    106358273 :          jp = npt + j
    2098    106358273 :          w(jp) = bmat(knew, j)
    2099    106358273 :          tempa = (alpha*vlag(jp) - tau*w(jp))/denom
    2100    106358273 :          tempb = (-beta*w(jp) - tau*vlag(jp))/denom
    2101    850939947 :          DO i = 1, jp
    2102    691405437 :             bmat(i, j) = bmat(i, j) + tempa*vlag(i) + tempb*w(i)
    2103    797763710 :             IF (i > npt) bmat(jp, i - npt) = bmat(i, j)
    2104              :          END DO
    2105              :       END DO
    2106              : 
    2107     53176237 :    END SUBROUTINE update
    2108              : 
    2109            0 : END MODULE powell
        

Generated by: LCOV version 2.0-1