U
    Gvf¿X  ã                   @   s~   d dl Zd dlmZ ddlmZmZ ddlm	Z	 d dl
mZ dZG dd„ dƒZG d	d
„ d
ƒZG dd„ dƒZG dd„ deƒZdS )é    Né   )Úapprox_derivativeÚgroup_columns)ÚHessianUpdateStrategy)ÚLinearOperator)z2-pointz3-pointÚcsc                   @   sR   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚScalarFunctiona©  Scalar function and its derivatives.

    This class defines a scalar function F: R^n->R and methods for
    computing or approximating its first and second derivatives.

    Parameters
    ----------
    fun : callable
        evaluates the scalar function. Must be of the form ``fun(x, *args)``,
        where ``x`` is the argument in the form of a 1-D array and ``args`` is
        a tuple of any additional fixed parameters needed to completely specify
        the function. Should return a scalar.
    x0 : array-like
        Provides an initial set of variables for evaluating fun. Array of real
        elements of size (n,), where 'n' is the number of independent
        variables.
    args : tuple, optional
        Any additional fixed parameters needed to completely specify the scalar
        function.
    grad : {callable, '2-point', '3-point', 'cs'}
        Method for computing the gradient vector.
        If it is a callable, it should be a function that returns the gradient
        vector:

            ``grad(x, *args) -> array_like, shape (n,)``

        where ``x`` is an array with shape (n,) and ``args`` is a tuple with
        the fixed parameters.
        Alternatively, the keywords  {'2-point', '3-point', 'cs'} can be used
        to select a finite difference scheme for numerical estimation of the
        gradient with a relative step size. These finite difference schemes
        obey any specified `bounds`.
    hess : {callable, '2-point', '3-point', 'cs', HessianUpdateStrategy}
        Method for computing the Hessian matrix. If it is callable, it should
        return the  Hessian matrix:

            ``hess(x, *args) -> {LinearOperator, spmatrix, array}, (n, n)``

        where x is a (n,) ndarray and `args` is a tuple with the fixed
        parameters. Alternatively, the keywords {'2-point', '3-point', 'cs'}
        select a finite difference scheme for numerical estimation. Or, objects
        implementing `HessianUpdateStrategy` interface can be used to
        approximate the Hessian.
        Whenever the gradient is estimated via finite-differences, the Hessian
        cannot be estimated with options {'2-point', '3-point', 'cs'} and needs
        to be estimated using one of the quasi-Newton strategies.
    finite_diff_rel_step : None or array_like
        Relative step size to use. The absolute step size is computed as
        ``h = finite_diff_rel_step * sign(x0) * max(1, abs(x0))``, possibly
        adjusted to fit into the bounds. For ``method='3-point'`` the sign
        of `h` is ignored. If None then finite_diff_rel_step is selected
        automatically,
    finite_diff_bounds : tuple of array_like
        Lower and upper bounds on independent variables. Defaults to no bounds,
        (-np.inf, np.inf). Each bound must match the size of `x0` or be a
        scalar, in the latter case the bound will be the same for all
        variables. Use it to limit the range of function evaluation.
    epsilon : None or array_like, optional
        Absolute step size to use, possibly adjusted to fit into the bounds.
        For ``method='3-point'`` the sign of `epsilon` is ignored. By default
        relative steps are used, only if ``epsilon is not None`` are absolute
        steps used.

    Notes
    -----
    This class implements a memoization logic. There are methods `fun`,
    `grad`, hess` and corresponding attributes `f`, `g` and `H`. The following
    things should be considered:

        1. Use only public methods `fun`, `grad` and `hess`.
        2. After one of the methods is called, the corresponding attribute
           will be set. However, a subsequent call with a different argument
           of *any* of the methods may overwrite the attribute.
    Nc	                    sØ  t ˆƒs ˆtkr tdt› dƒ‚t ˆƒsJˆtksJtˆtƒsJtdt› dƒ‚ˆtkrbˆtkrbtdƒ‚t |¡ t¡ˆ_	ˆj	j
ˆ_dˆ_dˆ_dˆ_dˆ_dˆ_dˆ_d ˆ_tjˆ_i ‰ˆtkrÜˆˆd< |ˆd< |ˆd	< |ˆd
< ˆtkrˆˆd< |ˆd< |ˆd	< dˆd< ‡ ‡‡fdd„‰‡‡fdd„}	|	ˆ_ˆ ¡  t ˆƒr\‡ ‡‡fdd„‰‡‡fdd„}
nˆtkrv‡‡‡fdd„}
|
ˆ_ˆ ¡  t ˆƒr:ˆt |¡fˆ žŽ ˆ_dˆ_ˆ jd7  _t ˆj¡ræ‡ ‡‡fdd„‰t ˆj¡ˆ_nDtˆjtƒr‡ ‡‡fdd„‰n$‡ ‡‡fdd„‰t t  ˆj¡¡ˆ_‡‡fdd„}nhˆtkrb‡‡‡fdd„}|ƒ  dˆ_n@tˆtƒr¢ˆˆ_ˆj !ˆjd¡ dˆ_d ˆ_"d ˆ_#‡fdd„}|ˆ_$tˆtƒrÂ‡fd d!„}n‡fd"d!„}|ˆ_%d S )#Nz)`grad` must be either callable or one of Ú.z@`hess` must be either callable, HessianUpdateStrategy or one of z‹Whenever the gradient is estimated via finite-differences, we require the Hessian to be estimated using one of the quasi-Newton strategies.r   FÚmethodÚrel_stepZabs_stepÚboundsTÚas_linear_operatorc              
      sŠ   ˆ j d7  _ ˆt | ¡fˆ žŽ }t |¡spzt |¡ ¡ }W n0 ttfk
rn } ztdƒ|‚W 5 d }~X Y nX |ˆjk r†| ˆ_	|ˆ_|S )Nr   z@The user-provided objective function must return a scalar value.)
ÚnfevÚnpÚcopyZisscalarÚasarrayÚitemÚ	TypeErrorÚ
ValueErrorÚ	_lowest_fÚ	_lowest_x)ÚxZfxÚe)ÚargsÚfunÚself© úL/tmp/pip-unpacked-wheel-96ln3f52/scipy/optimize/_differentiable_functions.pyÚfun_wrapped„   s    
ÿý
z,ScalarFunction.__init__.<locals>.fun_wrappedc                      s   ˆ ˆj ƒˆ_d S ©N©r   Úfr   ©r   r   r   r   Ú
update_funš   s    z+ScalarFunction.__init__.<locals>.update_func                    s(   ˆ j d7  _ t ˆt | ¡fˆ žŽ ¡S ©Nr   )Úngevr   Ú
atleast_1dr   ©r   )r   Úgradr   r   r   Úgrad_wrapped¢   s    z-ScalarFunction.__init__.<locals>.grad_wrappedc                      s   ˆ ˆj ƒˆ_d S r   )r   Úgr   )r)   r   r   r   Úupdate_grad¦   s    z,ScalarFunction.__init__.<locals>.update_gradc                      s6   ˆ  ¡  ˆ jd7  _tˆˆjfdˆjiˆ —Žˆ_d S )Nr   Úf0)Ú_update_funr%   r   r   r!   r*   r   ©Úfinite_diff_optionsr   r   r   r   r+   ª   s
    ÿr   c                    s(   ˆ j d7  _ t ˆt | ¡fˆ žŽ ¡S r$   )ÚnhevÚspsÚ
csr_matrixr   r   r'   ©r   Úhessr   r   r   Úhess_wrappedº   s    z-ScalarFunction.__init__.<locals>.hess_wrappedc                    s"   ˆ j d7  _ ˆt | ¡fˆ žŽ S r$   )r0   r   r   r'   r3   r   r   r5   À   s    c                    s.   ˆ j d7  _ t t ˆt | ¡fˆ žŽ ¡¡S r$   )r0   r   Ú
atleast_2dr   r   r'   r3   r   r   r5   Å   s    c                      s   ˆ ˆj ƒˆ_d S r   )r   ÚHr   ©r5   r   r   r   Úupdate_hessÊ   s    z,ScalarFunction.__init__.<locals>.update_hessc                      s*   ˆ  ¡  tˆˆjfdˆjiˆ —Žˆ_ˆjS ©Nr,   )Ú_update_gradr   r   r*   r7   r   )r/   r)   r   r   r   r9   Î   s
    ÿr4   c                      s*   ˆ   ¡  ˆ j ˆ jˆ j ˆ jˆ j ¡ d S r   )r;   r7   Úupdater   Úx_prevr*   Úg_prevr   ©r   r   r   r9   Ý   s    c                    sH   ˆ   ¡  ˆ jˆ _ˆ jˆ _t | ¡ t¡ˆ _dˆ _	dˆ _
dˆ _ˆ  ¡  d S ©NF)r;   r   r=   r*   r>   r   r&   ÚastypeÚfloatÚ	f_updatedÚ	g_updatedÚ	H_updatedÚ_update_hessr'   r?   r   r   Úupdate_xä   s    z)ScalarFunction.__init__.<locals>.update_xc                    s(   t  | ¡ t¡ˆ _dˆ _dˆ _dˆ _d S r@   )r   r&   rA   rB   r   rC   rD   rE   r'   r?   r   r   rG   ð   s    )&ÚcallableÚ
FD_METHODSr   Ú
isinstancer   r   r&   rA   rB   r   ÚsizeÚnr   r%   r0   rC   rD   rE   r   Úinfr   Ú_update_fun_implr-   Ú_update_grad_implr;   r   r7   r1   Úissparser2   r   r6   r   Ú
initializer=   r>   Ú_update_hess_implÚ_update_x_impl)r   r   Úx0r   r(   r4   Úfinite_diff_rel_stepÚfinite_diff_boundsÚepsilonr#   r+   r9   rG   r   )	r   r/   r   r   r(   r)   r4   r5   r   r   Ú__init__V   s    
ÿÿ
ÿ





zScalarFunction.__init__c                 C   s   | j s|  ¡  d| _ d S ©NT©rC   rN   r?   r   r   r   r-   ù   s    zScalarFunction._update_func                 C   s   | j s|  ¡  d| _ d S rY   )rD   rO   r?   r   r   r   r;   þ   s    zScalarFunction._update_gradc                 C   s   | j s|  ¡  d| _ d S rY   ©rE   rR   r?   r   r   r   rF     s    zScalarFunction._update_hessc                 C   s&   t  || j¡s|  |¡ |  ¡  | jS r   )r   Úarray_equalr   rS   r-   r!   ©r   r   r   r   r   r     s    
zScalarFunction.func                 C   s&   t  || j¡s|  |¡ |  ¡  | jS r   )r   r\   r   rS   r;   r*   r]   r   r   r   r(     s    
zScalarFunction.gradc                 C   s&   t  || j¡s|  |¡ |  ¡  | jS r   )r   r\   r   rS   rF   r7   r]   r   r   r   r4     s    
zScalarFunction.hessc                 C   s4   t  || j¡s|  |¡ |  ¡  |  ¡  | j| jfS r   )r   r\   r   rS   r-   r;   r!   r*   r]   r   r   r   Úfun_and_grad  s
    
zScalarFunction.fun_and_grad)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rX   r-   r;   rF   r   r(   r4   r^   r   r   r   r   r      s   K ÿ
 $r   c                   @   sX   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )ÚVectorFunctiona‘  Vector function and its derivatives.

    This class defines a vector function F: R^n->R^m and methods for
    computing or approximating its first and second derivatives.

    Notes
    -----
    This class implements a memoization logic. There are methods `fun`,
    `jac`, hess` and corresponding attributes `f`, `J` and `H`. The following
    things should be considered:

        1. Use only public methods `fun`, `jac` and `hess`.
        2. After one of the methods is called, the corresponding attribute
           will be set. However, a subsequent call with a different argument
           of *any* of the methods may overwrite the attribute.
    c	                    sf  t ˆƒsˆtkrtd t¡ƒ‚t ˆƒsFˆtksFtˆtƒsFtd t¡ƒ‚ˆtkr^ˆtkr^tdƒ‚t |¡ t	¡ˆ_
