3

6^                 @   sP  d Z ddlmZmZm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mZmZmZ ddlZddlZddlmZ ddlZddlmZ d	d
lmZm Z  dddddddgZ!G dd de"Z#dd Z$dd Z%dd Z&dd Z'e(dj) dj) dZ*dd  Z+dId%d&Z,e+e, dJd)d*Z-G d+d, d,e.Z/G d-d. d.e.Z0G d/d0 d0e.Z1d1d2 Z2G d3d4 d4e0Z3G d5d6 d6e.Z4d7j) e*d8< G d9d: d:e3Z5G d;d< d<e5Z6G d=d> d>e3Z7G d?d@ d@e3Z8G dAdB dBe3Z9G dCdD dDe3Z:G dEdF dFe0Z;dGdH Z<e<de5Z=e<de6Z>e<de7Z?e<de9Z@e<de8ZAe<de:ZBe<de;ZCdS )Ka  

Nonlinear solvers
-----------------

.. currentmodule:: scipy.optimize

This is a collection of general-purpose nonlinear multidimensional
solvers.  These solvers find *x* for which *F(x) = 0*. Both *x*
and *F* can be multidimensional.

Routines
~~~~~~~~

Large-scale nonlinear solvers:

.. autosummary::

   newton_krylov
   anderson

General nonlinear solvers:

.. autosummary::

   broyden1
   broyden2

Simple iterations:

.. autosummary::

   excitingmixing
   linearmixing
   diagbroyden


Examples
~~~~~~~~

**Small problem**

>>> def F(x):
...    return np.cos(x) + x[::-1] - [1, 2, 3, 4]
>>> import scipy.optimize
>>> x = scipy.optimize.broyden1(F, [1,1,1,1], f_tol=1e-14)
>>> x
array([ 4.04674914,  3.91158389,  2.71791677,  1.61756251])
>>> np.cos(x) + x[::-1]
array([ 1.,  2.,  3.,  4.])


**Large problem**

Suppose that we needed to solve the following integrodifferential
equation on the square :math:`[0,1]\times[0,1]`:

.. math::

   \nabla^2 P = 10 \left(\int_0^1\int_0^1\cosh(P)\,dx\,dy\right)^2

with :math:`P(x,1) = 1` and :math:`P=0` elsewhere on the boundary of
the square.

The solution can be found using the `newton_krylov` solver:

.. plot::

   import numpy as np
   from scipy.optimize import newton_krylov
   from numpy import cosh, zeros_like, mgrid, zeros

   # parameters
   nx, ny = 75, 75
   hx, hy = 1./(nx-1), 1./(ny-1)

   P_left, P_right = 0, 0
   P_top, P_bottom = 1, 0

   def residual(P):
       d2x = zeros_like(P)
       d2y = zeros_like(P)

       d2x[1:-1] = (P[2:]   - 2*P[1:-1] + P[:-2]) / hx/hx
       d2x[0]    = (P[1]    - 2*P[0]    + P_left)/hx/hx
       d2x[-1]   = (P_right - 2*P[-1]   + P[-2])/hx/hx

       d2y[:,1:-1] = (P[:,2:] - 2*P[:,1:-1] + P[:,:-2])/hy/hy
       d2y[:,0]    = (P[:,1]  - 2*P[:,0]    + P_bottom)/hy/hy
       d2y[:,-1]   = (P_top   - 2*P[:,-1]   + P[:,-2])/hy/hy

       return d2x + d2y - 10*cosh(P).mean()**2

   # solve
   guess = zeros((nx, ny), float)
   sol = newton_krylov(residual, guess, method='lgmres', verbose=1)
   print('Residual: %g' % abs(residual(sol)).max())

   # visualize
   import matplotlib.pyplot as plt
   x, y = mgrid[0:1:(nx*1j), 0:1:(ny*1j)]
   plt.pcolor(x, y, sol)
   plt.colorbar()
   plt.show()

    )divisionprint_functionabsolute_importN)callableexec_xrange)normsolveinvqrsvdLinAlgError)asarraydotvdot)get_blas_funcs)getargspec_no_self   )scalar_search_wolfe1scalar_search_armijobroyden1broyden2andersonlinearmixingdiagbroydenexcitingmixingnewton_krylovc               @   s   e Zd ZdS )NoConvergenceN)__name__
