a
    ‡ù»jn  ã                	   @   sÊ   d Z ddlmZ ddlmZ ddlmZ ddlZ	g d¢Z
G dd	„ d	eƒZd
d„ Zd.dd„Zd/dd„ZeZd0dd„Zd1dd„Zdd„ Zdd„ Zdd „ Zd2d!d"„Zd3d#d$„Zd4d%d&„Zd5d)d*„Zd6d,d-„ZdS )7z·
Functions
---------
.. autosummary::
   :toctree: generated/

    line_search_armijo
    line_search_wolfe1
    line_search_wolfe2
    scalar_search_wolfe1
    scalar_search_wolfe2

é    )Úwarn)Ú	_minpack2é   )ÚDCSRCHN)ÚLineSearchWarningÚline_search_wolfe1Úline_search_wolfe2Úscalar_search_wolfe1Úscalar_search_wolfe2Úline_search_armijoc                   @   s   e Zd ZdS )r   N)Ú__name__Ú
__module__Ú__qualname__© r   r   ú@E:\soccer\ml_env\Lib\site-packages\scipy/optimize/_linesearch.pyr      s   r   c                 C   s,   d|   k r|  k rdk s(n t dƒ‚d S )Nr   r   z.'c1' and 'c2' do not satisfy'0 < c1 < c2 < 1'.)Ú
ValueError)Úc1Úc2r   r   r   Ú_check_c1_c2   s     r   r   ç-Cëâ6?çÍÌÌÌÌÌì?é2   ç:Œ0âŽyE>ç›+¡†›„=c                    sž   |du rˆˆgˆ ¢R Ž }|g‰dg‰dg‰‡ ‡‡‡‡fdd„}‡ ‡‡‡‡‡fdd„}t  |ˆ¡}t|||||||	|
||d�
\}}}|ˆd ˆd ||ˆd fS )a1  
    As `scalar_search_wolfe1` but do a line search to direction `pk`

    Parameters
    ----------
    f : callable
        Function `f(x)`
    fprime : callable
        Gradient of `f`
    xk : array_like
        Current point
    pk : array_like
        Search direction
    gfk : array_like, optional
        Gradient of `f` at point `xk`
    old_fval : float, optional
        Value of `f` at point `xk`
    old_old_fval : float, optional
        Value of `f` at point preceding `xk`

    The rest of the parameters are the same as for `scalar_search_wolfe1`.

    Returns
    -------
    stp, f_count, g_count, fval, old_fval
        As in `line_search_wolfe1`
    gval : array
        Gradient of `f` at the final point

    Notes
    -----
    Parameters `c1` and `c2` must satisfy ``0 < c1 < c2 < 1``.

    Nr   c                    s(   ˆd  d7  < ˆˆ| ˆ  gˆ ¢R Ž S ©Nr   r   r   ©Ús©ÚargsÚfÚfcÚpkÚxkr   r   ÚphiS   s    zline_search_wolfe1.<locals>.phic                    s<   ˆˆ| ˆ  gˆ ¢R Ž ˆd< ˆd  d7  < t  ˆd ˆ¡S r   ©ÚnpÚdotr   )r   ÚfprimeÚgcÚgvalr!   r"   r   r   ÚderphiW   s    z"line_search_wolfe1.<locals>.derphi)r   r   ÚamaxÚaminÚxtol)r%   r&   r	   )r   r'   r"   r!   ÚgfkÚold_fvalÚold_old_fvalr   r   r   r+   r,   r-   r#   r*   Úderphi0ÚstpZfvalr   )r   r   r    r'   r(   r)   r!   r"   r   r   &   s    &

þr   c
                 C   sœ   t ||ƒ |du r| dƒ}|du r*|dƒ}|dur^|dkr^tdd||  | ƒ}
