newton Subroutine

public subroutine newton(x, f, dfdx, ftol, xtol, max_iter, xs, fx, iflag)

Newton's method for root finding of scalar function f(x)

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: x

initial point (initial guess)

procedure(func) :: f

function f(x)

procedure(func) :: dfdx

first derivative function f'(x)

real(kind=wp), intent(in) :: ftol

convergence tolerance for f(x)

real(kind=wp), intent(in) :: xtol

convergence tolerance for x

integer, intent(in) :: max_iter

the maximum number of iterations

real(kind=wp), intent(out) :: xs

the value where f(x) is zero

real(kind=wp), intent(out) :: fx

the value of f(x) at the root xs

integer, intent(out) :: iflag

status flag: 0 : absolute convergence in f 1 : relative convergence in x -1 : Error: derivative is zero -2 : Error: max iterations exceeded


Called by

proc~~newton~~CalledByGraph proc~newton newton_module::newton proc~kepler_classical kepler_module::kepler_classical proc~kepler_classical->proc~newton

Source Code

    subroutine newton(x,f,dfdx,ftol,xtol,max_iter,xs,fx,iflag)

    implicit none

    real(wp),intent(in)    :: x         !! initial point (initial guess)
    procedure(func)        :: f         !! function f(x)
    procedure(func)        :: dfdx      !! first derivative function f'(x)
    real(wp),intent(in)    :: ftol      !! convergence tolerance for f(x)
    real(wp),intent(in)    :: xtol      !! convergence tolerance for x
    integer,intent(in)     :: max_iter  !! the maximum number of iterations
    real(wp),intent(out)   :: xs        !! the value where f(x) is zero
    real(wp),intent(out)   :: fx        !! the value of f(x) at the root xs
    integer,intent(out)    :: iflag     !! status flag:
                                        !!  0 : absolute convergence in f
                                        !!  1 : relative convergence in x
                                        !! -1 : Error: derivative is zero
                                        !! -2 : Error: max iterations exceeded

    real(wp)  :: f1,df1,x1,x1_prev
    integer   :: iter
    real(wp),parameter :: alpha = one !! step factor

    x1 = x

    do iter = 1,max_iter

        call f(x1, f1)
        if (abs(f1)<=ftol) then
            iflag = 0
            exit
        end if

        call dfdx(x1, df1)
        if (df1==zero) then
            iflag = -1
            exit
        end if

        x1_prev = x1
        x1 = x1 - alpha * ( f1 / df1 )

        if (abs(x1_prev-x1)<=xtol) then
            iflag = 1
            exit
        end if

    end do

    ! max iterations exceeded
    if (iter>max_iter) iflag = -2

    !return results:
    xs  = x1
    fx  = f1

    end subroutine newton