__module____qualname__ r!   r!   6/tmp/pip-build-vw4w4j08/scipy/scipy/optimize/nonlin.pyr      s   r   c             C   s   t j| j S )N)npZabsolutemax)xr!   r!   r"   maxnorm   s    r&   c             C   s*   t | } tj| 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float_)r%   r!   r!   r"   _as_inexact   s    r)   c             C   s(   t j| t j|} 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_like   s    r/   c             C   s"   t j| j st jt jS t| S )N)r#   isfiniteallarrayinfr   )vr!   r!   r"   
_safe_norm   s    r5   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 )N)__doc__
_doc_parts)objr!   r!   r"   _set_doc   s    r9   krylovFarmijoTc                 sb  |
dkrt n|
}
t||||	||
d}t fdd}j }tj}||}t|}t|}|j|j	 || |dkr|dk	r|d }nd|j
d  }|dkrd}n|d	krd}|dkrtdd}d}d}d}xHt|D ] }|j|||}| rP t||| }|j||d }t|dkr0td|rPt|||||\}}}}nd}|| }||}t|}|j|j	 | |r||| ||d  |d  }||d  |k rt||}nt|t|||d  }|}|rtjjd||
||f  tjj  qW |rtt|nd}|rT|j|||dkddd| d}t||fS t|S d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| j S )N)r)   r/   flatten)z)Fr-   r!   r"   <lambda>  s    znonlin_solve.<locals>.<lambda>r   d   Tr;   FwolfezInvalid line searchg?gH.?g?gMbP?)tolr   z[Jacobian inversion yielded zero vector. This indicates a bug in the Jacobian approximation.g      ?   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   rH   )ZnitZfunstatussuccessmessage)Nr;   rF   )r&   TerminationConditionr)   rA   r#   r3   r   
asjacobiansetupcopysize
ValueErrorr   checkminr	   _nonlin_line_searchupdater$   sysstdoutwriteflushr   r/   	iteration) rC   r-   jacobianr@   verbosemaxiterr<   r=   r>   r?   Ztol_normZline_searchcallbackZfull_outputZraise_exception	conditionfuncr%   dxFxFx_normgammaZeta_maxZeta_tresholdetanrI   rG   sZFx_norm_newZeta_Ainfor!   )rC   r-   r"   nonlin_solve   s    -