|
dk rbd}
nd}
d}t| ||||	||ƒ}||
|||d�\}}}}|||fS )a   
    Scalar function search for alpha that satisfies strong Wolfe conditions

    alpha > 0 is assumed to be a descent direction.

    Parameters
    ----------
    phi : callable phi(alpha)
        Function at point `alpha`
    derphi : callable phi'(alpha)
        Objective function derivative. Returns a scalar.
    phi0 : float, optional
        Value of phi at 0
    old_phi0 : float, optional
        Value of phi at previous point
    derphi0 : float, optional
        Value derphi at 0
    c1 : float, optional
        Parameter for Armijo condition rule.
    c2 : float, optional
        Parameter for curvature condition rule.
    amax, amin : float, optional
        Maximum and minimum step size
    xtol : float, optional
        Relative tolerance for an acceptable step.

    Returns
    -------
    alpha : float
        Step size, or None if no suitable step was found
    phi : float
        Value of `phi` at the new point `alpha`
    phi0 : float
        Value of `phi` at `alpha=0`

    Notes
    -----
    Uses routine DCSRCH from MINPACK.
    
    Parameters `c1` and `c2` must satisfy ``0 < c1 < c2 < 1`` as described in [1]_.

    References
    ----------
    
    .. [1] Nocedal, J., & Wright, S. J. (2006). Numerical optimization.
       In Springer Series in Operations Research and Financial Engineering.
       (Springer Series in Operations Research and Financial Engineering).
       Springer Nature.

    Nç        r   ç      ð?ç)\�Âõ( @éd   )Úphi0r1   Úmaxiter)r   Úminr   )r#   r*   r7   Úold_phi0r1   r   r   r+   r,   r-   Úalpha1r8   Zdcsrchr2   Úphi1Útaskr   r   r   r	   e   s     5
ÿr	   é
   c                    sì   dg‰dg‰dg‰dg‰‡ ‡‡‡	‡