ˆj
jˆ_dˆ_dˆ_dˆ_dˆ_dˆ_dˆ_i ‰ ˆtkrìˆˆ d< |ˆ d< |d k	rÖt|ƒ}	||	fˆ d< |ˆ d	< t ˆj
¡ˆ_ˆtkrˆˆ d< |ˆ d< d
ˆ d< t ˆj
¡ˆ_ˆtkr8ˆtkr8tdƒ‚‡‡fdd„‰‡‡fdd„}
|
ˆ_|
ƒ  t ˆj¡ˆ_ˆjjˆ_t ˆƒrFˆˆj
ƒˆ_d
ˆ_ˆ jd7  _|sÀ|d krät ˆj¡rä‡‡fdd„‰t ˆj¡ˆ_d
ˆ_nRt ˆj¡r‡‡fdd„‰ˆj  ¡ ˆ_dˆ_n"‡‡fdd„‰t !ˆj¡ˆ_dˆ_‡‡fdd„}nÆˆtkrt"ˆˆj
fdˆjiˆ —Žˆ_d
ˆ_|s|d kr¶t ˆj¡r¶‡ ‡‡fdd„}t ˆj¡ˆ_d
ˆ_nVt ˆj¡rè‡ ‡‡fdd„}ˆj  ¡ ˆ_dˆ_n$‡ ‡‡fdd„}t !ˆj¡ˆ_dˆ_|ˆ_#t ˆƒr¼ˆˆj
ˆjƒˆ_$d
ˆ_ˆ jd7  _t ˆj$¡rl‡‡fdd„‰t ˆj$¡ˆ_$n@tˆj$t%ƒrŠ‡‡fdd„‰n"‡‡fdd„‰t !t &ˆj$¡¡ˆ_$‡‡fdd „}ntˆtkrð‡fd!d"„‰‡ ‡‡fd#d „}|ƒ  d
ˆ_n@tˆtƒr0ˆˆ_$ˆj$ 'ˆjd$¡ d
ˆ_d ˆ_(d ˆ_)‡fd%d „}|ˆ_*tˆtƒrP‡fd&d'„}n‡fd(d'„}|ˆ_+d S ))Nz+`jac` must be either callable or one of {}.zB`hess` must be either callable,HessianUpdateStrategy or one of {}.z‹Whenever the Jacobian is estimated via finite-differences, we require the Hessian to be estimated using one of the quasi-Newton strategies.r   Fr
   r   Zsparsityr   Tr   c                    s   ˆ j d7  _ t ˆ | ƒ¡S r$   )r   r   r&   r'   )r   r   r   r   r   e  s    z,VectorFunction.__init__.<locals>.fun_wrappedc                      s   ˆ ˆj ƒˆ_d S r   r    r   r"   r   r   r#   i  s    z+VectorFunction.__init__.<locals>.update_funr   c                    s   ˆ j d7  _ t ˆ | ƒ¡S r$   )Únjevr1   r2   r'   ©Újacr   r   r   Újac_wrappedz  s    z,VectorFunction.__init__.<locals>.jac_wrappedc                    s   ˆ j d7  _ ˆ | ƒ ¡ S r$   )rd   Útoarrayr'   re   r   r   rg     s    c                    s   ˆ j d7  _ t ˆ | ƒ¡S r$   )rd   r   r6   r'   re   r   r   rg   ˆ  s    c                      s   ˆ ˆj ƒˆ_d S r   )r   ÚJr   )rg   r   r   r   Ú