ri   :0yE>{Gz?c                s   dg|gt |d gt t   d fdd	fdd}|dkrxt|d d	|d
\}}	}
n&|dkrtd d  |d\}}	|d krd}|   |d kr̈d }n}t |}|||fS )Nr   rH   Tc                sT   | d krd S |    }|}t |d }|rP| d< |d< |d< |S )Nr   rH   )r5   )rg   storeZxtr4   p)ra   r`   tmp_Fxtmp_phitmp_sr%   r!   r"   phi|  s    z _nonlin_line_search.<locals>.phic                s0   t |  d  } | | dd |  | S )Nr   F)rl   )abs)rg   ds)rq   rdiffs_normr!   r"   derphi  s    z#_nonlin_line_search.<locals>.derphirF   g{Gz?)Zxtolaminr;   )rw   g      ?)T)r   r   r   )r`   r%   rb   ra   Zsearch_typert   Zsminrv   rg   Zphi1Zphi0rc   r!   )	ra   r`   rq   rt   ru   rn   ro   rp   r%   r"   rT   u  s(    
rT   c               @   s.   e Zd ZdZdddddefddZdd ZdS )rL   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 krt jt jjd }|d kr(t j}|d kr6t j}|d krDt j}|| _|| _|| _|| _|| _	|| _
d | _d| _d S )Ng      ?   r   gUUUUUU?)r#   finfor(   epsr3   r>   r?   r<   r=   r   r@   f0_normrZ   )selfr<   r=   r>   r?   r@   r   r!   r!   r"   __init__  s     zTerminationCondition.__init__c             C   s   |  j d7  _ | j|}| j|}| j|}| jd kr<|| _|dkrHdS | jd k	rbd| j | jk S t|| jko|| j | jko|| jko|| j |kS )Nr   r   rH   )	rZ   r   r{   r@   intr<   r=   r>   r?   )r|   fr%   ra   Zf_normZx_normdx_normr!   r!   r"   rR     s    





zTerminationCondition.check)r   r   r    r6   r&   r}   rR   r!   r!   r!   r"   rL     s   rL   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          	      st   ddddddddd	g	}x@|j  D ]4\}}||kr<td
| |d k	r t |||  q W t drp fdd _d S )Nr	   rU   matvecrmatvecrsolveZmatmattodenser+   r'   zUnknown keyword argument %sc                  s    j  S )N)r   r!   )r|   r!   r"   rD     s    z#Jacobian.__init__.<locals>.<lambda>)itemsrQ   setattrhasattr	__array__)r|   kwnamesnamevaluer!   )r|   r"   r}     s    

zJacobian.__init__c             C   s   t | S )N)InverseJacobian)r|   r!   r!   r"   aspreconditioner  s    zJacobian.aspreconditionerr   c             C   s   t d S )N)NotImplementedError)r|   r4   rG   r!   r!   r"   r	     s    zJacobian.solvec             C   s   d S )Nr!   )r|   r%   rC   r!   r!   r"   rU     s    zJacobian.updatec             C   s:   || _ |j|jf| _|j| _| jjtjkr6| j|| d S )N)r`   rP   r+   r'   	__class__rN   r   rU   )r|   r%   rC   r`   r!   r!   r"   rN     s
    zJacobian.setupN)r   )	r   r   r    r6   r}   r   r	   rU   rN   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   s>   || _ |j| _|j| _t|dr(|j| _t|dr:|j| _d S )NrN   r   )r[   r	   r   rU   r   rN   r   r   )r|   r[   r!   r!   r"   r}   '  s    

zInverseJacobian.__init__c             C   s   | j jS )N)r[   r+   )r|   r!   r!   r"   r+   0  s    zInverseJacobian.shapec             C   s   | j jS )N)r[   r'   )r|   r!   r!   r"   r'   4  s    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j r2t tr2  S t t	j
r jdkrPtdt	jt	j   jd  jd kr|tdt fdd fdd fd	d fd
d j jdS t jj r jd  jd krtdt fdd fdd fdd fdd j jdS t drzt drzt drzt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dS )zE
    Convert given object to one suitable for use as a Jacobian.
    rH   zarray must have rank <= 2r   r   zarray must be squarec                s
   t  | S )N)r   )r4   )Jr!   r"   rD   I  s    zasjacobian.<locals>.<lambda>c                s   t  j j| S )N)r   conjT)r4   )r   r!   r"   rD   J  s    c                s
   t  | S )N)r	   )r4   )r   r!   r"   rD   K  s    c                s   t  j j| S )N)r	   r   r   )r4   )r   r!   r"   rD   L  s    )r   r   r	   r   r'   r+   zmatrix must be squarec                s    |  S )Nr!   )r4   )r   r!   r"   rD   Q  s    c                s    j  j|  S )N)r   r   )r4   )r   r!   r"   rD   R  s    c                s
    | S )Nr!   )r4   )r   spsolver!   r"   rD   S  s    c                s    j  j| S )N)r   r   )r4   )r   r   r!   r"   rD   T  s    r+   r'   r	   r   r   r   rU   rN   )r   r   r	   r   rU   rN   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 )N)r%   )r|   r%   rC   r!   r!   r"   rU   b  s    zasjacobian.<locals>.Jac.updater   c                sB    | j }t|tjr t||S tjj|r6||S tdd S )NzUnknown matrix type)	r%   
isinstancer#   ndarrayr	   scipysparse
isspmatrixrQ   )r|   r4   rG   m)r   r   r!   r"   r	   e  s    