fdd„}|‰‡ ‡‡‡‡‡	‡
fdd„‰|du r`ˆˆ
gˆ ¢R Ž }t  |ˆ	¡}ˆdurŒ‡‡‡‡‡	‡
fdd„}nd}t|ˆ|||||	|
||d	�
\}}}}|du rÌtd
tdd� nˆd }|ˆd ˆd |||fS )a  Find alpha that satisfies strong Wolfe conditions.

    Parameters
    ----------
    f : callable f(x,*args)
        Objective function.
    myfprime : callable f'(x,*args)
        Objective function gradient.
    xk : ndarray
        Starting point.
    pk : ndarray
        Search direction. The search direction must be a descent direction
        for the algorithm to converge.
    gfk : ndarray, optional
        Gradient value for x=xk (xk being the current parameter
        estimate). Will be recomputed if omitted.
    old_fval : float, optional
        Function value for x=xk. Will be recomputed if omitted.
    old_old_fval : float, optional
        Function value for the point preceding x=xk.
    args : tuple, optional
        Additional arguments passed to objective function.
    c1 : float, optional
        Parameter for Armijo condition rule.
    c2 : float, optional
        Parameter for curvature condition rule.
    amax : float, optional
        Maximum step size
    extra_condition : callable, optional
        A callable of the form ``extra_condition(alpha, x, f, g)``
        returning a boolean. Arguments are the proposed step ``alpha``
        and the corresponding ``x``, ``f`` and ``g`` values. The line search
        accepts the value of ``alpha`` only if this
        callable returns ``True``. If the callable returns ``False``
        for the step length, the algorithm will continue with
        new iterates. The callable is only called for iterates
        satisfying the strong Wolfe conditions.
    maxiter : int, optional
        Maximum number of iterations to perform.

    Returns
    -------
    alpha : float or None
        Alpha for which ``x_new = x0 + alpha * pk``,
        or None if the line search algorithm did not converge.
    fc : int
        Number of function evaluations made.
    gc : int
        Number of gradient evaluations made.
    new_fval : float or None
        New function value ``f(x_new)=f(x0+alpha*pk)``,
        or None if the line search algorithm did not converge.
    old_fval : float
        Old function value ``f(x0)``.
    new_slope : float or None
        The local slope along the search direction at the
        new value ``<myfprime(x_new), pk>``,
        or None if the line search algorithm did not converge.


    Notes
    -----
    Uses the line search algorithm to enforce strong Wolfe
    conditions. See Wright and Nocedal, 'Numerical Optimization',
    1999, pp. 59-61.

    The search direction `pk` must be a descent direction (e.g.
    ``-myfprime(xk)``) to find a step length that satisfies the strong Wolfe
    conditions. If the search direction is not a descent direction (e.g.
    ``myfprime(xk)``), then `alpha`, `new_fval`, and `new_slope` will be None.

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.optimize import line_search

    A objective function and its gradient are defined.

    >>> def obj_func(x):
    ...     return (x[0])**2+(x[1])**2
    >>> def obj_grad(x):
    ...     return [2*x[0], 2*x[1]]

    We can find alpha that satisfies strong Wolfe conditions.

    >>> start_point = np.array([1.8, 1.7])
    >>> search_gradient = np.array([-1.0, -1.0])
    >>> line_search(obj_func, obj_grad, start_point, search_gradient)
    (1.0, 2, 1, 1.1300000000000001, 6.13, [1.6, 1.4])

    r   Nc                    s(   ˆd  d7  < ˆˆ| ˆ  gˆ ¢R Ž S r   r   ©Úalphar   r   r   r#     s    zline_search_wolfe2.<locals>.phic                    sD   ˆd  d7  < ˆˆ| ˆ  gˆ ¢R Ž ˆd< | ˆd< t  ˆd ˆ¡S r   r$   r?   )r   r'   r(   r)   Ú
gval_alphar!   r"   r   r   r*   $  s    z"line_search_wolfe2.<locals>.derphic                    s2   ˆd | krˆ | ƒ ˆ| ˆ  }ˆ| ||ˆd ƒS )Nr   r   )r@   r#   Úx)r*   Úextra_conditionr)   rA   r!   r"   r   r   Úextra_condition21  s    z,line_search_wolfe2.<locals>.extra_condition2)r8   ú*The line search algorithm did not convergeé   ©Ú
stacklevel)r%   r&   r
   r   r   )r   Zmyfprimer"   r!   r.   r/   r0   r   r   r   r+   rC   r8   r#   r1   rD   Ú
alpha_starÚphi_starÚderphi_starr   )r   r*   rC   r   r    r'   r(   r)   rA   r!   r"   r   r   »   s.    ^þÿr   c
                 C   s  t ||ƒ |du r| dƒ}|du r*|dƒ}d}
|durV|dkrVtdd||  | ƒ}nd}|dk rfd}|durxt||ƒ}| |ƒ}|}|}|du r˜dd„ }t|	ƒD �]T}|dks¾|durü|
|krüd}|}|}d}|dkrÜd}nd	d
|  }t|tdd�  �q|dk}|||| |  k�s*||k�rT|�rTt|
||||| ||||||ƒ\}}} �q||ƒ}t|ƒ| | k�rŽ|||ƒ�rŽ|}|}|} �q|dk�rÂt||
|||| ||||||ƒ\}}} �qd| }|du�rÞt||ƒ}|}
|}|}| |ƒ}|}q |}|}d}tdtdd� ||||fS )a­  Find alpha that satisfies strong Wolfe conditions.

    alpha > 0 is assumed to be a descent direction.

    Parameters
    ----------
    phi : callable phi(alpha)
        Objective scalar function.
    derphi : callable phi'(alpha)
        Objective function derivative. Returns a scalar.
    phi0 : float, optional
        Value of phi at 0.
    old_phi0 : float, optional
        Value of phi at previous point.
    derphi0 : float, optional
        Value of derphi at 0
    c1 : float, optional
        Parameter for Armijo condition rule.
    c2 : float, optional
        Parameter for curvature condition rule.
    amax : float, optional
        Maximum step size.
    extra_condition : callable, optional
        A callable of the form ``extra_condition(alpha, phi_value)``
        returning a boolean. The line search accepts the value
        of ``alpha`` only if this callable returns ``True``.
        If the callable returns ``False`` for the step length,
        the algorithm will continue with new iterates.
        The callable is only called for iterates satisfying
        the strong Wolfe conditions.
    maxiter : int, optional
        Maximum number of iterations to perform.

    Returns
    -------
    alpha_star : float or None
        Best alpha, or None if the line search algorithm did not converge.
    phi_star : float
        phi at alpha_star.
    phi0 : float
        phi at 0.
    derphi_star : float or None
        derphi at alpha_star, or None if the line search algorithm
        did not converge.

    Notes
    -----
    Uses the line search algorithm to enforce strong Wolfe
    conditions. See Wright and Nocedal, 'Numerical Optimization',
    1999, pp. 59-61.

    Nr3   r   r4   r5   c                 S   s   dS )NTr   )r@   r#   r   r   r   rC   �  s    z-scalar_search_wolfe2.<locals>.extra_conditionz7Rounding errors prevent the line search from convergingz4The line search algorithm could not find a solution zless than or equal to amax: %srF   rG   rE   )r   r9   Úranger   r   Ú_zoomÚabs)r#   r*   r7   r:   r1   r   r   r+   rC   r8   Úalpha0r;   Úphi_a1Úphi_a0Z	derphi_a0ÚirI   rJ   rK   ÚmsgZnot_first_iterationZ	derphi_a1Úalpha2r   r   r   r
   J  s�    8

ÿÿÿ
þÿ

þÿ

ÿr
   c              
   C   sL  t jdddd��� zà|}||  }||  }	||	 d ||	  }
t  d¡}|	d |d< |d  |d< |	d  |d< |d |d	< t  |t  || ||  || ||	  g¡ ¡ ¡\}}||
 }||
 }|| d| |  }| | t  |¡ d|   }W n" t�y   Y W d
  ƒ d
S 0 W d
  ƒ n1 �s.0    Y  t  |¡�sHd
S |S )z¾
    Finds the minimizer for a cubic polynomial that goes through the
    points (a,fa), (b,fb), and (c,fc) with derivative at a of fpa.

    If no minimizer can be found, return None.

    Úraise©ÚdivideZoverÚinvalidrF   )rF   rF   )r   r   )r   r   é   )r   r   )r   r   N)	r%   ÚerrstateÚemptyr&   ZasarrayÚflattenÚsqrtÚArithmeticErrorÚisfinite)ÚaÚfaÚfpaÚbÚfbÚcr    ÚCÚdbZdcÚdenomZd1ÚAÚBÚradicalÚxminr   r   r   Ú	_cubicminÞ  s.    

ÿ 4rm   c           
   	   C   s¤   t jdddd��r z@|}|}|| d  }|| ||  ||  }| |d|   }	W n  tyr   Y W d  ƒ dS 0 W d  ƒ n1 sˆ0    Y  t  |	¡s dS |	S )z†
    Finds the minimizer for a quadratic polynomial that goes through
    the points (a,fa), (b,fb) with derivative at a of fpa.

    rU   rV   r4   ç       @N)r%   rZ   r^   r_   )
r`   ra   rb   rc   rd   ÚDrf   rg   rj   rl   r   r   r   Ú_quadmin   s    2
rp   c                 C   s¢  d}d}d}d}|}d}||  }|dk r4||  }}n
| | }}|dkrb|| }t | ||||||ƒ}|dksŠ|du sŠ||| ksŠ||| k rÎ|| }t| ||||ƒ}|du sÂ||| ksÂ||| k rÎ| d|  }||ƒ}|||	| |  ksô||k�r|}|}|}|}np||ƒ}t|ƒ|
 | k�r>|||ƒ�r>|}|}|}�q˜|||   dk�rb|}|}| }|}n|}| }|} |}|}|d7 }||krd}d}d}�q˜q|||fS )a  Zoom stage of approximate linesearch satisfying strong Wolfe conditions.

    Part of the optimization algorithm in `scalar_search_wolfe2`.

    Notes
    -----
    Implements Algorithm 3.6 (zoom) in Wright and Nocedal,
    'Numerical Optimization', 1999, pp. 61.

    r>   r   gš™™™™™É?çš™™™™™¹?Nç      à?r   )rm   rp   rN   )Za_loZa_hiZphi_loZphi_hiZ	derphi_lor#   r*   r7   r1   r   r   rC   r8   rR   Zdelta1Zdelta2Zphi_recZa_recZdalphar`   rc   ZcchkZa_jZqchkZphi_ajZ	derphi_ajZa_starZval_starZvalprime_starr   r   r   rM     sb    	

