o
    EOf                     @   s2  d dl Z d dlZd dlZd dlZd dlmZmZmZ d dlm	Z	m
Z
mZmZmZmZ d dlZd dlZd dlmZ d dlmZ d dlmZ ddlmZmZ g d	ZG d
d deZdd Zdd Zdd Zdd Z e!d" d" dZ#dd Z$				dHddZ%e$e% 		 dId!d"Z&G d#d$ d$Z'G d%d& d&Z(G d'd( d(Z)d)d* Z*G d+d, d,e(Z+G d-d. d.Z,d/" e#d0< G d1d2 d2e+Z-G d3d4 d4e-Z.G d5d6 d6e+Z/G d7d8 d8e+Z0G d9d: d:e+Z1G d;d< d<e+Z2G d=d> d>e(Z3d?d@ Z4e4dAe-Z5e4dBe.Z6e4dCe/Z7e4dDe1Z8e4dEe0Z9e4dFe2Z:e4dGe3Z;dS )J    N)asarraydotvdot)normsolveinvqrsvdLinAlgError)get_blas_funcs)copy_if_needed)getfullargspec_no_self   )scalar_search_wolfe1scalar_search_armijo)broyden1broyden2andersonlinearmixingdiagbroydenexcitingmixingnewton_krylovBroydenFirstKrylovJacobianInverseJacobianNoConvergencec                   @   s   e Zd ZdZdS )r   z\Exception raised when nonlinear solver fails to converge within the specified
    `maxiter`.N)__name__
__module____qualname____doc__ r    r    6lib/python3.10/site-packages/scipy/optimize/_nonlin.pyr      s    r   c                 C   s   t |  S N)npZabsolutemaxxr    r    r!   maxnorm$      r'   c                 C   s*   t | } t| jtjst | tjdS | S )z:Return `x` as an array, of either floats or complex floatsdtype)r   r#   Z
issubdtyper*   Zinexactfloat64r%   r    r    r!   _as_inexact(   s   r,   c                 C   s(   t | t |} t|d| j}|| S )z;Return ndarray `x` as same array subclass and shape as `x0`__array_wrap__)r#   Zreshapeshapegetattrr-   )r&   x0wrapr    r    r!   _array_like0   s   r2   c                 C   s"   t |  st t jS t| S r"   )r#   isfiniteallarrayinfr   vr    r    r!   
_safe_norm7   s   r9   z
    F : function(x) -> f
        Function whose root to find; should take and return an array-like
        object.
    xin : array_like
        Initial guess for the solution
    a  
    iter : int, optional
        Number of iterations to make. If omitted (default), make as many
        as required to meet tolerances.
    verbose : bool, optional
        Print status to stdout on every iteration.
    maxiter : int, optional
        Maximum number of iterations to make. If more are needed to
        meet convergence, `NoConvergence` is raised.
    f_tol : float, optional
        Absolute tolerance (in max-norm) for the residual.
        If omitted, default is 6e-6.
    f_rtol : float, optional
        Relative tolerance for the residual. If omitted, not used.
    x_tol : float, optional
        Absolute minimum step size, as determined from the Jacobian
        approximation. If the step size is smaller than this, optimization
        is terminated as successful. If omitted, not used.
    x_rtol : float, optional
        Relative minimum step size. If omitted, not used.
    tol_norm : function(vector) -> scalar, optional
        Norm to use in convergence check. Default is the maximum norm.
    line_search : {None, 'armijo' (default), 'wolfe'}, optional
        Which type of a line search to use to determine the step size in the
        direction given by the Jacobian approximation. Defaults to 'armijo'.
    callback : function, optional
        Optional callback function. It is called on every iteration as
        ``callback(x, f)`` where `x` is the current solution and `f`
        the corresponding residual.

    Returns
    -------
    sol : ndarray
        An array (of similar array type as `x0`) containing the final solution.

    Raises
    ------
    NoConvergence
        When a solution was not found.

    )Zparams_basicZparams_extrac                 C   s   | j r| j t | _ d S d S r"   )r   
_doc_parts)objr    r    r!   _set_docu   s   r<   krylovFarmijoTc                     sT  |
du rt n|
}
t||||	||
d}t fdd} }t|tj}||}t|}t|}|	|
 || |du rQ|durJ|d }nd|jd  }|du rXd}n|d	u r^d}|d
vrftdd}d}d}d}t|D ]}||||}|r nt||| }|j||d }t|dkrtd|rt|||||\}}}}nd}|| }||}t|}||
 | |r||| ||d  |d  }||d  |k rt||}nt|t|||d  }|}|rtjd||
||f  tj  qr|r	tt|d}|r%|j|||dkddd| d}t||fS t|S )a  
    Find a root of a function, in a way suitable for large-scale problems.

    Parameters
    ----------
    %(params_basic)s
    jacobian : Jacobian
        A Jacobian approximation: `Jacobian` object or something that
        `asjacobian` can transform to one. Alternatively, a string specifying
        which of the builtin Jacobian approximations to use:

            krylov, broyden1, broyden2, anderson
            diagbroyden, linearmixing, excitingmixing

    %(params_extra)s
    full_output : bool
        If true, returns a dictionary `info` containing convergence
        information.
    raise_exception : bool
        If True, a `NoConvergence` exception is raise if no solution is found.

    See Also
    --------
    asjacobian, Jacobian

    Notes
    -----
    This algorithm implements the inexact Newton method, with
    backtracking or full line searches. Several Jacobian
    approximations are available, including Krylov and Quasi-Newton
    methods.

    References
    ----------
    .. [KIM] C. T. Kelley, "Iterative Methods for Linear and Nonlinear
       Equations". Society for Industrial and Applied Mathematics. (1995)
       https://archive.siam.org/books/kelley/fr16/

    N)f_tolf_rtolx_tolx_rtoliterr   c                    s   t  t|  S r"   )r,   r2   flatten)zFr0   r    r!   func   s   znonlin_solve.<locals>.funcr   d   Tr>   F)Nr>   wolfezInvalid line searchg?gH.?g?gMbP?)tolr   z[Jacobian inversion yielded zero vector. This indicates a bug in the Jacobian approximation.      ?   z%d:  |F(x)| = %g; step %g
