o
    iZa                     @   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 dlmZ d dlmZ dZdd
dZdddZdd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)array_namespace)array_api_extra)z2-pointz3-pointcs c                    s   dg fdd}|fS )Nr   c              
      sp   d  d7  < t | g R  }t |s6z
t | }W |S  ttfy5 } ztd|d }~ww |S )Nr   r   z@The user-provided objective function must return a scalar value.)npcopyZisscalarasarrayitem	TypeError
ValueError)xfxeargsfunncallsr
   b/home/kim/smarthome/.venv/lib/python3.10/site-packages/scipy/optimize/_differentiable_functions.pywrapped   s   
z_wrapper_fun.<locals>.wrappedr
   )r   r   r   r
   r   r   _wrapper_fun   s   r   c                    sL   dgt r fdd}|fS tv r$dfdd	}|fS d S )Nr   c                    s,   d  d7  < t t | g R  S Nr   r   )r   
atleast_1dr   r   kwds)r   gradr   r
   r   r   '   s   z_wrapper_grad.<locals>.wrappedc                    s&   d  d7  < t | fd|i S )Nr   r   f0r   r   r    )finite_diff_optionsr   r   r
   r   wrapped1.   s   z_wrapper_grad.<locals>.wrapped1N)callable
FD_METHODS)r   r   r   r#   r   r$   r
   )r   r#   r   r   r   r   _wrapper_grad#   s   r(   c                    s   t rHt|g R  }dgt|r% fdd}t|}nt|tr3 fdd}n fdd}tt	|}||fS t
v r\dgd	fdd	}|d fS d S )
Nr   c                    s,   d  d7  < t t| g R  S r   )sps
csr_matrixr   r   r   r   hessr   r
   r   r   =   s   z_wrapper_hess.<locals>.wrappedc                    s&   d  d7  < t | g R  S r   )r   r   r   r+   r
   r   r   D   s   c                    s2   d  d7  < t t t | g R  S r   )r   
atleast_2dr   r   r   r+   r
   r   r   I   s   "r   c                    s   t | fd|i S Nr    r!   r"   )r#   r   r
   r   r$   S   s   z_wrapper_hess.<locals>.wrapped1r%   )r&   r   r   r)   issparser*   
isinstancer   r-   r   r'   )r,   r   x0r   r#   Hr   r$   r
   )r   r#   r   r,   r   r   _wrapper_hess7   s    



r3   c                   @   s   e Zd ZdZ	dddZedd Zedd Ze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 )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	                 C   sF  t |s|tvrtdt dt |s%|tv s%t|ts%tdt d|tv r1|tv r1tdt| | _}	tj|		|d|	d}
|	j
}|	|
jdrP|
j}t||d\| _| _|| _|| _|| _|| _|	|
|| _|| _| jj| _d	| _d	| _d	| _d | _tj| _i }|tv r||d
< ||d< ||d< ||d< |tv r||d
< ||d< ||d< d|d< |    t!|| j||d\| _"| _#| $  t |rt%|||d\| _&| _'| _(d| _d S |tv rt%|| j"||d\| _&| _'| _(| $  | j&| j| j)d| _(d| _d S t|tr!|| _(| j(*| jd d| _d | _+d | _,dg| _'d S d S )Nz)`grad` must be either callable or one of .z@`hess` must be either callable, HessianUpdateStrategy or one of zWhenever the gradient is estimated via finite-differences, we require the Hessian to be estimated using one of the quasi-Newton strategies.r   ndimxpreal floating)r   Fmethodrel_stepZabs_stepboundsTas_linear_operator)r   r   r#   )r1   r   )r   r1   r#   r    r,   r   )-r&   r'   r   r0   r   r   r8   xpx
atleast_ndr   float64isdtypedtyper   _wrapped_fun_nfevZ	_orig_fun
_orig_grad
_orig_hess_argsastyper   x_dtypesizen	f_updated	g_updated	H_updated	_lowest_xr   inf	_lowest_f_update_funr(   _wrapped_grad_ngev_update_gradr3   _wrapped_hess_nhevr2   g
initializex_prevg_prev)selfr   r1   r   r   r,   finite_diff_rel_stepfinite_diff_boundsepsilonr8   _x_dtyper#   r
   r
   r   __init__   s   




zScalarFunction.__init__c                 C   
   | j d S Nr   )rE   r]   r
   r
   r   nfev     
zScalarFunction.nfevc                 C   rd   re   )rU   rf   r
   r
   r   ngev  rh   zScalarFunction.ngevc                 C   rd   re   )rX   rf   r
   r
   r   nhev
  rh   zScalarFunction.nhevc                 C   s   t | jtr7|   | j| _| j| _tj	| j
|d| j
d}| j
|| j| _d| _d| _d| _|   d S tj	| j
|d| j
d}| j
|| j| _d| _d| _d| _d S Nr   r6   F)r0   rG   r   rV   r   r[   rY   r\   r?   r@   r8   r   rI   rJ   rM   rN   rO   _update_hessr]   r   ra   r
   r
   r   	_update_x  s   