ÿ(  rM   c                    sj   t  ˆ¡‰dg‰‡ ‡‡‡‡fdd„}|du r6|dƒ}	n|}	t  |ˆ¡}
t||	|
||d�\}}|ˆd |fS )a  Minimize over alpha, the function ``f(xk+alpha pk)``.

    Parameters
    ----------
    f : callable
        Function to be minimized.
    xk : array_like
        Current point.
    pk : array_like
        Search direction.
    gfk : array_like
        Gradient of `f` at point `xk`.
    old_fval : float
        Value of `f` at point `xk`.
    args : tuple, optional
        Optional arguments.
    c1 : float, optional
        Value to control stopping criterion.
    alpha0 : scalar, optional
        Value of `alpha` at start of the optimization.

    Returns
    -------
    alpha
    f_count
    f_val_at_alpha

    Notes
    -----
    Uses the interpolation algorithm (Armijo backtracking) as suggested by
    Wright and Nocedal in 'Numerical Optimization', 1999, pp. 56-57

    r   c                    s(   ˆd  d7  < ˆˆ| ˆ  gˆ ¢R Ž S r   r   )r;   r   r   r   r#   •  s    zline_search_armijo.<locals>.phiNr3   )r   rO   )r%   Z
atleast_1dr&   Úscalar_search_armijo)r   r"   r!   r.   r/   r   r   rO   r#   r7   r1   r@   r<   r   r   r   r   p  s    "