zasjacobian.<locals>.Jac.solvec                s@    | j }t|tjr t||S tjj|r4|| S tdd S )NzUnknown matrix type)	r%   r   r#   r   r   r   r   r   rQ   )r|   r4   r   )r   r!   r"   r   n  s    

zasjacobian.<locals>.Jac.matvecc                sN    | j }t|tjr&t|j j|S tjj	|rB|j j|S t
dd S )NzUnknown matrix type)r%   r   r#   r   r	   r   r   r   r   r   rQ   )r|   r4   rG   r   )r   r   r!   r"   r   w  s    
zasjacobian.<locals>.Jac.rsolvec                sL    | j }t|tjr&t|j j|S tjj	|r@|j j| S t
dd S )NzUnknown matrix type)r%   r   r#   r   r   r   r   r   r   r   rQ   )r|   r4   r   )r   r!   r"   r     s    
zasjacobian.<locals>.Jac.rmatvecN)r   )r   )r   r   r    rU   r	   r   r   r   r!   )r   r   r!   r"   Jaca  s
   			r   )r   r   r   r   r   r   r:   z#Cannot convert object to a JacobianN) r   r   linalgr   r   r   inspectZisclass
issubclassr#   r   ndimrQ   Z
atleast_2dr   r+   r'   r   r   r,   r	   r   strdictBroydenFirstBroydenSecondAndersonDiagBroydenLinearMixingExcitingMixingKrylovJacobian	TypeError)r   r   r!   )r   r   r"   rM   9  sZ    






$


'rM   c               @   s$   e Zd Zdd Zdd Zdd ZdS )GenericBroydenc             C   s`   t j| ||| || _|| _t| dr\| jd kr\t|}|rVdtt|d | | _nd| _d S )Nalphag      ?r   g      ?)r   rN   last_flast_xr   r   r   r$   )r|   r-   f0r`   Znormf0r!   r!   r"   rN     s    zGenericBroyden.setupc             C   s   t d S )N)r   )r|   r%   r   ra   dfr   df_normr!   r!   r"   _update  s    zGenericBroyden._updatec             C   s@   || j  }|| j }| j||||t|t| || _ || _d S )N)r   r   r   r   )r|   r%   r   r   ra   r!   r!   r"   rU     s
    

zGenericBroyden.updateN)r   r   r    rN   r   rU   r!   r!   r!   r"   r     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 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 )N)r   csrs   rf   r'   	collapsed)r|   r   rf   r'   r!   r!   r"   r}     s    zLowRankMatrix.__init__c             C   sb   t dddg|d d | g \}}}||  }x0t||D ]"\}}	||	| }
||||j|
}q8W |S )Naxpyscaldotcr   )r   ziprP   )r4   r   r   rs   r   r   r   wcdar!   r!   r"   _matvec  s    