z0A solution was found at the specified tolerance.z:The maximum number of iterations allowed has been reached.)r   rM   )ZnitZfunstatusZsuccessmessage)r'   TerminationConditionr,   rD   r#   Z	full_liker6   r   
asjacobiansetupcopysize
ValueErrorrangecheckminr   _nonlin_line_searchupdater$   sysstdoutwriteflushr   r2   	iteration) rG   r0   jacobianrC   verbosemaxiterr?   r@   rA   rB   Ztol_normZline_searchcallbackZfull_outputZraise_exceptionZ	conditionrH   r&   dxFxFx_normgammaZeta_maxZeta_tresholdZetanrN   rK   sZFx_norm_newZeta_Ainfor    rF   r!   nonlin_solvez   s   -






rk   :0yE>{Gz?c                    s   dg|gt |d gt t   d fdd	fdd}|dkr<t|d d	|d
\}}	}
n|dkrOtd d  |d\}}	|d u rUd}|   |d krfd }n}t |}|||fS )Nr   rM   Tc                    sT   | d kr
d S |    }|}t |d }|r(| d< |d< |d< |S )Nr   rM   )r9   )ri   storeZxtr8   p)rd   rH   tmp_Fxtmp_phitmp_sr&   r    r!   phi  s   z _nonlin_line_search.<locals>.phic                    s0   t |  d  } | | dd |  | S )Nr   F)rn   )abs)ri   ds)rs   rdiffs_normr    r!   derphi#  s   z#_nonlin_line_search.<locals>.derphirJ   rm   )Zxtolaminr>   )ry   rL   )T)r   r   r   )rH   r&   re   rd   Zsearch_typerv   Zsminrx   ri   Zphi1Zphi0rf   r    )	rd   rH   rs   rv   rw   rp   rq   rr   r&   r!   rY     s,   

rY   c                   @   s.   e Zd ZdZdddddefddZdd ZdS )rP   z
    Termination condition for an iteration. It is terminated if

    - |F| < f_rtol*|F_0|, AND
    - |F| < f_tol

    AND

    - |dx| < x_rtol*|x|, AND
    - |dx| < x_tol

    Nc                 C   sx   |d u rt t jjd }|d u rt j}|d u rt j}|d u r"t j}|| _|| _|| _|| _|| _	|| _
d | _d| _d S )NgUUUUUU?r   )r#   finfor+   epsr6   rA   rB   r?   r@   r   rC   f0_normr_   )selfr?   r@   rA   rB   rC   r   r    r    r!   __init__J  s    
zTerminationCondition.__init__c                 C   s   |  j d7  _ | |}| |}| |}| jd u r|| _|dkr$dS | jd ur1d| j | jk S t|| jkoJ|| j | jkoJ|| jkoJ|| j |kS )Nr   r   rM   )	r_   r   r|   rC   intr?   r@   rA   rB   )r}   fr&   rd   Zf_normZx_normdx_normr    r    r!   rW   b  s    





zTerminationCondition.check)r   r   r   r   r'   r~   rW   r    r    r    r!   rP   =  s    
rP   c                   @   s:   e Zd ZdZdd Zdd ZdddZd	d
 Zdd ZdS )Jacobiana  
    Common interface for Jacobians or Jacobian approximations.

    The optional methods come useful when implementing trust region
    etc., algorithms that often require evaluating transposes of the
    Jacobian.

    Methods
    -------
    solve
        Returns J^-1 * v
    update
        Updates Jacobian to point `x` (where the function has residual `Fx`)

    matvec : optional
        Returns J * v
    rmatvec : optional
        Returns A^H * v
    rsolve : optional
        Returns A^-H * v
    matmat : optional
        Returns A * V, where V is a dense matrix with dimensions (N,K).
    todense : optional
        Form the dense Jacobian matrix. Necessary for dense trust region
        algorithms, and useful for testing.

    Attributes
    ----------
    shape
        Matrix dimensions (M, N)
    dtype
        Data type of the matrix.
    func : callable, optional
        Function the Jacobian corresponds to

    c                 K   sb   g d}|  D ]\}}||vrtd| |d ur"t| |||  qt| dr/ddd}d S d S )N)	r   rZ   matvecrmatvecrsolveZmatmattodenser.   r*   zUnknown keyword argument %sr   c                 S   s   |d urt d| |  S )Nz`dtype` must be None, was )rU   r   )r}   r*   rS   r    r    r!   	__array__  s   z$Jacobian.__init__.<locals>.__array__NN)itemsrU   setattrhasattr)r}   kwnamesnamevaluer   r    r    r!   r~     s   
zJacobian.__init__c                 C   s   t | S r"   )r   r}   r    r    r!   aspreconditioner  s   zJacobian.aspreconditionerr   c                 C      t r"   NotImplementedErrorr}   r8   rK   r    r    r!   r        zJacobian.solvec                 C      d S r"   r    r}   r&   rG   r    r    r!   rZ     r   zJacobian.updatec                 C   s>   || _ |j|jf| _|j| _| jjtju r| || d S d S r"   )rH   rT   r.   r*   	__class__rR   r   rZ   r}   r&   rG   rH   r    r    r!   rR     s   zJacobian.setupNr   )	r   r   r   r   r~   r   r   rZ   rR   r    r    r    r!   r   }  s    %
r   c                   @   s,   e Zd Zdd Zedd Zedd ZdS )r   c                 C   sB   || _ |j| _|j| _t|dr|j| _t|dr|j| _d S d S )NrR   r   )r`   r   r   rZ   r   rR   r   r   )r}   r`   r    r    r!   r~     s   