zScalarFunction._update_xc                 C   s>   | j s| | j}|| jk r| j| _|| _|| _d| _ d S d S NT)rM   rD   r   rR   rP   f)r]   r   r
   r
   r   rS   %  s   

zScalarFunction._update_func                 C   s:   | j s| jtv r|   | j| j| jd| _d| _ d S d S Nr>   T)rN   rF   r'   rS   rT   r   rp   rY   rf   r
   r
   r   rV   /  s   

zScalarFunction._update_gradc                 C   s~   | j s=| jtv r|   | j| j| jd| _n!t| jt	r1|   | j
| j| j | j| j  n| | j| _d| _ d S d S rq   )rO   rG   r'   rV   rW   r   rY   r2   r0   r   updater[   r\   rf   r
   r
   r   rl   6  s   
 
zScalarFunction._update_hessc                 C   &   t || js| | |   | jS r%   )r   array_equalr   rn   rS   rp   r]   r   r
   r
   r   r   C     
zScalarFunction.func                 C   rs   r%   )r   rt   r   rn   rV   rY   ru   r
   r
   r   r   I  rv   zScalarFunction.gradc                 C   rs   r%   )r   rt   r   rn   rl   r2   ru   r
   r
   r   r,   O  rv   zScalarFunction.hessc                 C   s4   t || js| | |   |   | j| jfS r%   )r   rt   r   rn   rS   rV   rp   rY   ru   r
   r
   r   fun_and_gradU  s
   
zScalarFunction.fun_and_gradr%   )__name__
__module____qualname____doc__rc   propertyrg   ri   rj   rn   rS   rV   rl   r   r   r,   rw   r
   r
   r
   r   r4   [   s$    K
\



r4   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	                    s  t stvrtdt dt s%tv s%tts%tdt dtv r1tv r1tdt| _}	tj|		|d|	d}
|	j
}|	|
jdrP|
j}|	|
|_|_jj_d_d_d_d	_d	_d	_i  tv r d
< | d< |d urt|}||f d< | d< tj_tv r d
< | d< d d< tj_tv rtv rtdfddfdd}|_|  tj_jj_ t rAj_!d_ jd7  _|s|d u rt"#j!rfddt"$j!_!d_%n)t"#j!r(fddj!& _!d	_%nfddt'j!_!d	_%fdd}nctv rt(jfdji _!d_|sf|d u ryt"#j!ry fdd}t"$j!_!d_%n+t"#j!r fdd}j!& _!d	_%n fdd}t'j!_!d	_%|_)t rjj_*d_ jd7  _t"#j*rԇfddt"$j*_*n tj*t+rfd dnfd!dt't	j*_*fd"d#}n:tv rfd$d% fd&d#}|  d_n ttr6_*j*,jd' d_d _-d _.fd(d#}|_/ttrFfd)d*}nfd+d*}|_0d S ),Nz(`jac` must be either callable or one of r5   z?`hess` must be either callable,HessianUpdateStrategy or one of zWhenever the Jacobian is estimated via finite-differences, we require the Hessian to be estimated using one of the quasi-Newton strategies.r   r6   r9   r   Fr:   r;   Zsparsityr<   Tr=   c                        j d7  _ t | S Nr   )rg   r   r   r   )r   r]   r
   r   fun_wrapped     z,VectorFunction.__init__.<locals>.fun_wrappedc                          j _d S r%   )r   rp   r
   )r   r]   r
   r   
update_fun     z+VectorFunction.__init__.<locals>.update_func                    r~   r   )njevr)   r*   r   jacr]   r
   r   jac_wrapped  r   z,VectorFunction.__init__.<locals>.jac_wrappedc                    s    j d7  _  |  S r   )r   toarrayr   r   r
   r   r     s   c                    r~   r   )r   r   r-   r   r   r
   r   r     r   c                      r   r%   )r   Jr
   )r   r]   r
   r   
update_jac  r   z+VectorFunction.__init__.<locals>.update_jacr    c                      .      ttjfdji _d S r.   )rS   r)   r*   r   r   rp   r   r
   r#   r   r]   r
   r   r        
c                      s,      tjfdji  _d S r.   )rS   r   r   rp   r   r   r
   r   r
   r   r     s   c                      r   r.   )rS   r   r-   r   r   rp   r   r
   r   r
   r   r     r   c                    s    j d7  _ t | |S r   )rj   r)   r*   r   vr,   r]   r
   r   hess_wrapped  s   z-VectorFunction.__init__.<locals>.hess_wrappedc                    s    j d7  _  | |S r   )rj   r   r   r
   r   r     s   
c                    s$    j d7  _ tt | |S r   )rj   r   r-   r   r   r   r
   r   r     s   c                      s    j j_d S r%   )r   r   r2   r
   )r   r]   r
   r   update_hess  s   z,VectorFunction.__init__.<locals>.update_hessc                    s    | j |S r%   )Tdotr   )r   r
   r   	jac_dot_v  r   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   r   r   r   r   r2   r
   )r#   r   r]   r
   r   r     s   