zLowRankMatrix._matvecc             C   s  t |dkr| | S tddg|dd | g \}}|d }|tjt ||jd }xDt|D ]8\}}	x.t|D ]"\}
}|||
f  ||	|7  < qpW q^W tjt ||jd}x"t|D ]\}
}	||	| ||
< qW || }t||}| | }x(t||D ]\}}||||j	| }qW |S )zEvaluate w = M^-1 vr   r   r   Nr   )r'   )
lenr   r#   identityr'   	enumeratezerosr	   r   rP   )r4   r   r   rs   r   r   Zc0Air   jr   qr   Zqcr!   r!   r"   _solve  s"     "
zLowRankMatrix._solvec             C   s.   | j dk	rtj| j |S tj|| j| j| jS )zEvaluate w = M vN)r   r#   r   r   r   r   r   rs   )r|   r4   r!   r!   r"   r     s    
zLowRankMatrix.matvecc             C   s:   | j dk	rtj| j jj |S tj|tj| j| j| j	S )zEvaluate w = M^H vN)
r   r#   r   r   r   r   r   r   rs   r   )r|   r4   r!   r!   r"   r     s    
zLowRankMatrix.rmatvecr   c             C   s,   | j dk	rt| j |S tj|| j| j| jS )zEvaluate w = M^-1 vN)r   r	   r   r   r   r   rs   )r|   r4   rG   r!   r!   r"   r	     s    
zLowRankMatrix.solvec             C   s8   | j dk	rt| j jj |S tj|tj| j| j| j	S )zEvaluate w = M^-H vN)
r   r	   r   r   r   r   r#   r   rs   r   )r|   r4   rG   r!   r!   r"   r     s    
zLowRankMatrix.rsolvec             C   sp   | j d k	r<|  j |d d d f |d d d f j  7  _ d S | jj| | jj| t| j|jkrl| j  d S )N)r   r   r   appendrs   r   rP   collapse)r|   r   r   r!   r!   r"   r     s    
.zLowRankMatrix.appendc             C   sp   | j d k	r| j S | jtj| j| jd }xBt| j| jD ]0\}}||d d d f |d d d f j	  7 }q8W |S )N)r'   )
r   r   r#   r   rf   r'   r   r   rs   r   )r|   Gmr   r   r!   r!   r"   r     s    
,zLowRankMatrix.__array__c             C   s"   t j| | _d| _d| _d| _dS )z0Collapse the low-rank matrix to a full-rank one.N)r#   r2   r   r   rs   r   )r|   r!   r!   r"   r     s    zLowRankMatrix.collapsec             C   sD   | j dk	rdS |dkstt| j|kr@| jdd= | jdd= dS )zH
        Reduce the rank of the matrix by dropping all vectors.
        Nr   )r   AssertionErrorr   r   rs   )r|   rankr!   r!   r"   restart_reduce  s    
zLowRankMatrix.restart_reducec             C   sB   | j dk	rdS |dkstx"t| j|kr<| jd= | jd= qW dS )zK
        Reduce the rank of the matrix by dropping oldest vectors.
        Nr   )r   r   r   r   rs   )r|   r   r!   r!   r"   simple_reduce*  s    
zLowRankMatrix.simple_reduceNc             C   s<  | j dk	rdS |}|dk	r |}n|d }| jrBt|t| jd }tdt||d }t| j}||k rldS tj| jj}tj| jj}t	|dd\}}t
||jj }t|ddd	\}	}
}t
|t|}t
||jj }xDt|D ]8}|dd|f j | j|< |dd|f j | j|< qW | 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

        NrH   r   r   Zeconomic)modeFT)Zfull_matricesZ
compute_uv)r   r   rS   r   r$   r#   r2   r   rs   r   r   r   r   r
   r   rO   )r|   max_rankZ	to_retainrm   r   r   CDRUSZWHkr!   r!   r"   
svd_reduce5  s0    

zLowRankMatrix.svd_reduce)r   )r   )N)r   r   r    r6   r}   staticmethodr   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 (ie., 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

    Nrestartc                s   t j |_d _|d kr$tj}|_t|tr:f  n|dd   |d }|d f   |dkrv fdd_	n@|dkr fdd_	n&|dkr fd	d_	nt
d
| d S )Nr   r   r   c                  s   j j  S )N)r   r   r!   )reduce_paramsr|   r!   r"   rD     s    z'BroydenFirst.__init__.<locals>.<lambda>simplec                  s   j j  S )N)r   r   r!   )r   r|   r!   r"   rD     s    r   c                  s   j j  S )N)r   r   r!   )r   r|   r!   r"   rD     s    z"Unknown rank reduction method '%s')r   r}   r   r   r#   r3   r   r   r   _reducerQ   )r|   r   Zreduction_methodr   r!   )r   r|   r"   r}     s&    

