subroutine bisection_rc ( a, b, x, fx, job ) !*****************************************************************************80 ! !! bisection_rc() seeks a zero of f(x) in a change of sign interval. ! ! Discussion: ! ! The bisection method is used. ! ! This routine uses reverse communication, so that the function is always ! evaluated in the calling program. ! ! On the first call, the user sets JOB = 0, and the values of A and B. ! Thereafter, the user checks the returned value of JOB and follows ! directions. ! ! Licensing: ! ! This code is distributed under the MIT license. ! ! Modified: ! ! 03 September 2021 ! ! Author: ! ! John Burkardt ! ! Input: ! ! real ( kind = rk ) A, B: the change of sign interval. ! ! real ( kind = rk ) FX: ! on first call, with JOB = 0, a value of FX is not needed. ! Thereafter, FX should be set to f(x), where x is output of previous call. ! ! integer JOB: set to 0 on first call, to request initialization. ! ! Output: ! ! real ( kind = rk ) A, B: the updated change of sign interval. ! ! real ( kind = rk ) X: the next point at which a function value is needed. ! ! integer JOB: reset to 1, indicating that initialization was completed. ! implicit none integer, parameter :: rk = kind ( 1.0D+00 ) real ( kind = rk ) a real ( kind = rk ) b real ( kind = rk ), save :: fa real ( kind = rk ), save :: fb real ( kind = rk ) fx integer job integer, save :: state real ( kind = rk ) x ! ! Initialize. ! Accept value of a. ! Request value of f(a). ! if ( job == 0 ) then fa = 0.0D+00 fb = 0.0D+00 state = 1 x = a job = 1 ! ! Accept value of f(a). ! Request value of f(b). ! else if ( state == 1 ) then if ( fx == 0.0 ) then b = a state = 3 return end if fa = fx x = b state = 2 ! ! Accept value of f(b). ! Request value of f at midpoint. ! else if ( state == 2 ) then if ( fx == 0.0 ) then a = b state = 3 return end if fb = fx if ( 0.0 < fa * fb ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'bisection_rc(): Fatal error!' write ( *, '(a)' ) ' f(a) and f(b) have the same sign.' stop ( 1 ) end if x = ( a + b ) / 2.0D+00 state = 3 ! ! Use sign of function value to bisect current interval. ! Determine new midpoint and request function value. ! else if ( fx == 0.0 ) then a = x b = x return end if if ( 0.0 < fx * fa ) then a = x fa = fx else b = x fb = fx end if x = ( a + b ) / 2.0D+00 state = 3 end if return end