r,   c                     sb        jd ur- jd ur/ j j }  jj j jj j } j	| | d S d S d S r%   )
r   r[   J_prevr   r   r   r   r   r2   rr   )Zdelta_xZdelta_grf   r
   r   r   !  s    c                    sb        j _ j _tj j| d jd} j	| j
 _d _d _d _   d S rk   )r   r   r[   r   r   r?   r@   r8   r   rI   rJ   rM   	J_updatedrO   rl   r   ra   rf   r
   r   update_x-  s   z)VectorFunction.__init__.<locals>.update_xc                    sB   t j j| d jd} j| j _d _d _d _	d S rk   )
r?   r@   r8   r   rI   rJ   r   rM   r   rO   r   rf   r
   r   r   8  s
   
)1r&   r'   r   r0   r   r   r8   r?   r@   r   rA   rB   rC   rI   r   rJ   rK   rL   rg   r   rj   rM   r   rO   r   r   r   Zx_diff_update_fun_implZ
zeros_likerp   r   mr   r)   r/   r*   sparse_jacobianr   r-   r   _update_jac_implr2   r   rZ   r[   r   _update_hess_impl_update_x_impl)r]   r   r1   r   r,   r^   Zfinite_diff_jac_sparsityr_   r   r8   ra   rb   Zsparsity_groupsr   r   r   r   r
   )	r#   r   r   r,   r   r   r   r   r]   r   rc   n  s   






	
zVectorFunction.__init__c                 C   s"   t || js|| _d| _d S d S )NF)r   rt   r   rO   )r]   r   r
   r
   r   	_update_vA  s   
zVectorFunction._update_vc                 C   s    t || js| | d S d S r%   )r   rt   r   r   ru   r
   r
   r   rn   F  s   zVectorFunction._update_xc                 C      | j s|   d| _ d S d S ro   )rM   r   rf   r
   r
   r   rS   J     
zVectorFunction._update_func                 C   r   ro   )r   r   rf   r
   r
   r   r   O  r   zVectorFunction._update_jacc                 C   r   ro   )rO   r   rf   r
   r
   r   rl   T  r   zVectorFunction._update_hessc                 C      |  | |   | jS r%   )rn   rS   rp   ru   r
   r
   r   r   Y     
zVectorFunction.func                 C   r   r%   )rn   r   r   ru   r
   r
   r   r   ^  r   zVectorFunction.jacc                 C   s"   |  | | | |   | jS r%   )r   rn   rl   r2   r]   r   r   r
   r
   r   r,   c  s   

zVectorFunction.hessN)rx   ry   rz   r{   rc   r   rn   rS   r   rl   r   r   r,   r
   r
   r
   r   r}   ]  s     Tr}   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 )LinearVectorFunctionzLinear 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 u rt |rt || _d| _nt |r#| | _d| _ntt|| _d| _| jj	\| _
| _t| | _}tj||d|d}|j}||jdrV|j}|||| _|| _| j| j| _d| _tj| j
td| _t | j| jf| _d S )NTFr   r6   r9   )rC   )r)   r/   r*   r   r   r   r   r-   r   shaper   rL   r   r8   r?   r@   rA   rB   rC   rI   r   rJ   r   rp   rM   Zzerosfloatr   r2   )r]   Ar1   r   r8   ra   rb   r
   r
   r   rc   r  s(   

zLinearVectorFunction.__init__c                 C   sH   t || js"tj| j|d| jd}| j|| j| _d| _	d S d S rk   )
r   rt   r   r?   r@   r8   r   rI   rJ   rM   rm   r
   r
   r   rn     s
   
zLinearVectorFunction._update_xc                 C   s*   |  | | js| j|| _d| _| jS ro   )rn   rM   r   r   rp   ru   r
   r
   r   r     s
   
zLinearVectorFunction.func                 C   s   |  | | jS r%   )rn   r   ru   r
   r
   r   r     s   
zLinearVectorFunction.jacc                 C   s   |  | || _| jS r%   )rn   r   r2   r   r
   r
   r   r,     s   
zLinearVectorFunction.hessN)	rx   ry   rz   r{   rc   rn   r   r   r,   r
   r
   r
   r   r   k  s    r   c                       s    e Zd ZdZ fddZ  ZS )IdentityVectorFunctionzIdentity 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 u rtj|dd}d}nt|}d}t ||| d S )NZcsr)formatTF)lenr)   eyer   superrc   )r]   r1   r   rL   r   	__class__r
   r   rc     s   
zIdentityVectorFunction.__init__)rx   ry   rz   r{   rc   __classcell__r
   r
   r   r   r     s    r   )r
   )Nr
   N)NNr
   N)numpyr   Zscipy.sparsesparser)   Z_numdiffr   r   Z_hessian_update_strategyr   Zscipy.sparse.linalgr   Zscipy._lib._array_apir   Z
scipy._libr   r?   r'   r   r(   r3   r4   r}   r   r   r
   r
   r
   r   <module>   s&    


$    <