def METHOD_NAME(x: NDArray, s: Float, d: NDArray,
            fun: ObjFunc, alpha_0: Float, alpha_1: Float, f0: Float,
            fl: Float, c1: float, c2: float) -> Tuple[Float, NDArray, np.floating, NDArray]:
    """
    @brief
    @return alpha, xc, fc, gc
    """
    iter_ = 0
    while iter_ < 20:
        alpha = (alpha_0 + alpha_1)/2
        xc = x + alpha*d
        fc, gc = fun(xc)
        if (fc > f0 + c1*alpha*s)\
        or (fc >= fl):
            alpha_1 = alpha
        else:
            sc = np.sum(gc*d)
            if np.abs(sc) <= -c2*s:
                return alpha, xc, fc, gc
            if sc*(alpha_1 - alpha_0) >= 0:
                alpha_0, alpha_1 = alpha, alpha_0
                fl = fc
        iter_ += 1
    return alpha, xc, fc, gc