ÿ
r   c           	   
   C   s0   t | |||||||d�}|d |d d|d fS )z8
    Compatibility wrapper for `line_search_armijo`
    )r   r   rO   r   r   rF   )r   )	r   r"   r!   r.   r/   r   r   rO   Úrr   r   r   Úline_search_BFGS¤  s    ÿru   c                 C   s–  | |ƒ}|||| |  kr$||fS | |d  d || ||   }| |ƒ}|||| |  krj||fS ||k�rŽ|d |d  ||  }	|d || ||   |d || ||    }
|
|	 }
|d  || ||   |d || ||    }||	 }| t  t|d d|
 |  ƒ¡ d|
  }| |ƒ}|||| |  k�rP||fS || |d k�std||  dk �r||d }|}|}|}|}qjd|fS )a(  Minimize over alpha, the function ``phi(alpha)``.

    Uses the interpolation algorithm (Armijo backtracking) as suggested by
    Wright and Nocedal in 'Numerical Optimization', 1999, pp. 56-57

    alpha > 0 is assumed to be a descent direction.

    Returns
    -------
    alpha
    phi1

    rF   rn   rY   g      @r   g¸…ëQ¸î?N)r%   r]   rN   )r#   r7   r1   r   rO   r,   rQ   r;   rP   Úfactorr`   rc   rT   Zphi_a2r   r   r   rs   ­  s8    "
ÿÿ,$rs   rq   rr   c                 C   s  |d }t |ƒ}	d}
d}d}||
|  }| |ƒ\}}||	| ||
d  |  krX|
}�q|
d | |d|
 d |   }|||  }| |ƒ\}}||	| ||d  |  kr¶| }�q|d | |d| d |   }t |||
 ||
 ¡}