update_jacŽ  s    z+VectorFunction.__init__.<locals>.update_jacr,   c                      s.   ˆ  ¡  t tˆˆjfdˆjiˆ —Ž¡ˆ_d S r:   )r-   r1   r2   r   r   r!   ri   r   r.   r   r   rj   ˜  s    ÿÿc                      s,   ˆ  ¡  tˆˆjfdˆjiˆ —Ž ¡ ˆ_d S r:   )r-   r   r   r!   rh   ri   r   r.   r   r   rj   ¡  s    ÿc                      s.   ˆ  ¡  t tˆˆjfdˆjiˆ —Ž¡ˆ_d S r:   )r-   r   r6   r   r   r!   ri   r   r.   r   r   rj   ©  s    ÿÿc                    s   ˆ j d7  _ t ˆ | |ƒ¡S r$   )r0   r1   r2   ©r   Úv©r4   r   r   r   r5   º  s    z-VectorFunction.__init__.<locals>.hess_wrappedc                    s   ˆ j d7  _ ˆ | |ƒS r$   )r0   rk   rm   r   r   r5   À  s    c                    s$   ˆ j d7  _ t t ˆ | |ƒ¡¡S r$   )r0   r   r6   r   rk   rm   r   r   r5   Å  s    c                      s   ˆ ˆj ˆjƒˆ_d S r   )r   rl   r7   r   r8   r   r   r9   Ê  s    z,VectorFunction.__init__.<locals>.update_hessc                    s   ˆ | ƒj  |¡S r   )ÚTÚdotrk   )rg   r   r   Ú	jac_dot_vÍ  s    z*VectorFunction.__init__.<locals>.jac_dot_vc                      s8   ˆ  ¡  tˆˆjfˆjj ˆj¡ˆjfdœˆ —Žˆ_d S )N)r,   r   )Ú_update_jacr   r   ri   rn   ro   rl   r7   r   )r/   rp   r   r   r   r9   Ð  s    
þýr4   c                     sZ   ˆ   ¡  ˆ jd k	rVˆ jd k	rVˆ jˆ j } ˆ jj ˆ j¡ˆ jj ˆ j¡ }ˆ j 	| |¡ d S r   )
rq   r=   ÚJ_prevr   ri   rn   ro   rl   r7   r<   )Zdelta_xZdelta_gr?   r   r   r9   ß  s
     c                    sH   ˆ   ¡  ˆ jˆ _ˆ jˆ _t | ¡ t¡ˆ _dˆ _	dˆ _