zBroydenFirst.__init__c             C   s.   t j| ||| t| j | jd | j| _d S )Nr   )r   rN   r   r   r+   r'   r   )r|   r%   rC   r`   r!   r!   r"   rN     s    zBroydenFirst.setupc             C   s
   t | jS )N)r
   r   )r|   r!   r!   r"   r     s    zBroydenFirst.todenser   c             C   s:   | j j|}tj|j s.| j| j| j| j | j j|S )N)	r   r   r#   r0   r1   rN   r   r   r`   )r|   r   rG   rr!   r!   r"   r	     s    zBroydenFirst.solvec             C   s   | j j|S )N)r   r	   )r|   r   r!   r!   r"   r     s    zBroydenFirst.matvecc             C   s   | j j|S )N)r   r   )r|   r   rG   r!   r!   r"   r     s    zBroydenFirst.rsolvec             C   s   | j j|S )N)r   r   )r|   r   r!   r!   r"   r     s    zBroydenFirst.rmatvecc       
      C   sD   | j   | jj|}|| jj| }|t|| }	| jj||	 d S )N)r   r   r   r   r   r   )
r|   r%   r   ra   r   r   r   r4   r   r   r!   r!   r"   r     s
    zBroydenFirst._update)Nr   N)r   )r   )r   r   r    r6   r}   rN   r   r	   r   r   r   r   r!   r!   r!   r"   r     s   %


r   c               @   s   e Zd ZdZdd ZdS )r   a  
    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

    c       
      C   s:   | j   |}|| jj| }||d  }	| jj||	 d S )NrH   )r   r   r   r   )
r|   r%   r   ra   r   r   r   r4   r   r   r!   r!   r"   r     s
    zBroydenSecond._updateN)r   r   r    r6   r   r!   r!   r!   r"   r     s   "r   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   av  
    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).

    N{Gz?   c             C   s2   t j|  || _|| _g | _g | _d | _|| _d S )N)r   r}   r   Mra   r   rd   w0)r|   r   r   r   r!   r!   r"   r}   Z  s    
zAnderson.__init__r   c       	      C   s   | j  | }t| j}|dkr"|S tj||jd}x$t|D ]}t| j| |||< q<W yt	| j
|}W n, tk
r   | jd d = | jd d = |S X x6t|D ]*}||| | j| | j | j|    7 }qW |S )Nr   )r'   )r   r   ra   r#   emptyr'   r   r   r   r	   r   r   )	r|   r   rG   ra   rf   df_fr   rd   r   r!   r!   r"   r	   c  s     
*zAnderson.solvec          	   C   s>  | | j  }t| j}|dkr"|S tj||jd}x$t|D ]}t| j| |||< q<W tj||f|jd}xt|D ]|}xvt|D ]j}t| j| | j| |||f< ||kr| j	dkr|||f  t| j| | j| | j	d  | j  8  < qW qvW t
||}	x8t|D ],}
||	|
 | j|
 | j|
 | j    7 }q
W |S )Nr   )r'   rH   )r   r   ra   r#   r   r'   r   r   r   r   r	   )r|   r   ra   rf   r   r   br   r   rd   r   r!   r!   r"   r   z  s"    
>
,zAnderson.matvecc             C   s   | j dkrd S | jj| | jj| x,t| j| j krR| jjd | jjd q(W t| j}tj||f|jd}xbt	|D ]V}	xPt	|	|D ]B}
|	|
kr| j
d }nd}d| t| j|	 | j|
  ||	|
f< qW q|W |tj|djj 7 }|| _d S )Nr   )r'   rH   r   )r   ra   r   r   r   popr#   r   r'   r   r   r   Ztriur   r   r   )r|   r%   r   ra   r   r   r   rf   r   r   r   wdr!   r!   r"   r     s"    

.zAnderson._update)Nr   r   )r   )r   r   r    r6   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 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.
    Nc             C   s   t j|  || _d S )N)r   r}   r   )r|   r   r!   r!   r"   r}     s    
