bracket Subroutine

subroutine bracket(ax, bx, cx, fa, fb, fc, func)

Arguments

Type IntentOptional Attributes Name
real(kind=8), intent(inout) :: ax
real(kind=8), intent(inout) :: bx
real(kind=8), intent(out) :: cx
real(kind=8), intent(out) :: fa
real(kind=8), intent(out) :: fb
real(kind=8), intent(out) :: fc
function func(x)
Arguments
Type IntentOptional Attributes Name
real(kind=8) :: x
Return Value real(kind=8)

Source Code

subroutine bracket(ax,bx,cx,fa,fb,fc,func)
  real(8), intent(inout) :: ax,bx
  real(8), intent(out) :: cx,fa,fb,fc
  !...the first parameter is the default ratio by which successive intervals
  !   are magnified; the second is the maximum magnification allowed for a
  !   parabolic-fit step
  real(8), parameter :: gold=1.618034d0,glimit=100.d0,tiny=1.d-20
  real(8) :: fu,q,r,u,ulim
  interface
     function func(x)
       real(8) :: x
       real(8) :: func
     end function func
  end interface
  fa=func(ax)
  fb=func(bx)
  if (fb > fa) then
     call swap(ax,bx)
     call swap(fa,fb)
  end if
  cx=bx+GOLD*(bx-ax)
  fc=func(cx)
  do
     if (fb < fc) RETURN
     r=(bx-ax)*(fb-fc)
     q=(bx-cx)*(fb-fa)
     u=bx-((bx-cx)*q-(bx-ax)*r)/(2.0*sign(max(abs(q-r),TINY),q-r))
     ulim=bx+GLIMIT*(cx-bx)
     if ((bx-u)*(u-cx) > 0.d0) then
        fu=func(u)
        if (fu < fc) then
           ax=bx
           fa=fb
           bx=u
           fb=fu
           RETURN
        else if (fu > fb) then
           cx=u
           fc=fu
           RETURN
        end if
        u=cx+GOLD*(cx-bx)
        fu=func(u)
     else if ((cx-u)*(u-ulim) > 0.d0) then
        fu=func(u)
        if (fu < fc) then
           bx=cx
           cx=u
           u=cx+GOLD*(cx-bx)
           call shft(fb,fc,fu,func(u))
        end if
     else if ((u-ulim)*(ulim-cx) >= 0.d0) then
        u=ulim
        fu=func(u)
     else
        u=cx+GOLD*(cx-bx)
        fu=func(u)
     end if
     call shft(ax,bx,cx,u)
     call shft(fa,fb,fc,fu)
  end do
contains
  subroutine swap(a,b)
    real(8), intent(inout) :: a,b
    real(8) :: dum
    dum=a
    a=b
    b=dum
  end subroutine swap
  !-------------------
  subroutine shft(a,b,c,d)
    real(8), intent(out) :: a
    real(8), intent(inout) :: b,c
    real(8), intent(in) :: d
    a=b
    b=c
    c=d
  end subroutine shft
end subroutine bracket