dˆ _ˆ  ¡  d S r@   )rq   r   r=   ri   rr   r   r&   rA   rB   rC   Ú	J_updatedrE   rF   r'   r?   r   r   rG   ë  s    z)VectorFunction.__init__.<locals>.update_xc                    s(   t  | ¡ t¡ˆ _dˆ _dˆ _dˆ _d S r@   )r   r&   rA   rB   r   rC   rs   rE   r'   r?   r   r   rG   õ  s    ),rH   rI   r   ÚformatrJ   r   r   r&   rA   rB   r   rK   rL   r   rd   r0   rC   rs   rE   r   r   Zx_diffrN   Z
zeros_liker!   rl   Úmri   r1   rP   r2   Úsparse_jacobianrh   r6   r   Ú_update_jac_implr7   r   r   rQ   r=   rr   rR   rS   )r   r   rT   rf   r4   rU   Zfinite_diff_jac_sparsityrV   rv   Zsparsity_groupsr#   rj   r9   rG   r   )	r/   r   r   r4   r5   rf   rp   rg   r   r   rX   3  sä    ÿÿþ
ÿ


ÿ
ÿ
ÿÿ
ÿ

	
zVectorFunction.__init__c                 C   s   t  || j¡s|| _d| _d S r@   )r   r\   rl   rE   )r   rl   r   r   r   Ú	_update_vý  s    zVectorFunction._update_vc                 C   s   t  || j¡s|  |¡ d S r   )r   r\   r   rS   r]   r   r   r   Ú	_update_x  s    zVectorFunction._update_xc                 C   s   | j s|  ¡  d| _ d S rY   rZ   r?   r   r   r   r-     s    zVectorFunction._update_func                 C   s   | j s|  ¡  d| _ d S rY   )rs   rw   r?   r   r   r   rq     s    zVectorFunction._update_jacc                 C   s   | j s|  ¡  d| _ d S rY   r[   r?   r   r   r   rF     s    zVectorFunction._update_hessc                 C   s   |   |¡ |  ¡  | jS r   )ry   r-   r!   r]   r   r   r   r     s    
zVectorFunction.func                 C   s   |   |¡ |  ¡  | jS r   )ry   rq   ri   r]   r   r   r   rf     s    
zVectorFunction.jacc                 C   s"   |   |¡ |  |¡ |  ¡  | jS r   )rx   ry   rF   r7   ©r   r   rl   r   r   r   r4     s    