zDiagBroyden.__init__c             C   s6   t j| ||| tj| jd fd| j | jd| _d S )Nr   r   )r'   )r   rN   r#   fullr+   r   r'   r   )r|   r%   rC   r`   r!   r!   r"   rN     s    zDiagBroyden.setupr   c             C   s   | | j  S )N)r   )r|   r   rG   r!   r!   r"   r	     s    zDiagBroyden.solvec             C   s   | | j  S )N)r   )r|   r   r!   r!   r"   r     s    zDiagBroyden.matvecc             C   s   | | j j  S )N)r   r   )r|   r   rG   r!   r!   r"   r     s    zDiagBroyden.rsolvec             C   s   | | j j  S )N)r   r   )r|   r   r!   r!   r"   r     s    zDiagBroyden.rmatvecc             C   s   t j| j S )N)r#   diagr   )r|   r!   r!   r"   r     s    zDiagBroyden.todensec             C   s(   |  j || j |  | |d  8  _ d S )NrH   )r   )r|   r%   r   ra   r   r   r   r!   r!   r"   r     s    zDiagBroyden._update)N)r   )r   )r   r   r    r6   r}   rN   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   s   t j|  || _d S )N)r   r}   r   )r|   r   r!   r!   r"   r}     s    
zLinearMixing.__init__r   c             C   s   | | j  S )N)r   )r|   r   rG   r!   r!   r"   r	     s    zLinearMixing.solvec             C   s   | | j  S )N)r   )r|   r   r!   r!   r"   r     s    zLinearMixing.matvecc             C   s   | t j| j S )N)r#   r   r   )r|   r   rG   r!   r!   r"   r     s    zLinearMixing.rsolvec             C   s   | t j| j S )N)r#   r   r   )r|   r   r!   r!   r"   r     s    zLinearMixing.rmatvecc             C   s   t jt j| jd d| j S )Nr   r   )r#   r   r   r+   r   )r|   r!   r!   r"   r   
  s    zLinearMixing.todensec             C   s   d S )Nr!   )r|   r%   r   ra   r   r   r   r!   r!   r"   r     s    zLinearMixing._update)N)r   )r   )r   r   r    r6   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
    N      ?c             C   s    t j|  || _|| _d | _d S )N)r   r}   r   alphamaxbeta)r|   r   r   r!   r!   r"   r}   ,  s    
zExcitingMixing.__init__c             C   s2   t j| ||| tj| jd f| j| jd| _d S )Nr   )r'   )r   rN   r#   r   r+   r   r'   r   )r|   r%   rC   r`   r!   r!   r"   rN   2  s    zExcitingMixing.setupr   c             C   s   | | j  S )N)r   )r|   r   rG   r!   r!   r"   r	   6  s    zExcitingMixing.solvec             C   s   | | j  S )N)r   )r|   r   r!   r!   r"   r   9  s    zExcitingMixing.matvecc             C   s   | | j j  S )N)r   r   )r|   r   rG   r!   r!   r"   r   <  s    zExcitingMixing.rsolvec             C   s   | | j j  S )N)r   r   )r|   r   r!   r!   r"   r   ?  s    zExcitingMixing.rmatvecc             C   s   t jd| j S )Nr   r   )r#   r   r   )r|   r!   r!   r"   r   B  s    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   ra   r   r   r   incrr!   r!   r"   r   E  s    zExcitingMixing._update)Nr   )r   )r   )r   r   r    r6   r}   rN   r	   r   r   r   r   r   r!   r!   r!   r"   r     s   


