exact_linesearch Subroutine

private subroutine exact_linesearch(me, xold, p, x, f, fvec, fjac, fjac_sparse)

An exact linesearch that uses a derivative-free minimizer to find the minimum value of f(x) between x = xold + p * alpha_min and x = xold + p * alpha_max.

Usually this is overkill and not necessary, but is here as an option for testing.

Arguments

Type IntentOptional Attributes Name
class(nlesolver_type), intent(inout) :: me
real(kind=wp), intent(in), dimension(me%n) :: xold

previous value of x

real(kind=wp), intent(in), dimension(me%n) :: p

search direction

real(kind=wp), intent(out), dimension(me%n) :: x

new x

real(kind=wp), intent(inout) :: f

magnitude of fvec

real(kind=wp), intent(inout), dimension(me%m) :: fvec

function vector

real(kind=wp), intent(in), optional, dimension(:,:) :: fjac

jacobian matrix [dense]

real(kind=wp), intent(in), optional, dimension(:) :: fjac_sparse

jacobian matrix [sparse]


Calls

proc~~exact_linesearch~~CallsGraph proc~exact_linesearch nlesolver_module::exact_linesearch fmin fmin proc~exact_linesearch->fmin

Source Code

    subroutine exact_linesearch(me,xold,p,x,f,fvec,fjac,fjac_sparse)

    implicit none

    class(nlesolver_type),intent(inout) :: me
    real(wp),dimension(me%n),intent(in) :: xold      !! previous value of `x`
    real(wp),dimension(me%n),intent(in) :: p         !! search direction
    real(wp),dimension(me%n),intent(out) :: x        !! new `x`
    real(wp),intent(inout) :: f                      !! magnitude of `fvec`
    real(wp),dimension(me%m),intent(inout) :: fvec   !! function vector
    real(wp),dimension(:,:),intent(in),optional :: fjac !! jacobian matrix [dense]
    real(wp),dimension(:),intent(in),optional :: fjac_sparse !! jacobian matrix [sparse]

    real(wp),dimension(:),allocatable :: xnew !! used in [[func_for_fmin]]
    real(wp) :: alpha_min

    allocate(xnew(me%n))

    ! find the minimum value of f in the range of alphas:
    alpha_min = fmin(func_for_fmin,me%alpha_min,me%alpha_max,me%fmin_tol)

    if (me%verbose) write(me%iunit,'(1P,*(A,1X,E16.6))') '        alpha_min = ', alpha_min

    x = xold + p * alpha_min
    if (all(x==xnew)) then
        ! already computed in the func
    else
        call me%func(x,fvec)
        f = norm2(fvec)
    end if

contains

    real(wp) function func_for_fmin(alpha)
    !! function for [[fmin]]
    implicit none
    real(wp),intent(in) :: alpha !! indep variable

    xnew = xold + p * alpha
    call me%func(xnew,fvec)
    func_for_fmin = norm2(fvec) ! return result

    f = func_for_fmin ! just in case this is the solution

    end function func_for_fmin

    end subroutine exact_linesearch