zInverseJacobian.__init__c                 C      | j jS r"   )r`   r.   r   r    r    r!   r.        zInverseJacobian.shapec                 C   r   r"   )r`   r*   r   r    r    r!   r*     r   zInverseJacobian.dtypeN)r   r   r   r~   propertyr.   r*   r    r    r    r!   r     s    	
r   c              
      s  t jjjt tr S t rt tr  S t t	j
r\ jdkr(tdt	t	   jd  jd kr>tdt fdd fddd fd	d	d fd
d	 j jdS t j r jd  jd krptdt fdd fddd fdd	d fdd	 j jdS t drt drt drtt dt d jt dt dt d j jdS t rG  fdddt}| S t trttttttttd   S td) zE
    Convert given object to one suitable for use as a Jacobian.
    rM   zarray must have rank <= 2r   r   zarray must be squarec                    
   t  | S r"   )r   r7   Jr    r!   <lambda>     
 zasjacobian.<locals>.<lambda>c                       t   j| S r"   )r   conjTr7   r   r    r!   r         c                    r   r"   )r   r8   rK   r   r    r!   r     r   c                    r   r"   )r   r   r   r   r   r    r!   r     r   )r   r   r   r   r*   r.   zmatrix must be squarec                    s    |  S r"   r    r7   r   r    r!   r     s    c                    s      j|  S r"   r   r   r7   r   r    r!   r     s    c                    s
    | S r"   r    r   r   spsolver    r!   r     r   c                    s      j| S r"   r   r   r   r    r!   r     r   r.   r*   r   r   r   r   rZ   rR   )r   r   r   r   rZ   rR   r*   r.   c                       sL   e Zd Zdd Zd fdd	Z fddZd fdd		Z fd
dZdS )zasjacobian.<locals>.Jacc                 S   s
   || _ d S r"   r%   r   r    r    r!   rZ        
zasjacobian.<locals>.Jac.updater   c                    s>    | j }t|tjrt||S tj|r||S tdNzUnknown matrix type)	r&   
isinstancer#   ndarrayr   scipysparseissparserU   r}   r8   rK   mr   r    r!   r     s   


zasjacobian.<locals>.Jac.solvec                    s<    | j }t|tjrt||S tj|r|| S tdr   )	r&   r   r#   r   r   r   r   r   rU   r}   r8   r   r   r    r!   r     s   

zasjacobian.<locals>.Jac.matvecc                    sJ    | j }t|tjrt| j|S tj	|r!| j|S t
dr   )r&   r   r#   r   r   r   r   r   r   r   rU   r   r   r    r!   r     s   
zasjacobian.<locals>.Jac.rsolvec                    sH    | j }t|tjrt| j|S tj	|r | j| S t
dr   )r&   r   r#   r   r   r   r   r   r   r   rU   r   r   r    r!   r     s   
zasjacobian.<locals>.Jac.rmatvecNr   )r   r   r   rZ   r   r   r   r   r    r   r    r!   Jac   s    			r   )r   r   r   r   r   r   r=   z#Cannot convert object to a JacobianNr   ) r   r   linalgr   r   r   inspectZisclass
issubclassr#   r   ndimrU   Z
atleast_2dr   r.   r*   r   r   r/   r   callablestrdictr   BroydenSecondAndersonDiagBroydenLinearMixingExcitingMixingr   	TypeError)r   r   r    r   r!   rQ     sf   





'
rQ   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )GenericBroydenc                 C   sj   t | ||| || _|| _t| dr1| jd u r3t|}|r,dtt|d | | _d S d| _d S d S d S )Nalpha      ?r   rL   )r   rR   last_flast_xr   r   r   r$   )r}   r0   f0rH   Znormf0r    r    r!   rR   9  s   
zGenericBroyden.setupc                 C   r   r"   r   r}   r&   r   rd   dfr   df_normr    r    r!   _updateG  r   zGenericBroyden._updatec              	   C   s@   || j  }|| j }| ||||t|t| || _ || _d S r"   )r   r   r   r   )r}   r&   r   r   rd   r    r    r!   rZ   J  s
   


zGenericBroyden.updateN)r   r   r   rR   r   rZ   r    r    r    r!   r   8  s    r   c                   @   s   e Zd ZdZdd Zedd Zedd Zdd	 Zd
d Z	dddZ
dddZdd ZdddZdd Zdd Zdd Zd ddZdS )!LowRankMatrixz
    A matrix represented as

    .. math:: \alpha I + \sum_{n=0}^{n=M} c_n d_n^\dagger

    However, if the rank of the matrix reaches the dimension of the vectors,
    full matrix representation will be used thereon.

    c                 C   s(   || _ g | _g | _|| _|| _d | _d S r"   )r   csru   rh   r*   	collapsed)r}   r   rh   r*   r    r    r!   r~   ]  s   
zLowRankMatrix.__init__c                 C   s\   t g d|d d | g \}}}||  }t||D ]\}}	||	| }
||||j|
}q|S )N)axpyscaldotcr   )r   ziprT   )r8   r   r   ru   r   r   r   wcdar    r    r!   _matvece  s   

zLowRankMatrix._matvecc                 C   s
  t |dkr
| | S tddg|dd | g \}}|d }|tjt ||jd }t|D ]\}}	t|D ]\}
}|||
f  ||	|7  < q6q.tjt ||jd}t|D ]\}
}	||	| ||
< qW|| }t||}| | }t||D ]\}}||||j	| }qu|S )Evaluate w = M^-1 vr   r   r   Nr   r)   )
lenr   r#   identityr*   	enumeratezerosr   r   rT   )r8   r   r   ru   r   r   Zc0Air   jr   qr   Zqcr    r    r!   _solveo  s$    
zLowRankMatrix._solvec                 C   s.   | j durt| j |S t|| j| j| jS )zEvaluate w = M vN)r   r#   r   r   r   r   r   ru   r}   r8   r    r    r!   r     s   
zLowRankMatrix.matvecc                 C   s:   | j durt| j j |S t|t| j| j| j	S )zEvaluate w = M^H vN)
r   r#   r   r   r   r   r   r   ru   r   r   r    r    r!   r     s   
zLowRankMatrix.rmatvecr   c                 C   s,   | j durt| j |S t|| j| j| jS )r   N)r   r   r   r   r   r   ru   r   r    r    r!   r     s   
zLowRankMatrix.solvec                 C   s8   | j durt| j j |S t|t| j| j| j	S )zEvaluate w = M^-H vN)
r   r   r   r   r   r   r#   r   ru   r   r   r    r    r!   r     s   
zLowRankMatrix.rsolvec                 C   st   | j d ur|  j |d d d f |d d d f   7  _ d S | j| | j| t| j|jkr8|   d S d S r"   )r   r   r   appendru   r   rT   collapse)r}   r   r   r    r    r!   r     s   
.zLowRankMatrix.appendNc                 C   s   |d urt jd| ddd |d urt jd| ddd | jd ur&| jS | jtj| j| jd }t| j	| j
D ]\}}||d d d f |d d d f   7 }q9|S )NzJLowRankMatrix is scipy-internal code, `dtype` should only be None but was z (not handled)   )
stacklevelzILowRankMatrix is scipy-internal code, `copy` should only be None but was r)   )warningswarnr   r   r#   r   rh   r*   r   r   ru   r   )r}   r*   rS   Gmr   r   r    r    r!   r     s$   
*zLowRankMatrix.__array__c                 C   s&   t j| td| _d| _d| _d| _dS )z0Collapse the low-rank matrix to a full-rank one.)rS   N)r#   r5   r   r   r   ru   r   r   r    r    r!   r     s   
zLowRankMatrix.collapsec                 C   sH   | j durdS |dksJ t| j|kr"| jdd= | jdd= dS dS )zH
        Reduce the rank of the matrix by dropping all vectors.
        Nr   r   r   r   ru   r}   Zrankr    r    r!   restart_reduce  s   
zLowRankMatrix.restart_reducec                 C   sN   | j durdS |dksJ t| j|kr%| jd= | jd= t| j|ksdS dS )zK
        Reduce the rank of the matrix by dropping oldest vectors.
        Nr   r   r   r    r    r!   simple_reduce  s   
zLowRankMatrix.simple_reducec                 C   s6  | j durdS |}|dur|}n|d }| jr!t|t| jd }tdt||d }t| j}||k r6dS t| jj}t| jj}t	|dd\}}t
||j }t|dd\}	}
}t
|t|}t
||j }t|D ]}|dd|f  | j|< |dd|f  | j|< qp| j|d= | j|d= dS )	a  
        Reduce the rank of the matrix by retaining some SVD components.

        This corresponds to the "Broyden Rank Reduction Inverse"
        algorithm described in [1]_.

        Note that the SVD decomposition can be done by solving only a
        problem whose size is the effective rank of this matrix, which
        is viable even for large problems.

        Parameters
        ----------
        max_rank : int
            Maximum rank of this matrix after reduction.
        to_retain : int, optional
            Number of SVD components to retain when reduction is done
            (ie. rank > max_rank). Default is ``max_rank - 2``.

        References
        ----------
        .. [1] B.A. van der Rotten, PhD thesis,
           "A limited memory Broyden method to solve high-dimensional
           systems of nonlinear equations". Mathematisch Instituut,
           Universiteit Leiden, The Netherlands (2003).

           https://web.archive.org/web/20161022015821/http://www.math.leidenuniv.nl/scripties/Rotten.pdf

        NrM   r   r   Zeconomic)modeF)Zfull_matrices)r   r   rX   r   r$   r#   r5   r   ru   r   r   r   r	   r   rV   rS   )r}   max_rankZ	to_retainro   r   r   CDRUSZWHkr    r    r!   
svd_reduce  s0   

zLowRankMatrix.svd_reducer   r   r"   )r   r   r   r   r~   staticmethodr   r   r   r   r   r   r   r   r   r   r   r   r    r    r    r!   r   R  s"    

	



r   a  
    alpha : float, optional
        Initial guess for the Jacobian is ``(-1/alpha)``.
    reduction_method : str or tuple, optional
        Method used in ensuring that the rank of the Broyden matrix
        stays low. Can either be a string giving the name of the method,
        or a tuple of the form ``(method, param1, param2, ...)``
        that gives the name of the method and values for additional parameters.

        Methods available:

            - ``restart``: drop all matrix columns. Has no extra parameters.
            - ``simple``: drop oldest matrix column. Has no extra parameters.
            - ``svd``: keep only the most significant SVD components.
              Takes an extra parameter, ``to_retain``, which determines the
              number of SVD components to retain when rank reduction is done.
              Default is ``max_rank - 2``.

    max_rank : int, optional
        Maximum rank for the Broyden matrix.
        Default is infinity (i.e., no rank reduction).
    Zbroyden_paramsc                   @   sV   e Zd ZdZdddZdd Zdd	 ZdddZdd ZdddZ	dd Z
dd ZdS )r   a  
    Find a root of a function, using Broyden's first Jacobian approximation.

    This method is also known as \"Broyden's good method\".

    Parameters
    ----------
    %(params_basic)s
    %(broyden_params)s
    %(params_extra)s

    See Also
    --------
    root : Interface to root finding algorithms for multivariate
           functions. See ``method='broyden1'`` in particular.

    Notes
    -----
    This algorithm implements the inverse Jacobian Quasi-Newton update

    .. math:: H_+ = H + (dx - H df) dx^\dagger H / ( dx^\dagger H df)

    which corresponds to Broyden's first Jacobian update

    .. math:: J_+ = J + (df - J dx) dx^\dagger / dx^\dagger dx


    References
    ----------
    .. [1] B.A. van der Rotten, PhD thesis,
       \"A limited memory Broyden method to solve high-dimensional
       systems of nonlinear equations\". Mathematisch Instituut,
       Universiteit Leiden, The Netherlands (2003).

       https://web.archive.org/web/20161022015821/http://www.math.leidenuniv.nl/scripties/Rotten.pdf

    Examples
    --------
    The following functions define a system of nonlinear equations

    >>> def fun(x):
    ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
    ...             0.5 * (x[1] - x[0])**3 + x[1]]

    A solution can be obtained as follows.

    >>> from scipy import optimize
    >>> sol = optimize.broyden1(fun, [0, 0])
    >>> sol
    array([0.84116396, 0.15883641])

    Nrestartc                    s   t  |_d _|d u rtj}|_t|trd n
|dd   |d }|d f   |dkr< fdd_	d S |dkrJ fdd_	d S |d	krX fd
d_	d S t
d| )Nr    r   r   r	   c                         j j  S r"   )r   r   r    Zreduce_paramsr}   r    r!   r   }      z'BroydenFirst.__init__.<locals>.<lambda>simplec                      r   r"   )r   r   r    r   r    r!   r     r   r   c                      r   r"   )r   r   r    r   r    r!   r     r   z"Unknown rank reduction method '%s')r   r~   r   r   r#   r6   r   r   r   _reducerU   )r}   r   Zreduction_methodr   r    r   r!   r~   l  s(   

zBroydenFirst.__init__c                 C   s.   t | ||| t| j | jd | j| _d S )Nr   )r   rR   r   r   r.   r*   r   r   r    r    r!   rR     s   zBroydenFirst.setupc                 C   s
   t | jS r"   )r   r   r   r    r    r!   r     r   zBroydenFirst.todenser   c                 C   s>   | j |}t| s| | j| j| j | j |S |S r"   )	r   r   r#   r3   r4   rR   r   r   rH   )r}   r   rK   rr    r    r!   r     s
   zBroydenFirst.solvec                 C      | j |S r"   )r   r   r}   r   r    r    r!   r        zBroydenFirst.matvecc                 C   r  r"   )r   r   r}   r   rK   r    r    r!   r     r  zBroydenFirst.rsolvec                 C   r  r"   )r   r   r  r    r    r!   r     r  zBroydenFirst.rmatvecc           
      C   sD   |    | j|}|| j| }|t|| }	| j||	 d S r"   )r   r   r   r   r   r   
r}   r&   r   rd   r   r   r   r8   r   r   r    r    r!   r     s
   zBroydenFirst._update)Nr   Nr   )r   r   r   r   r~   rR   r   r   r   r   r   r   r    r    r    r!   r   6  s    
5

r   c                   @   s   e Zd ZdZdd ZdS )r   aK  
    Find a root of a function, using Broyden's second Jacobian approximation.

    This method is also known as "Broyden's bad method".

    Parameters
    ----------
    %(params_basic)s
    %(broyden_params)s
    %(params_extra)s

    See Also
    --------
    root : Interface to root finding algorithms for multivariate
           functions. See ``method='broyden2'`` in particular.

    Notes
    -----
    This algorithm implements the inverse Jacobian Quasi-Newton update

    .. math:: H_+ = H + (dx - H df) df^\dagger / ( df^\dagger df)

    corresponding to Broyden's second method.

    References
    ----------
    .. [1] B.A. van der Rotten, PhD thesis,
       "A limited memory Broyden method to solve high-dimensional
       systems of nonlinear equations". Mathematisch Instituut,
       Universiteit Leiden, The Netherlands (2003).

       https://web.archive.org/web/20161022015821/http://www.math.leidenuniv.nl/scripties/Rotten.pdf

    Examples
    --------
    The following functions define a system of nonlinear equations

    >>> def fun(x):
    ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
    ...             0.5 * (x[1] - x[0])**3 + x[1]]

    A solution can be obtained as follows.

    >>> from scipy import optimize
    >>> sol = optimize.broyden2(fun, [0, 0])
    >>> sol
    array([0.84116365, 0.15883529])

    c           
      C   s:   |    |}|| j| }||d  }	| j||	 d S NrM   )r   r   r   r   r  r    r    r!   r     s
   zBroydenSecond._updateN)r   r   r   r   r   r    r    r    r!   r     s    2r   c                   @   s4   e Zd ZdZdddZddd	Zd
d Zdd ZdS )r   a  
    Find a root of a function, using (extended) Anderson mixing.

    The Jacobian is formed by for a 'best' solution in the space
    spanned by last `M` vectors. As a result, only a MxM matrix
    inversions and MxN multiplications are required. [Ey]_

    Parameters
    ----------
    %(params_basic)s
    alpha : float, optional
        Initial guess for the Jacobian is (-1/alpha).
    M : float, optional
        Number of previous vectors to retain. Defaults to 5.
    w0 : float, optional
        Regularization parameter for numerical stability.
        Compared to unity, good values of the order of 0.01.
    %(params_extra)s

    See Also
    --------
    root : Interface to root finding algorithms for multivariate
           functions. See ``method='anderson'`` in particular.

    References
    ----------
    .. [Ey] V. Eyert, J. Comp. Phys., 124, 271 (1996).

    Examples
    --------
    The following functions define a system of nonlinear equations

    >>> def fun(x):
    ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
    ...             0.5 * (x[1] - x[0])**3 + x[1]]

    A solution can be obtained as follows.

    >>> from scipy import optimize
    >>> sol = optimize.anderson(fun, [0, 0])
    >>> sol
    array([0.84116588, 0.15883789])

    Nrm      c                 C   s2   t |  || _|| _g | _g | _d | _|| _d S r"   )r   r~   r   Mrd   r   rg   w0)r}   r   r	  r  r    r    r!   r~   /  s   

zAnderson.__init__r   c           	      C   s   | j  | }t| j}|dkr|S tj||jd}t|D ]}t| j| |||< qzt	| j
|}W n tyI   | jd d = | jd d = | Y S w t|D ]}||| | j| | j | j|    7 }qN|S Nr   r)   )r   r   rd   r#   emptyr*   rV   r   r   r   r   r
   )	r}   r   rK   rd   rh   df_fr   rg   r   r    r    r!   r   8  s"   
(zAnderson.solvec              	   C   s,  | | j  }t| j}|dkr|S tj||jd}t|D ]}t| j| |||< qtj||f|jd}t|D ]<}t|D ]5}t| j| | j| |||f< ||krs| j	dkrs|||f  t| j| | j| | j	d  | j  8  < q>q8t
||}	t|D ]}
||	|
 | j|
 | j|
 | j    7 }q~|S )Nr   r)   rM   )r   r   rd   r#   r  r*   rV   r   r   r	  r   )r}   r   rd   rh   r  r   br   r   rg   r   r    r    r!   r   O  s&   
6
(zAnderson.matvecc                 C   s   | j dkrd S | j| | j| t| j| j kr/| jd | jd t| j| j kst| j}tj||f|jd}t	|D ])}	t	|	|D ]!}
|	|
krU| j
d }nd}d| t| j|	 | j|
  ||	|
f< qIqB|t|dj 7 }|| _d S )Nr   r)   rM   r   )r  rd   r   r   r   popr#   r   r*   rV   r	  r   Ztriur   r   r   )r}   r&   r   rd   r   r   r   rh   r   r   r   Zwdr    r    r!   r   f  s&   

(
zAnderson._update)Nrm   r  r   )r   r   r   r   r~   r   r   r   r    r    r    r!   r     s    
F
	r   c                   @   sV   e Zd ZdZdddZdd Zddd	Zd
d ZdddZdd Z	dd Z
dd ZdS )r   a,  
    Find a root of a function, using diagonal Broyden Jacobian approximation.

    The Jacobian approximation is derived from previous iterations, by
    retaining only the diagonal of Broyden matrices.

    .. warning::

       This algorithm may be useful for specific problems, but whether
       it will work may depend strongly on the problem.

    Parameters
    ----------
    %(params_basic)s
    alpha : float, optional
        Initial guess for the Jacobian is (-1/alpha).
    %(params_extra)s

    See Also
    --------
    root : Interface to root finding algorithms for multivariate
           functions. See ``method='diagbroyden'`` in particular.

    Examples
    --------
    The following functions define a system of nonlinear equations

    >>> def fun(x):
    ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
    ...             0.5 * (x[1] - x[0])**3 + x[1]]

    A solution can be obtained as follows.

    >>> from scipy import optimize
    >>> sol = optimize.diagbroyden(fun, [0, 0])
    >>> sol
    array([0.84116403, 0.15883384])

    Nc                 C      t |  || _d S r"   r   r~   r   r}   r   r    r    r!   r~        

zDiagBroyden.__init__c                 C   s6   t | ||| tj| jd fd| j | jd| _d S )Nr   r   r)   )r   rR   r#   fullr.   r   r*   r   r   r    r    r!   rR     s   &zDiagBroyden.setupr   c                 C      | | j  S r"   r   r  r    r    r!   r     r  zDiagBroyden.solvec                 C      | | j  S r"   r  r  r    r    r!   r     r  zDiagBroyden.matvecc                 C      | | j   S r"   r   r   r  r    r    r!   r        zDiagBroyden.rsolvec                 C      | | j   S r"   r  r  r    r    r!   r     r  zDiagBroyden.rmatvecc                 C   s   t | j S r"   )r#   diagr   r   r    r    r!   r     r(   zDiagBroyden.todensec                 C   s(   |  j || j |  | |d  8  _ d S r  r  r   r    r    r!   r     s   (zDiagBroyden._updater"   r   r   r   r   r   r~   rR   r   r   r   r   r   r   r    r    r    r!   r     s    
(

r   c                   @   sN   e Zd ZdZdddZdddZdd	 Zdd
dZdd Zdd Z	dd Z
dS )r   a  
    Find a root of a function, using a scalar Jacobian approximation.

    .. warning::

       This algorithm may be useful for specific problems, but whether
       it will work may depend strongly on the problem.

    Parameters
    ----------
    %(params_basic)s
    alpha : float, optional
        The Jacobian approximation is (-1/alpha).
    %(params_extra)s

    See Also
    --------
    root : Interface to root finding algorithms for multivariate
           functions. See ``method='linearmixing'`` in particular.

    Nc                 C   r  r"   r  r  r    r    r!   r~     r  zLinearMixing.__init__r   c                 C   r  r"   r   r  r    r    r!   r     r  zLinearMixing.solvec                 C   r  r"   r  r  r    r    r!   r     r  zLinearMixing.matvecc                 C   s   | t | j S r"   r#   r   r   r  r    r    r!   r        zLinearMixing.rsolvec                 C   s   | t | j S r"   r  r  r    r    r!   r     r  zLinearMixing.rmatvecc                 C   s   t t | jd d| j S )Nr   )r#   r  r  r.   r   r   r    r    r!   r     s   zLinearMixing.todensec                 C   r   r"   r    r   r    r    r!   r     r   zLinearMixing._updater"   r   )r   r   r   r   r~   r   r   r   r   r   r   r    r    r    r!   r     s    


r   c                   @   sV   e Zd ZdZdddZdd Zdd	d
Zdd ZdddZdd Z	dd Z
dd ZdS )r   a  
    Find a root of a function, using a tuned diagonal Jacobian approximation.

    The Jacobian matrix is diagonal and is tuned on each iteration.

    .. warning::

       This algorithm may be useful for specific problems, but whether
       it will work may depend strongly on the problem.

    See Also
    --------
    root : Interface to root finding algorithms for multivariate
           functions. See ``method='excitingmixing'`` in particular.

    Parameters
    ----------
    %(params_basic)s
    alpha : float, optional
        Initial Jacobian approximation is (-1/alpha).
    alphamax : float, optional
        The entries of the diagonal Jacobian are kept in the range
        ``[alpha, alphamax]``.
    %(params_extra)s
    NrL   c                 C   s    t |  || _|| _d | _d S r"   )r   r~   r   alphamaxbeta)r}   r   r!  r    r    r!   r~     s   

zExcitingMixing.__init__c                 C   s2   t | ||| tj| jd f| j| jd| _d S r
  )r   rR   r#   r  r.   r   r*   r"  r   r    r    r!   rR     s   "zExcitingMixing.setupr   c                 C   r  r"   r"  r  r    r    r!   r     r  zExcitingMixing.solvec                 C   r  r"   r#  r  r    r    r!   r     r  zExcitingMixing.matvecc                 C   r  r"   r"  r   r  r    r    r!   r   !  r  zExcitingMixing.rsolvec                 C   r  r"   r$  r  r    r    r!   r   $  r  zExcitingMixing.rmatvecc                 C   s   t d| j S )Nr   )r#   r  r"  r   r    r    r!   r   '  r  zExcitingMixing.todensec                 C   sL   || j  dk}| j|  | j7  < | j| j| < tj| jd| j| jd d S )Nr   )out)r   r"  r   r#   Zclipr!  )r}   r&   r   rd   r   r   r   Zincrr    r    r!   r   *  s   zExcitingMixing._update)NrL   r   r  r    r    r    r!   r     s    


r   c                   @   sH   e Zd ZdZ		dddZdd	 Zd
d ZdddZdd Zdd Z	dS )r   a  
    Find a root of a function, using Krylov approximation for inverse Jacobian.

    This method is suitable for solving large-scale problems.

    Parameters
    ----------
    %(params_basic)s
    rdiff : float, optional
        Relative step size to use in numerical differentiation.
    method : str or callable, optional
        Krylov method to use to approximate the Jacobian.  Can be a string,
        or a function implementing the same interface as the iterative
        solvers in `scipy.sparse.linalg`. If a string, needs to be one of:
        ``'lgmres'``, ``'gmres'``, ``'bicgstab'``, ``'cgs'``, ``'minres'``,
        ``'tfqmr'``.

        The default is `scipy.sparse.linalg.lgmres`.
    inner_maxiter : int, optional
        Parameter to pass to the "inner" Krylov solver: maximum number of
        iterations. Iteration will stop after maxiter steps even if the
        specified tolerance has not been achieved.
    inner_M : LinearOperator or InverseJacobian
        Preconditioner for the inner Krylov iteration.
        Note that you can use also inverse Jacobians as (adaptive)
        preconditioners. For example,

        >>> from scipy.optimize import BroydenFirst, KrylovJacobian
        >>> from scipy.optimize import InverseJacobian
        >>> jac = BroydenFirst()
        >>> kjac = KrylovJacobian(inner_M=InverseJacobian(jac))

        If the preconditioner has a method named 'update', it will be called
        as ``update(x, f)`` after each nonlinear step, with ``x`` giving
        the current point, and ``f`` the current function value.
    outer_k : int, optional
        Size of the subspace kept across LGMRES nonlinear iterations.
        See `scipy.sparse.linalg.lgmres` for details.
    inner_kwargs : kwargs
        Keyword parameters for the "inner" Krylov solver
        (defined with `method`). Parameter names must start with
        the `inner_` prefix which will be stripped before passing on
        the inner method. See, e.g., `scipy.sparse.linalg.gmres` for details.
    %(params_extra)s

    See Also
    --------
    root : Interface to root finding algorithms for multivariate
           functions. See ``method='krylov'`` in particular.
    scipy.sparse.linalg.gmres
    scipy.sparse.linalg.lgmres

    Notes
    -----
    This function implements a Newton-Krylov solver. The basic idea is
    to compute the inverse of the Jacobian with an iterative Krylov
    method. These methods require only evaluating the Jacobian-vector
    products, which are conveniently approximated by a finite difference:

    .. math:: J v \approx (f(x + \omega*v/|v|) - f(x)) / \omega

    Due to the use of iterative matrix inverses, these methods can
    deal with large nonlinear problems.

    SciPy's `scipy.sparse.linalg` module offers a selection of Krylov
    solvers to choose from. The default here is `lgmres`, which is a
    variant of restarted GMRES iteration that reuses some of the
    information obtained in the previous Newton steps to invert
    Jacobians in subsequent steps.

    For a review on Newton-Krylov methods, see for example [1]_,
    and for the LGMRES sparse inverse method, see [2]_.

    References
    ----------
    .. [1] C. T. Kelley, Solving Nonlinear Equations with Newton's Method,
           SIAM, pp.57-83, 2003.
           :doi:`10.1137/1.9780898718898.ch3`
    .. [2] D.A. Knoll and D.E. Keyes, J. Comp. Phys. 193, 357 (2004).
           :doi:`10.1016/j.jcp.2003.08.010`
    .. [3] A.H. Baker and E.R. Jessup and T. Manteuffel,
           SIAM J. Matrix Anal. Appl. 26, 962 (2005).
           :doi:`10.1137/S0895479803422014`

    Examples
    --------
    The following functions define a system of nonlinear equations

    >>> def fun(x):
    ...     return [x[0] + 0.5 * x[1] - 1.0,
    ...             0.5 * (x[1] - x[0]) ** 2]

    A solution can be obtained as follows.

    >>> from scipy import optimize
    >>> sol = optimize.newton_krylov(fun, [0, 0])
    >>> sol
    array([0.66731771, 0.66536458])

    Nlgmres   
   c           	      K   s^  || _ || _ttjjjtjjjtjjjtjjj	tjjj
tjjjd||| _t|| j d| _| jtjjju rI|| jd< d| jd< | jdd nG| jtjjjtjjjtjjj	fv rb| jdd n.| jtjjju r|| jd< d| jd< | jd	g  | jd
d | jdd | jdd | D ]\}}|dstd| || j|dd  < qd S )N)bicgstabgmresr&  cgsminrestfqmr)rb   r  r   r   rb   Zatolr   outer_kZouter_vZprepend_outer_vTZstore_outer_AvFZinner_zUnknown parameter %s   )preconditionerrv   r   r   r   r   r)  r*  r&  r+  r,  r-  getmethod	method_kw
setdefaultZgcrotmkr   
startswithrU   )	r}   rv   r2  Zinner_maxiterZinner_Mr.  r   keyr   r    r    r!   r~     sD   	




zKrylovJacobian.__init__c                 C   s<   t | j }t | j }| jtd| td| | _d S )Nr   )rt   r0   r$   r   rv   omega)r}   ZmxZmfr    r    r!   _update_diff_step  s    z KrylovJacobian._update_diff_stepc                 C   sl   t |}|dkrd| S | j| }| | j||  | j | }tt|s4tt|r4td|S )Nr   z$Function returned non-finite results)	r   r7  rH   r0   r   r#   r4   r3   rU   )r}   r8   ZnvZscr   r    r    r!   r     s   
 zKrylovJacobian.matvecr   c                 C   sN   d| j v r| j| j|fi | j \}}|S | j| j|fd|i| j \}}|S )NZrtol)r3  r2  op)r}   ZrhsrK   Zsolrj   r    r    r!   r     s
   
 zKrylovJacobian.solvec                 C   sD   || _ || _|   | jd urt| jdr | j|| d S d S d S )NrZ   )r0   r   r8  r0  r   rZ   )r}   r&   r   r    r    r!   rZ     s   
zKrylovJacobian.updatec                 C   s   t | ||| || _|| _tjj| | _| j	d u r%t
|jjd | _	|   | jd ur>t| jdr@| j||| d S d S d S )Nr   rR   )r   rR   r0   r   r   r   r   Zaslinearoperatorr9  rv   r#   rz   r*   r{   r8  r0  r   )r}   r&   r   rH   r    r    r!   rR     s   

zKrylovJacobian.setup)Nr&  r'  Nr(  r   )
r   r   r   r   r~   r8  r   r   rZ   rR   r    r    r    r!   r   5  s    e
/


r   c                 C   s   t |j}|\}}}}}}}	tt|t| d |}
ddd |
D }|r,d| }ddd |
D }|r<|d }|rDtd| d}|t| ||j|d }i }|	t
  t|| ||  }|j|_t| |S )	a  
    Construct a solver wrapper with given name and Jacobian approx.

    It inspects the keyword arguments of ``jac.__init__``, and allows to
    use the same arguments in the wrapper function, in addition to the
    keyword arguments of `nonlin_solve`

    Nz, c                 S   s   g | ]\}}| d |qS =r    .0r   r8   r    r    r!   
<listcomp>      z#_nonlin_wrapper.<locals>.<listcomp>c                 S   s   g | ]\}}| d | qS r:  r    r<  r    r    r!   r>    r?  zUnexpected signature %sa  
def %(name)s(F, xin, iter=None %(kw)s, verbose=False, maxiter=None,
             f_tol=None, f_rtol=None, x_tol=None, x_rtol=None,
             tol_norm=None, line_search='armijo', callback=None, **kw):
    jac = %(jac)s(%(kwkw)s **kw)
    return nonlin_solve(F, xin, jac, iter, verbose, maxiter,
                        f_tol, f_rtol, x_tol, x_rtol, tol_norm, line_search,
                        callback)
)r   r   jacZkwkw)_getfullargspecr~   listr   r   joinrU   r   r   rZ   globalsexecr   r<   )r   r@  Z	signatureargsZvarargsZvarkwdefaults
kwonlyargsZ
kwdefaults_kwargsZkw_strZkwkw_strwrappernsrH   r    r    r!   _nonlin_wrapper  s,   
	

rM  r   r   r   r   r   r   r   )r=   NFNNNNNNr>   NFT)r>   rl   rm   )<r   r[   r   Znumpyr#   r   r   r   Zscipy.linalgr   r   r   r   r	   r
   Zscipy.sparse.linalgr   Zscipy.sparser   Zscipy._lib._utilr   r   rA  Z_linesearchr   r   __all__	Exceptionr   r'   r,   r2   r9   r   stripr:   r<   rk   rY   rP   r   r   rQ   r   r   r   r   r   r   r   r   r   rM  r   r   r   r   r   r   r   r    r    r    r!   <module>   s|    

(4
 
-@H` Mr@ D.? K
,