r   c               @   sD   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 : {'lgmres', 'gmres', 'bicgstab', 'cgs', 'minres'} or function
        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`.

        The default is `scipy.sparse.linalg.lgmres`.
    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.nonlin import BroydenFirst, KrylovJacobian
        >>> from scipy.optimize.nonlin 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.
    inner_tol, inner_maxiter, ...
        Parameters to pass on to the \"inner\" Krylov solver.
        See `scipy.sparse.linalg.gmres` for details.
    outer_k : int, optional
        Size of the subspace kept across LGMRES nonlinear iterations.
        See `scipy.sparse.linalg.lgmres` 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] D.A. Knoll and D.E. Keyes, J. Comp. Phys. 193, 357 (2004).
           :doi:`10.1016/j.jcp.2003.08.010`
    .. [2] A.H. Baker and E.R. Jessup and T. Manteuffel,
           SIAM J. Matrix Anal. Appl. 26, 962 (2005).
           :doi:`10.1137/S0895479803422014`

    Nlgmres   
   c       	      K   sN  || _ || _ttjjjtjjjtjjjtjjj	tjjj
dj||| _t|| j d| _| jtjjjkr|| jd< d| jd< | jjdd n~| jtjjjkr| jjdd n^| jtjjjkr|| jd< d| jd< | jjd	g  | jjd
d | jjdd | jjdd x@|j D ]4\}}|jds2td| || j|dd  < qW d S )N)bicgstabgmresr   cgsminres)r]   r   Zrestrtr   r]   Zatolr   outer_kZouter_vZprepend_outer_vTZstore_outer_AvFZinner_zUnknown parameter %s   )preconditionerrt   r   r   r   r   r   r   r   r   r   getmethod	method_kw
setdefaultZgcrotmkr   
startswithrQ   )	r|   rt   r   Zinner_maxiterZinner_Mr   r   keyr   r!   r!   r"   r}     s6    




zKrylovJacobian.__init__c             C   s<   t | jj }t | jj }| jtd| td| | _d S )Nr   )rr   r-   r$   r   rt   omega)r|   ZmxZmfr!   r!   r"   _update_diff_step  s    z KrylovJacobian._update_diff_stepc             C   sn   t |}|dkrd| S | j| }| j| j||  | j | }tjtj| rjtjtj|rjtd|S )Nr   z$Function returned non-finite results)	r   r   r`   r-   r   r#   r1   r0   rQ   )r|   r4   nvZscr   r!   r!   r"   r     s    
"zKrylovJacobian.matvecr   c             C   sH   d| j kr$| j| j|f| j \}}n | j| j|fd|i| j \}}|S )NrG   )r   r   op)r|   rhsrG   Zsolrh   r!   r!   r"   r	     s    
 zKrylovJacobian.solvec             C   s<   || _ || _| j  | jd k	r8t| jdr8| jj|| d S )NrU   )r-   r   r  r   r   rU   )r|   r%   r   r!   r!   r"   rU     s    
zKrylovJacobian.updatec             C   s|   t j| ||| || _|| _tjjj| | _| j	d krJt
j|jjd | _	| j  | jd k	rxt| jdrx| jj||| d S )Ng      ?rH   rN   g      ?)r   rN   r-   r   r   r   r   Zaslinearoperatorr  rt   r#   ry   r'   rz   r  r   r   )r|   r%   r   r`   r!   r!   r"   rN     s    

zKrylovJacobian.setup)Nr   r   Nr   )r   )
r   r   r    r6   r}   r  r   r	   rU   rN   r!   r!   r!   r"   r   P  s   J 
)


r   c             C   s   t |j\}}}}tt|t| d |}djdd |D }|rNd| }djdd |D }|rn|d }d}	|	t| ||j|d }	i }
|
j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 ||f qS )z%s=%rr!   ).0r   r4   r!   r!   r"   
<listcomp>  s    z#_nonlin_wrapper.<locals>.<listcomp>c             S   s   g | ]\}}d ||f qS )z%s=%sr!   )r  r   r4   r!   r!   r"   r  	  s    a  
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)_getargspecr}   listr   r   joinr   r   rU   globalsr   r6   r9   )r   r  argsZvarargsZvarkwdefaultskwargsZkw_strZkwkw_strwrappernsr`   r!   r!   r"   _nonlin_wrapper  s$    	

r  )r:   NFNNNNNNr;   NFT)r;   rj   rk   )Dr6   
__future__r   r   r   rV   Znumpyr#   Zscipy._lib.sixr   r   r   Zscipy.linalgr   r	   r
   r   r   r   r   r   r   Zscipy.sparse.linalgr   Zscipy.sparser   r   Zscipy._lib._utilr   r  Z
linesearchr   r   __all__	Exceptionr   r&   r)   r/   r5   r   stripr7   r9   ri   rT   objectrL   r   r   rM   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r   r   r!   r!   r!   r"   <module>j   sp    

)   
  
,@D` Zb1 4.? ,)





