LCOV - code coverage report
Current view: top level - num/private - mod_brent.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.4 % 270 263
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 3 3

            Line data    Source code
       1              :    module mod_brent
       2              :    use const_def, only: dp
       3              : 
       4              :    implicit none
       5              : 
       6              :    contains
       7              : 
       8              :    ! this code was written by John Burkardt
       9              :    ! see his wonderful site for lots of numerical software.
      10              :    ! here's the link for the implementation that we use here.
      11              :    ! http://people.sc.fsu.edu/~jburkardt/f_src/brent/brent.html
      12              : 
      13              : 
      14            6 :    real(dp) function eval_global_min(max_tries, a, b, c, m, machep, e, t, f, x, ierr)
      15              :       integer, intent(in) :: max_tries
      16              :       real(dp), intent(in) :: a, b, c, m, machep, e, t
      17              :       interface
      18              :          real(dp) function f(x)
      19              :             use const_def, only: dp
      20              :             implicit none
      21              :             real(dp), intent(in) :: x
      22              :          end function f
      23              :       end interface
      24              :       real(dp), intent(out) :: x
      25              :       integer, intent(out) :: ierr
      26              : 
      27              :       !  Parameters:
      28              :       !
      29              :       !    Input, real ( kind = 8 ) A, B, the endpoints of the interval.
      30              :       !    It must be the case that A < B.
      31              :       !
      32              :       !    Input, real ( kind = 8 ) C, an initial guess for the global
      33              :       !    minimizer.  If no good guess is known, C = A or B is acceptable.
      34              :       !
      35              :       !    Input, real ( kind = 8 ) M, the bound on the second derivative.
      36              :       !
      37              :       !    Input, real ( kind = 8 ) MACHEP, an estimate for the relative machine
      38              :       !    precision.
      39              :       !
      40              :       !    Input, real ( kind = 8 ) E, a positive tolerance, a bound for the
      41              :       !    absolute error in the evaluation of F(X) for any X in [A,B].
      42              :       !
      43              :       !    Input, real ( kind = 8 ) T, a positive error tolerance.
      44              :       !
      45              :       !    Input, external real ( kind = 8 ) F, the name of a user-supplied
      46              :       !    function, of the form "FUNCTION F ( X )", which evaluates the
      47              :       !    function whose global minimum is being sought.
      48              :       !
      49              :       !    Output, real ( kind = 8 ) X, the estimated value of the abscissa
      50              :       !    for which F attains its global minimum value in [A,B].
      51              :       !
      52              :       !    Output, real ( kind = 8 ) GLOMIN, the value F(X).
      53              :       !
      54              : 
      55            6 :         real    ( kind = 8 ) :: a0
      56            6 :         real    ( kind = 8 ) :: a2
      57            6 :         real    ( kind = 8 ) :: a3
      58            6 :         real    ( kind = 8 ) :: d0
      59            6 :         real    ( kind = 8 ) :: d1
      60            6 :         real    ( kind = 8 ) :: d2
      61            6 :         real    ( kind = 8 ) :: h
      62              :         integer ( kind = 4 ) :: k, iter
      63            6 :         real    ( kind = 8 ) :: m2
      64            6 :         real    ( kind = 8 ) :: p
      65            6 :         real    ( kind = 8 ) :: q
      66            6 :         real    ( kind = 8 ) :: qs
      67            6 :         real    ( kind = 8 ) :: r
      68            6 :         real    ( kind = 8 ) :: s
      69            6 :         real    ( kind = 8 ) :: sc
      70            6 :         real    ( kind = 8 ) :: y
      71            6 :         real    ( kind = 8 ) :: y0
      72            6 :         real    ( kind = 8 ) :: y1
      73            6 :         real    ( kind = 8 ) :: y2
      74            6 :         real    ( kind = 8 ) :: y3
      75            6 :         real    ( kind = 8 ) :: yb
      76            6 :         real    ( kind = 8 ) :: z0
      77            6 :         real    ( kind = 8 ) :: z1
      78            6 :         real    ( kind = 8 ) :: z2
      79              : 
      80            6 :         ierr = 0
      81            6 :         a0 = b
      82            6 :         x = a0
      83            6 :         a2 = a
      84            6 :         y0 = f ( b )
      85            6 :         yb = y0
      86            6 :         y2 = f ( a )
      87            6 :         y = y2
      88              : 
      89            6 :         if ( y0 < y ) then
      90              :           y = y0
      91              :         else
      92            4 :           x = a
      93              :         end if
      94              : 
      95            6 :         if ( m <= 0.0D+00 .or. b <= a ) then
      96              :           eval_global_min = y
      97              :           return
      98              :         end if
      99              : 
     100            5 :         m2 = 0.5D+00 * ( 1.0D+00 + 16.0D+00 * machep ) * m
     101              : 
     102            5 :         if ( c <= a .or. b <= c ) then
     103            0 :           sc = 0.5D+00 * ( a + b )
     104              :         else
     105            5 :           sc = c
     106              :         end if
     107              : 
     108            5 :         y1 = f ( sc )
     109            5 :         k = 3
     110            5 :         d0 = a2 - sc
     111            5 :         h = 9.0D+00 / 11.0D+00
     112              : 
     113            5 :         if ( y1 < y ) then
     114            2 :           x = sc
     115            2 :           y = y1
     116              :         end if
     117              : 
     118         1084 :         do iter = 1, max_tries+1
     119              : 
     120         1084 :           if (iter > max_tries) then
     121            0 :             ierr = -1
     122            0 :             exit
     123              :           end if
     124              : 
     125         1084 :           d1 = a2 - a0
     126         1084 :           d2 = sc - a0
     127         1084 :           z2 = b - a2
     128         1084 :           z0 = y2 - y1
     129         1084 :           z1 = y2 - y0
     130         1084 :           r = d1 * d1 * z0 - d0 * d0 * z1
     131         1084 :           p = r
     132         1084 :           qs = 2.0D+00 * ( d0 * z1 - d1 * z0 )
     133         1084 :           q = qs
     134              : 
     135         1084 :           if ( k < 1000000 .or. y2 <= y ) then
     136              : 
     137              :             do
     138              : 
     139         1114 :               if ( q * ( r * ( yb - y2 ) + z2 * q * ( ( y2 - y ) + t ) ) < &
     140              :                 z2 * m2 * r * ( z2 * q - r ) ) then
     141          470 :                 a3 = a2 + r / q
     142          470 :                 y3 = f ( a3 )
     143              : 
     144          470 :                 if ( y3 < y ) then
     145          140 :                   x = a3
     146          140 :                   y = y3
     147              :                 end if
     148              :               end if
     149              : 
     150         1114 :               k = mod ( 1611 * k, 1048576 )
     151         1114 :               q = 1.0D+00
     152         1114 :               r = ( b - a ) * 0.00001D+00 * real ( k, kind = 8 )
     153              : 
     154         1114 :               if ( z2 <= r ) then
     155              :                 exit
     156              :               end if
     157              : 
     158              :             end do
     159              : 
     160              :           else
     161              : 
     162           43 :             k = mod ( 1611 * k, 1048576 )
     163           43 :             q = 1.0D+00
     164           43 :             r = ( b - a ) * 0.00001D+00 * real ( k, kind = 8 )
     165              : 
     166           47 :             do while ( r < z2 )
     167              : 
     168            4 :               if ( q * ( r * ( yb - y2 ) + z2 * q * ( ( y2 - y ) + t ) ) < &
     169              :                 z2 * m2 * r * ( z2 * q - r ) ) then
     170            4 :                 a3 = a2 + r / q
     171            4 :                 y3 = f ( a3 )
     172              : 
     173            4 :                 if ( y3 < y ) then
     174            0 :                   x = a3
     175            0 :                   y = y3
     176              :                 end if
     177              :               end if
     178              : 
     179            4 :               k = mod ( 1611 * k, 1048576 )
     180            4 :               q = 1.0D+00
     181            4 :               r = ( b - a ) * 0.00001D+00 * real ( k, kind = 8 )
     182              : 
     183              :             end do
     184              : 
     185              :           end if
     186              : 
     187         1084 :           r = m2 * d0 * d1 * d2
     188         1084 :           s = sqrt ( ( ( y2 - y ) + t ) / m2 )
     189         1084 :           h = 0.5D+00 * ( 1.0D+00 + h )
     190         1084 :           p = h * ( p + 2.0D+00 * r * s )
     191         1084 :           q = q + 0.5D+00 * qs
     192         1084 :           r = - 0.5D+00 * ( d0 + ( z0 + 2.01D+00 * e ) / ( d0 * m2 ) )
     193              : 
     194         1084 :           if ( r < s .or. d0 < 0.0D+00 ) then
     195         1059 :             r = a2 + s
     196              :           else
     197           25 :             r = a2 + r
     198              :           end if
     199              : 
     200         1084 :           if ( 0.0D+00 < p * q ) then
     201         1053 :             a3 = a2 + p / q
     202              :           else
     203           31 :             a3 = r
     204              :           end if
     205              : 
     206           13 :           do
     207              : 
     208         1097 :             a3 = max ( a3, r )
     209              : 
     210         1097 :             if ( b <= a3 ) then
     211            6 :               a3 = b
     212            6 :               y3 = yb
     213              :             else
     214         1091 :               y3 = f ( a3 )
     215              :             end if
     216              : 
     217         1097 :             if ( y3 < y ) then
     218           27 :               x = a3
     219           27 :               y = y3
     220              :             end if
     221              : 
     222         1097 :             d0 = a3 - a2
     223              : 
     224         1097 :             if ( a3 <= r ) then
     225              :               exit
     226              :             end if
     227              : 
     228           41 :             p = 2.0D+00 * ( y2 - y3 ) / ( m * d0 )
     229              : 
     230           41 :             if ( ( 1.0D+00 + 9.0D+00 * machep ) * d0 <= abs ( p ) ) then
     231              :               exit
     232              :             end if
     233              : 
     234           40 :             if ( 0.5D+00 * m2 * ( d0 * d0 + p * p ) <= &
     235              :               ( y2 - y ) + ( y3 - y ) + 2.0D+00 * t ) then
     236              :               exit
     237              :             end if
     238              : 
     239           13 :             a3 = 0.5D+00 * ( a2 + a3 )
     240           41 :             h = 0.9D+00 * h
     241              : 
     242              :           end do
     243              : 
     244         1084 :           if ( b <= a3 ) then
     245              :             exit
     246              :           end if
     247              : 
     248         1079 :           a0 = sc
     249         1079 :           sc = a2
     250         1079 :           a2 = a3
     251         1079 :           y0 = y1
     252         1079 :           y1 = y2
     253         1084 :           y2 = y3
     254              : 
     255              :         end do
     256              : 
     257              :         eval_global_min = y
     258              : 
     259              :         return
     260              :    end function eval_global_min
     261              : 
     262              : 
     263            5 :    real(dp) function eval_local_min(max_tries, a, b, eps, t, f, x, ierr)
     264              :       integer, intent(in) :: max_tries
     265              :       real(dp), intent(in) :: a, b, eps, t
     266              :       interface
     267              :          real(dp) function f(x)
     268              :             use const_def, only: dp
     269              :             implicit none
     270              :             real(dp), intent(in) :: x
     271              :          end function f
     272              :       end interface
     273              :       real(dp), intent(out) :: x
     274              :       integer, intent(out) :: ierr
     275              : 
     276              :    ! *****************************************************************************80
     277              :    !
     278              :    !! LOCAL_MIN seeks a local minimum of a function F(X) in an interval [A,B].
     279              :    !
     280              :    !  Discussion:
     281              :    !
     282              :    !    The method used is a combination of golden section search and
     283              :    !    successive parabolic interpolation.  Convergence is never much slower
     284              :    !    than that for a Fibonacci search.  If F has a continuous second
     285              :    !    derivative which is positive at the minimum (which is not at A or
     286              :    !    B), then convergence is superlinear, and usually of the order of
     287              :    !    about 1.324....
     288              :    !
     289              :    !    The values EPS and T define a tolerance TOL = EPS * abs ( X ) + T.
     290              :    !    F is never evaluated at two points closer than TOL.
     291              :    !
     292              :    !    If F is a unimodal function and the computed values of F are always
     293              :    !    unimodal when separated by at least SQEPS * abs ( X ) + (T/3), then
     294              :    !    LOCAL_MIN approximates the abscissa of the global minimum of F on the
     295              :    !    interval [A,B] with an error less than 3*SQEPS*abs(LOCAL_MIN)+T.
     296              :    !
     297              :    !    If F is not unimodal, then LOCAL_MIN may approximate a local, but
     298              :    !    perhaps non-global, minimum to the same accuracy.
     299              :    !
     300              :    !  Licensing:
     301              :    !
     302              :    !    This code is distributed under the GNU LGPL license.
     303              :    !
     304              :    !  Modified:
     305              :    !
     306              :    !    13 April 2008
     307              :    !
     308              :    !  Author:
     309              :    !
     310              :    !    Original FORTRAN77 version by Richard Brent
     311              :    !    FORTRAN90 version by John Burkardt
     312              :    !
     313              :    !  Reference:
     314              :    !
     315              :    !    Richard Brent,
     316              :    !    Algorithms for Minimization Without Derivatives,
     317              :    !    Dover, 2002,
     318              :    !    ISBN: 0-486-41998-3,
     319              :    !    LC: QA402.5.B74.
     320              :    !
     321              :    !  Parameters:
     322              :    !
     323              :    !    Input, real ( kind = 8 ) A, B, the endpoints of the interval.
     324              :    !
     325              :    !    Input, real ( kind = 8 ) EPS, a positive relative error tolerance.
     326              :    !    EPS should be no smaller than twice the relative machine precision,
     327              :    !    and preferably not much less than the square root of the relative
     328              :    !    machine precision.
     329              :    !
     330              :    !    Input, real ( kind = 8 ) T, a positive absolute error tolerance.
     331              :    !
     332              :    !    Input, external real ( kind = 8 ) F, the name of a user-supplied
     333              :    !    function, of the form "FUNCTION F ( X )", which evaluates the
     334              :    !    function whose local minimum is being sought.
     335              :    !
     336              :    !    Output, real ( kind = 8 ) X, the estimated value of an abscissa
     337              :    !    for which F attains a local minimum value in [A,B].
     338              :    !
     339              :    !    Output, real ( kind = 8 ) LOCAL_MIN, the value F(X).
     340              :    !
     341              : 
     342            5 :      real ( kind = 8 ) :: c
     343            5 :      real ( kind = 8 ) :: d
     344            5 :      real ( kind = 8 ) :: e
     345            5 :      real ( kind = 8 ) :: fu
     346            5 :      real ( kind = 8 ) :: fv
     347            5 :      real ( kind = 8 ) :: fw
     348            5 :      real ( kind = 8 ) :: fx
     349            5 :      real ( kind = 8 ) :: m
     350            5 :      real ( kind = 8 ) :: p
     351            5 :      real ( kind = 8 ) :: q
     352            5 :      real ( kind = 8 ) :: r
     353            5 :      real ( kind = 8 ) :: sa
     354            5 :      real ( kind = 8 ) :: sb
     355            5 :      real ( kind = 8 ) :: t2
     356            5 :      real ( kind = 8 ) :: tol
     357            5 :      real ( kind = 8 ) :: u
     358            5 :      real ( kind = 8 ) :: v
     359            5 :      real ( kind = 8 ) :: w
     360              :      integer ( kind = 4 ) :: iter
     361              : 
     362            5 :      ierr = 0
     363              : 
     364              :    !
     365              :    !  C is the square of the inverse of the golden ratio.
     366              :    !
     367            5 :      c = 0.5D+00 * ( 3.0D+00 - sqrt ( 5.0D+00 ) )
     368              : 
     369            5 :      sa = a
     370            5 :      sb = b
     371            5 :      x = sa + c * ( sb - sa )
     372            5 :      fx = f ( x )
     373            5 :      w = x
     374            5 :      v = w
     375            5 :      e = 0.0D+00
     376            5 :      fw = fx
     377            5 :      fv = fw
     378            5 :      d = 0
     379              : 
     380           49 :      do iter = 1, max_tries+1
     381              : 
     382           49 :        m = 0.5D+00 * ( sa + sb )
     383           49 :        tol = eps * abs ( x ) + t
     384           49 :        t2 = 2.0D+00 * tol
     385              :    !
     386              :    !  Check the stopping criterion.
     387              :    !
     388           49 :        if ( abs ( x - m ) <= t2 - 0.5D+00 * ( sb - sa ) ) then
     389              :          exit
     390              :        end if
     391              : 
     392           44 :        if (iter > max_tries) then
     393            0 :          ierr = -1
     394            0 :          exit
     395              :        end if
     396              :    !
     397              :    !  Fit a parabola.
     398              :    !
     399           44 :        r = 0.0D+00
     400           44 :        q = r
     401           44 :        p = q
     402              : 
     403           44 :        if ( tol < abs ( e ) ) then
     404              : 
     405           39 :          r = ( x - w ) * ( fx - fv )
     406           39 :          q = ( x - v ) * ( fx - fw )
     407           39 :          p = ( x - v ) * q - ( x - w ) * r
     408           39 :          q = 2.0D+00 * ( q - r )
     409              : 
     410           39 :          if ( 0.0D+00 < q ) then
     411           14 :            p = - p
     412              :          end if
     413              : 
     414           39 :          q = abs ( q )
     415              : 
     416           39 :          r = e
     417           39 :          e = d
     418              : 
     419              :        end if
     420              : 
     421              :        if ( abs ( p ) < abs ( 0.5D+00 * q * r ) .and. &
     422           44 :             q * ( sa - x ) < p .and. &
     423              :             p < q * ( sb - x ) ) then
     424              :    !
     425              :    !  Take the parabolic interpolation step.
     426              :    !
     427           32 :          d = p / q
     428           32 :          u = x + d
     429              :    !
     430              :    !  F must not be evaluated too close to A or B.
     431              :    !
     432           32 :          if ( ( u - sa ) < t2 .or. ( sb - u ) < t2 ) then
     433              : 
     434            5 :            if ( x < m ) then
     435              :              d = tol
     436              :            else
     437            3 :              d = - tol
     438              :            end if
     439              : 
     440              :          end if
     441              :    !
     442              :    !  A golden-section step.
     443              :    !
     444              :        else
     445              : 
     446           12 :          if ( x < m ) then
     447            6 :            e = sb - x
     448              :          else
     449            6 :            e = sa - x
     450              :          end if
     451              : 
     452           12 :          d = c * e
     453              : 
     454              :        end if
     455              :    !
     456              :    !  F must not be evaluated too close to X.
     457              :    !
     458           44 :        if ( tol <= abs ( d ) ) then
     459           41 :          u = x + d
     460            3 :        else if ( 0.0D+00 < d ) then
     461            2 :          u = x + tol
     462              :        else
     463            1 :          u = x - tol
     464              :        end if
     465              : 
     466           44 :        fu = f ( u )
     467              :    !
     468              :    !  Update A, B, V, W, and X.
     469              :    !
     470           49 :        if ( fu <= fx ) then
     471              : 
     472           26 :          if ( u < x ) then
     473              :            sb = x
     474              :          else
     475           11 :            sa = x
     476              :          end if
     477              : 
     478           26 :          v = w
     479           26 :          fv = fw
     480           26 :          w = x
     481           26 :          fw = fx
     482           26 :          x = u
     483           26 :          fx = fu
     484              : 
     485              :        else
     486              : 
     487           18 :          if ( u < x ) then
     488              :            sa = u
     489              :          else
     490           10 :            sb = u
     491              :          end if
     492              : 
     493           18 :          if ( fu <= fw .or. w == x ) then
     494              :            v = w
     495              :            fv = fw
     496              :            w = u
     497              :            fw = fu
     498            3 :          else if ( fu <= fv .or. v == x .or. v == w ) then
     499            3 :            v = u
     500            3 :            fv = fu
     501              :          end if
     502              : 
     503              :        end if
     504              : 
     505              :      end do
     506              : 
     507            5 :      eval_local_min = fx
     508              : 
     509              :      return
     510              :    end function eval_local_min
     511              : 
     512              : 
     513           10 :    real(dp) function eval_brent_safe_zero ( a, b, machep, t, epsy, f, fa_in, fb_in, lrpar, rpar, lipar, ipar, ierr )
     514              : 
     515              :    ! *****************************************************************************80
     516              :    !
     517              :    !! seeks the root of a function F(X) in an interval [A,B].
     518              :    !
     519              :    !  Discussion:
     520              :    !
     521              :    !    The interval [A,B] must be a change of sign interval for F.
     522              :    !    That is, F(A) and F(B) must be of opposite signs.  Then
     523              :    !    assuming that F is continuous implies the existence of at least
     524              :    !    one value C between A and B for which F(C) = 0.
     525              :    !
     526              :    !    The location of the zero is determined to within an accuracy
     527              :    !    of 6 * MACHEPS * abs ( C ) + 2 * T.   or if abs(f(x)) < epsy.
     528              :    !
     529              :    !  Licensing:
     530              :    !
     531              :    !    This code is distributed under the GNU LGPL license.
     532              :    !
     533              :    !  Modified:
     534              :    !
     535              :    !    12 April 2008
     536              :    !
     537              :    !  Author:
     538              :    !
     539              :    !    Original FORTRAN77 version by Richard Brent.
     540              :    !    FORTRAN90 version by John Burkardt.
     541              :    !
     542              :    !  Reference:
     543              :    !
     544              :    !    Richard Brent,
     545              :    !    Algorithms for Minimization Without Derivatives,
     546              :    !    Dover, 2002,
     547              :    !    ISBN: 0-486-41998-3,
     548              :    !    LC: QA402.5.B74.
     549              :    !
     550              :    !  Parameters:
     551              :    !
     552              :    !    Input, real ( kind = 8 ) A, B, the endpoints of the change of
     553              :    !    sign interval.
     554              :    !
     555              :    !    Input, real ( kind = 8 ) MACHEP, an estimate for the relative machine
     556              :    !    precision.
     557              :    !
     558              :    !    Input, real ( kind = 8 ) T, a positive error tolerance.
     559              :    !
     560              :    !    Input, external real ( kind = 8 ) F, the name of a user-supplied
     561              :    !    function, of the form "FUNCTION F ( X )", which evaluates the
     562              :    !    function whose zero is being sought.
     563              :    !
     564              :    !    Output, real ( kind = 8 ) ZERO, the estimated value of a zero of
     565              :    !    the function F.
     566              :    !
     567              : 
     568              :      interface
     569              : #include "num_root_fcn.dek"
     570              :      end interface
     571              :      integer, intent(in) :: lipar, lrpar
     572              :      integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     573              :      real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     574              :      integer, intent(out) :: ierr
     575              : 
     576              :      real ( kind = 8 ) :: a
     577              :      real ( kind = 8 ) :: b
     578           10 :      real ( kind = 8 ) :: c
     579           10 :      real ( kind = 8 ) :: d
     580           10 :      real ( kind = 8 ) :: e
     581           10 :      real ( kind = 8 ) :: fa, fa_in
     582           10 :      real ( kind = 8 ) :: fb, fb_in
     583           10 :      real ( kind = 8 ) :: fc
     584           10 :      real ( kind = 8 ) :: m
     585              :      real ( kind = 8 ) :: machep
     586           10 :      real ( kind = 8 ) :: p
     587           10 :      real ( kind = 8 ) :: q
     588           10 :      real ( kind = 8 ) :: r
     589           10 :      real ( kind = 8 ) :: s
     590           10 :      real ( kind = 8 ) :: sa
     591              :      real ( kind = 8 ) :: sb
     592              :      real ( kind = 8 ) :: t, epsy
     593           10 :      real ( kind = 8 ) :: tol
     594           10 :      real ( kind = 8 ) :: dfdx
     595              : 
     596           10 :      ierr = 0
     597              : 
     598              :    !
     599              :    !  Make local copies of A and B.
     600              :    !
     601           10 :      sa = a
     602           10 :      sb = b
     603           10 :      fa = fa_in
     604              :      !fa = f ( sa, dfdx, lrpar, rpar, lipar, ipar, ierr )
     605              :      !if (ierr /= 0) return
     606           10 :      fb = fb_in
     607              :      !fb = f ( sb, dfdx, lrpar, rpar, lipar, ipar, ierr )
     608              :      !if (ierr /= 0) return
     609              : 
     610           10 :      c = sa
     611           10 :      fc = fa
     612           10 :      e = sb - sa
     613           10 :      d = e
     614              : 
     615              :      do
     616              : 
     617          125 :        if ( abs ( fc ) < abs ( fb ) ) then
     618              : 
     619           35 :          sa = sb
     620           35 :          sb = c
     621           35 :          c = sa
     622           35 :          fa = fb
     623           35 :          fb = fc
     624           35 :          fc = fa
     625              : 
     626              :        end if
     627              : 
     628          125 :        tol = 2.0D+00 * machep * abs ( sb ) + t
     629          125 :        m = 0.5D+00 * ( c - sb )
     630              : 
     631          125 :        if ( abs ( m ) <= tol .or. fb == 0.0D+00 ) then
     632              :          exit
     633              :        end if
     634              : 
     635          118 :        if ( abs ( e ) < tol .or. abs ( fa ) <= abs ( fb ) ) then
     636              : 
     637              :          e = m
     638              :          d = e
     639              : 
     640              :        else
     641              : 
     642          115 :          s = fb / fa
     643              : 
     644          115 :          if ( sa == c ) then
     645              : 
     646           53 :            p = 2.0D+00 * m * s
     647           53 :            q = 1.0D+00 - s
     648              : 
     649              :          else
     650              : 
     651           62 :            q = fa / fc
     652           62 :            r = fb / fc
     653           62 :            p = s * ( 2.0D+00 * m * a * ( q - r ) - ( sb - sa ) * ( r - 1.0D+00 ) )
     654           62 :            q = ( q - 1.0D+00 ) * ( r - 1.0D+00 ) * ( s - 1.0D+00 )
     655              : 
     656              :          end if
     657              : 
     658          115 :          if ( 0.0D+00 < p ) then
     659           48 :            q = - q
     660              :          else
     661           67 :            p = - p
     662              :          end if
     663              : 
     664          115 :          s = e
     665          115 :          e = d
     666              : 
     667          115 :          if ( 2.0D+00 * p < 3.0D+00 * m * q - abs ( tol * q ) .and. &
     668              :            p < abs ( 0.5D+00 * s * q ) ) then
     669           97 :            d = p / q
     670              :          else
     671              :            e = m
     672              :            d = e
     673              :          end if
     674              : 
     675              :        end if
     676              : 
     677          118 :        sa = sb
     678          118 :        fa = fb
     679              : 
     680          118 :        if ( tol < abs ( d ) ) then
     681          112 :          sb = sb + d
     682            6 :        else if ( 0.0D+00 < m ) then
     683            3 :          sb = sb + tol
     684              :        else
     685            3 :          sb = sb - tol
     686              :        end if
     687              : 
     688          118 :        fb = f ( sb, dfdx, lrpar, rpar, lipar, ipar, ierr )
     689          118 :        if (ierr /= 0) return
     690          118 :        if (abs(fb) < epsy) exit
     691              : 
     692          115 :        if ( ( 0.0D+00 < fb .and. 0.0D+00 < fc ) .or. &
     693           10 :             ( fb <= 0.0D+00 .and. fc <= 0.0D+00 ) ) then
     694           50 :          c = sa
     695           50 :          fc = fa
     696           50 :          e = sb - sa
     697           50 :          d = e
     698              :        end if
     699              : 
     700              :      end do
     701              : 
     702           10 :      eval_brent_safe_zero = sb
     703              : 
     704           10 :      return
     705              :    end function eval_brent_safe_zero
     706              : 
     707              :    end module mod_brent
        

Generated by: LCOV version 2.0-1