t ||| || ¡}q||||fS )a@  
    Nonmonotone backtracking line search as described in [1]_

    Parameters
    ----------
    f : callable
        Function returning a tuple ``(f, F)`` where ``f`` is the value
        of a merit function and ``F`` the residual.
    x_k : ndarray
        Initial position.
    d : ndarray
        Search direction.
    prev_fs : float
        List of previous merit function values. Should have ``len(prev_fs) <= M``
        where ``M`` is the nonmonotonicity window parameter.
    eta : float
        Allowed merit function increase, see [1]_
    gamma, tau_min, tau_max : float, optional
        Search parameters, see [1]_

    Returns
    -------
    alpha : float
        Step length
    xp : ndarray
        Next position
    fp : float
        Merit function value at next position
    Fp : ndarray
        Residual at next position

    References
    ----------
    [1] "Spectral residual method without gradient information for solving
        large-scale nonlinear systems of equations." W. La Cruz,
        J.M. Martinez, M. Raydan. Math. Comp. **75**, 1429 (2006).

    éÿÿÿÿr   rF   )Úmaxr%   Úclip)r   Úx_kÚdZprev_fsÚetaÚgammaÚtau_minÚtau_maxÚf_kZf_barÚalpha_pÚalpha_mr@   ÚxpÚfpÚFpÚalpha_tpÚalpha_tmr   r   r   Ú_nonmonotone_line_search_cruzë  s(    (  rˆ   ç333333ë?c                 C   s(  d}d}d}|||  }| |ƒ\}}||| ||d  |  krF|}qð|d | |d| d |   }|||  }| |ƒ\}}||| ||d  |  kr¢| }qð|d | |d| d |   }t  ||| |	| ¡}t  ||| |	| ¡}q|
| d }|
| ||  | | }|}||||||fS )aŠ  
    Nonmonotone line search from [1]

    Parameters
    ----------
    f : callable
        Function returning a tuple ``(f, F)`` where ``f`` is the value
        of a merit function and ``F`` the residual.
    x_k : ndarray
        Initial position.
    d : ndarray
        Search direction.
    f_k : float
        Initial merit function value.
    C, Q : float
        Control parameters. On the first iteration, give values
        Q=1.0, C=f_k
    eta : float
        Allowed merit function increase, see [1]_
    nu, gamma, tau_min, tau_max : float, optional
        Search parameters, see [1]_

    Returns
    -------
    alpha : float
        Step length
    xp : ndarray
        Next position
    fp : float
        Merit function value at next position
    Fp : ndarray
        Residual at next position
    C : float
        New value for the control parameter C
    Q : float
        New value for the control parameter Q

    References
    ----------
    .. [1] W. Cheng & D.-H. Li, ''A derivative-free nonmonotone line
           search and its application to the spectral residual
           method'', IMA J. Numer. Anal. 29, 814 (2009).

    r   rF   )r%   ry   )r   rz   r{   r€   rf   ÚQr|   r}   r~   r   Únur�   r‚   r@   rƒ   r„   r…   r†   r‡   ZQ_nextr   r   r   Ú_nonmonotone_line_search_cheng3  s*    /  rŒ   )	NNNr   r   r   r   r   r   )NNNr   r   r   r   r   )	NNNr   r   r   NNr>   )NNNr   r   NNr>   )r   r   r   )r   r   r   )r   r   r   )r   rq   rr   )r   rq   rr   r‰   )Ú__doc__Úwarningsr   Zscipy.optimizer   Zminpack2Z_dcsrchr   Únumpyr%   Ú__all__ÚRuntimeWarningr   r   r   r	   Zline_searchr   r
   rm   rp   rM   r   ru   rs   rˆ   rŒ   r   r   r   r   Ú<module>   sN   
    ý
?   þ
M	   þ
     ý
 "[
4
	
? ÿ
I  þ