# Path: nlp/ls/linesearch.py
# class LineSearch(object):
# class ArmijoLineSearch(LineSearch):
# class ArmijoWolfeLineSearch(ArmijoLineSearch):
#     def __init__(self, linemodel, name="Generic Linesearch", **kwargs):
#     def linemodel(self):
#     def name(self):
#     def value(self):
#     def step(self):
#     def stepmin(self):
#     def trial_value(self):
#     def iterate(self):
#     def slope(self):
#     def check_slope(self, slope):
#     def __iter__(self):
#     def __next__(self):
#     def next(self):
#     def __init__(self, *args, **kwargs):
#     def ftol(self):
#     def bkmax(self):
#     def decr(self):
#     def bk(self):
#     def next(self):
#     def __init__(self, *args, **kwargs):
#     def gtol(self):
#     def wmax(self):
#     def incr(self):
#     def trial_slope(self):
#     def next(self):


from math import sqrt
from nlp.ls.linesearch import LineSearch, LineSearchFailure
from nlp.ls._strong_wolfe_linesearch import dcsrch
import numpy as np
            :lb: initial lower bound of the bracket
            :ub: initial upper bound of the bracket
        """
        name = kwargs.pop("name", "Strong Wolfe linesearch")
        super(StrongWolfeLineSearch, self).__init__(*args, name=name, **kwargs)
        sqeps = sqrt(np.finfo(np.double).eps)
        self.__ftol = max(min(kwargs.get("ftol", 1.0e-4),
                              1 - sqeps),
                          sqeps)
        self.__gtol = min(max(kwargs.get("gtol", 0.9),
                              self.ftol + sqeps),
                          1 - sqeps)
        self.__xtol = kwargs.get("xtol", 1.0e-10)
        self._lb = kwargs.get("lb", 0.0)
        self._ub = kwargs.get("ub",
                              max(4 * min(self.step, 1.0),
                                  -0.1 * self.value / self.slope / self.ftol))

        self._trial_slope = self.linemodel.grad(self.step, x=self.iterate)
        self.__task = "START"
        self.__isave = np.empty(2, dtype=np.int32)
        self.__dsave = np.empty(13, dtype=np.double)

        self._step, self.__task, self.__isave, self.__dsave = \
            dcsrch(self._step, self._value, self._slope,
                   self.ftol, self.gtol, self.xtol,
                   self.__task, self.lb, self.ub,
                   self.__isave, self.__dsave)

        if self.__task[:2] != "FG":

# Path: nlp/ls/linesearch.py
# class LineSearch(object):
# class ArmijoLineSearch(LineSearch):
# class ArmijoWolfeLineSearch(ArmijoLineSearch):
#     def __init__(self, linemodel, name="Generic Linesearch", **kwargs):
#     def linemodel(self):
#     def name(self):
#     def value(self):
#     def step(self):
#     def stepmin(self):
#     def trial_value(self):
#     def iterate(self):
#     def slope(self):
#     def check_slope(self, slope):
#     def __iter__(self):
#     def __next__(self):
#     def next(self):
#     def __init__(self, *args, **kwargs):
#     def ftol(self):
#     def bkmax(self):
#     def decr(self):
#     def bk(self):
#     def next(self):
#     def __init__(self, *args, **kwargs):
#     def gtol(self):
#     def wmax(self):
#     def incr(self):
#     def trial_slope(self):
#     def next(self):


# Path: nlp/ls/wolfe.py
from math import sqrt
from nlp.ls.linesearch import LineSearch, LineSearchFailure
from nlp.ls._strong_wolfe_linesearch import dcsrch
import numpy as np

            :lb: initial lower bound of the bracket
            :ub: initial upper bound of the bracket
        """
        name = kwargs.pop("name", "Strong Wolfe linesearch")
        super(StrongWolfeLineSearch, self).__init__(*args, name=name, **kwargs)
        sqeps = sqrt(np.finfo(np.double).eps)
        self.__ftol = max(min(kwargs.get("ftol", 1.0e-4),
                              1 - sqeps),
                          sqeps)
        self.__gtol = min(max(kwargs.get("gtol", 0.9),
                              self.ftol + sqeps),
                          1 - sqeps)
        self.__xtol = kwargs.get("xtol", 1.0e-10)
        self._lb = kwargs.get("lb", 0.0)
        self._ub = kwargs.get("ub",
                              max(4 * min(self.step, 1.0),
                                  -0.1 * self.value / self.slope / self.ftol))

        self._trial_slope = self.linemodel.grad(self.step, x=self.iterate)
        self.__task = "START"
        self.__isave = np.empty(2, dtype=np.int32)
        self.__dsave = np.empty(13, dtype=np.double)

        self._step, self.__task, self.__isave, self.__dsave = \
            dcsrch(self._step, self._value, self._slope,
                   self.ftol, self.gtol, self.xtol,
                   self.__task, self.lb, self.ub,
                   self.__isave, self.__dsave)

        if self.__task[:2] != "FG":

            raise LineSearchFailure(self.__task)