zVectorFunction.hessN)r_   r`   ra   rb   rX   rx   ry   r-   rq   rF   r   rf   r4   r   r   r   r   rc   "  s    Krc   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚLinearVectorFunctionzüLinear vector function and its derivatives.

    Defines a linear function F = A x, where x is N-D vector and
    A is m-by-n matrix. The Jacobian is constant and equals to A. The Hessian
    is identically zero and it is returned as a csr matrix.
    c                 C   sÀ   |s|d kr*t  |¡r*t  |¡| _d| _n4t  |¡rF| ¡ | _d| _nt t |¡¡| _d| _| jj	\| _
| _t |¡ t¡| _| j | j¡| _d| _tj| j
td| _t  | j| jf¡| _d S )NTF)Zdtype)r1   rP   r2   ri   rv   rh   r   r6   r   Úshaperu   rL   r&   rA   rB   r   ro   r!   rC   Úzerosrl   r7   )r   ÚArT   rv   r   r   r   rX   .  s    

zLinearVectorFunction.__init__c                 C   s*   t  || j¡s&t  |¡ t¡| _d| _d S r@   )r   r\   r   r&   rA   rB   rC   r]   r   r   r   ry   C  s    zLinearVectorFunction._update_xc                 C   s*   |   |¡ | js$| j |¡| _d| _| jS rY   )ry   rC   ri   ro   r!   r]   r   r   r   r   H  s
    
zLinearVectorFunction.func                 C   s   |   |¡ | jS r   )ry   ri   r]   r   r   r   rf   O  s    
zLinearVectorFunction.jacc                 C   s   |   |¡ || _| jS r   )ry   rl   r7   rz   r   r   r   r4   S  s    
zLinearVectorFunction.hessN)	r_   r`   ra   rb   rX   ry   r   rf   r4   r   r   r   r   r{   '  s   r{   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚIdentityVectorFunctionzþIdentity vector function and its derivatives.

    The Jacobian is the identity matrix, returned as a dense array when
    `sparse_jacobian=False` and as a csr matrix otherwise. The Hessian is
    identically zero and it is returned as a csr matrix.
    c                    sJ   t |ƒ}|s|d kr(tj|dd}d}nt |¡}d}tƒ  |||¡ d S )NZcsr)rt   TF)Úlenr1   Zeyer   ÚsuperrX   )r   rT   rv   rL   r~   ©Ú	__class__r   r   rX   `  s    
zIdentityVectorFunction.__init__)r_   r`   ra   rb   rX   Ú__classcell__r   r   r‚   r   r   Y  s   r   )Znumpyr   Zscipy.sparseÚsparser1   Z_numdiffr   r   Z_hessian_update_strategyr   Zscipy.sparse.linalgr   rI   r   rc   r{   r   r   r   r   r   Ú<module>   s       2