o
    	h|=                     @   s   d dl Zd dlmZ d dlmZmZmZmZm	Z	m
Z
 ddlmZ d dlmZ dgZ			dd
dZdddddddddd	dd
ddZdS )    N)LinAlgError)get_blas_funcsqrsolvesvd	qr_insertlstsq   )_get_atol_rtol)make_systemgcrotmk Fc	           "   
   C   s  |du rdd }|du rdd }t g d|f\}	}
}}|g}g }d}tj}|t| }tjt||f|jd}tjd|jd}tjd	|jd}t|jj}d
}t	|D ];}|rg|t|k rg|| \}}n.|rv|t|krv||}d}n|s||t| kr|||t|   \}}n||d }d}|du r|| |}n|
 }||}t|D ]\}}|
||}||||f< |	|||jd | }qtj|d |jd}t|D ]\}}|
||}|||< |	|||jd | }q||||d < tjddd d|d  }W d   n	1 sw   Y  t|r|||}|d || ks*d}|| || tj|d |d f|jdd}||d|d d|d f< d||d |d f< tj|d |f|jdd} || d|d ddf< t|| ||ddd
d\}}t|d }||k s|r nqUt|||f st t|d|d d|d f |dd|d f  \}}!}!}!|ddd|d f }|||||||fS )a  
    FGMRES Arnoldi process, with optional projection or augmentation

    Parameters
    ----------
    matvec : callable
        Operation A*x
    v0 : ndarray
        Initial vector, normalized to nrm2(v0) == 1
    m : int
        Number of GMRES rounds
    atol : float
        Absolute tolerance for early exit
    lpsolve : callable
        Left preconditioner L
    rpsolve : callable
        Right preconditioner R
    cs : list of (ndarray, ndarray)
        Columns of matrices C and U in GCROT
    outer_v : list of ndarrays
        Augmentation vectors in LGMRES
    prepend_outer_v : bool, optional
        Whether augmentation vectors come before or after
        Krylov iterates

    Raises
    ------
    LinAlgError
        If nans encountered

    Returns
    -------
    Q, R : ndarray
        QR decomposition of the upper Hessenberg H=QR
    B : ndarray
        Projections corresponding to matrix C
    vs : list of ndarray
        Columns of matrix V
    zs : list of ndarray
        Columns of matrix Z
    y : ndarray
        Solution to ||H y - e_1||_2 = min!
    res : float
        The final (preconditioned) residual norm

    Nc                 S      | S Nr   xr   r   X/var/www/vscode/kcb/lib/python3.10/site-packages/scipy/sparse/linalg/_isolve/_gcrotmk.pylpsolve@      z_fgmres.<locals>.lpsolvec                 S   r   r   r   r   r   r   r   rpsolveC   r   z_fgmres.<locals>.rpsolveaxpydotscalnrm2)dtype)r	   r	   )r	   r   Fr      r	   ignore)overdivideTFr   ordercol)whichoverwrite_qrucheck_finite)r   r   )r   npnanlenzerosr   onesfinfoepsrangecopy	enumerateshapeerrstateisfiniteappendr   absr   r   conj)"matvecv0matolr   r   csouter_vprepend_outer_vr   r   r   r   vszsyresBQRr.   	breakdownjzww_normicalphahcurvQ2R2_r   r   r   _fgmres   s   1





>rS   gh㈵>g        i     oldest)
rtolr;   maxiterMcallbackr:   kCU	discard_Ctruncatec       
   A   
   C   s  t | |||\} }}}}t| std|dvr"td|| j}|j}|
du r.g }
|	du r4|}	d\}}}|du rB| }n||| }tg d||f\}}}}||}td|||\}}|dkrn|}||dfS |r{d	d
 |
D |
dd< |
r-|
j	dd d tj
| jd t|
f|jdd}g }d}|
r|
d\}}|du r||}||dd|f< |d7 }|| |
st|dddd\}}}~t|j}g } tt|D ]E}|||  }t|D ]}!||||!  ||jd ||!|f  }qt|||f dt|d  k r n|d|||f  |}| | qtt|| ddd |
dd< |
r\tddg|f\}}|
D ]\}}|||}"||||jd |"}||||jd |" }q<t|D ]}#|durl|| ||}$t||| }%|$|%kr|#dks|
r||| }||}$|$|%krd}# n|t|	t|
 d }&dd
 |
D }z t|||$ |&|t||| |$ |d\}}}'}(})}*}+|*|$9 }*W n ty   Y  nw |)d |*d  },t|)dd |*dd D ]\}-}"||-|,|,jd |"},q|'|*}.t|
|.D ]\}/}0|/\}}|||,|,jd |0 },q|||*}1|(d |1d  }2t|(dd |1dd D ]\}3}4||3|2|2jd |4}2q8zd||2 }5t|5sXt W n ttfyf   Y q`w ||5|2}2||5|,},||2|}6||2||jd |6 }||,||jd |6}|dkrt|
|	kr|
r|
d= t|
|	kr|
sn|dkrdt|
|	krd|
rdt|ddddf j|'jj}7t|7\}8}9}:g };t|8ddd|	d f jD ]~\}}<|
d \}}||<d  }||<d  }t|
dd |<dd D ]\}=}>|=\}?}@||?||jd |>}||@||jd |>}q|;D ] \}?}@||?|}5||?||jd |5 }||@||jd |5 }q"||}5|d|5 |}|d|5 |}|;||f q|;|
dd< |
|2|,f q`|
d| f |rdd
 |
D |
dd< |||#d fS )a  
    Solve a matrix equation using flexible GCROT(m,k) algorithm.

    Parameters
    ----------
    A : {sparse array, ndarray, LinearOperator}
        The real or complex N-by-N matrix of the linear system.
        Alternatively, `A` can be a linear operator which can
        produce ``Ax`` using, e.g.,
        `LinearOperator`.
    b : ndarray
        Right hand side of the linear system. Has shape (N,) or (N,1).
    x0 : ndarray
        Starting guess for the solution.
    rtol, atol : float, optional
        Parameters for the convergence test. For convergence,
        ``norm(b - A @ x) <= max(rtol*norm(b), atol)`` should be satisfied.
        The default is ``rtol=1e-5`` and ``atol=0.0``.
    maxiter : int, optional
        Maximum number of iterations.  Iteration will stop after maxiter
        steps even if the specified tolerance has not been achieved. The
        default is ``1000``.
    M : {sparse array, ndarray, LinearOperator}, optional
        Preconditioner for `A`.  The preconditioner should approximate the
        inverse of `A`. gcrotmk is a 'flexible' algorithm and the preconditioner
        can vary from iteration to iteration. Effective preconditioning
        dramatically improves the rate of convergence, which implies that
        fewer iterations are needed to reach a given error tolerance.
    callback : function, optional
        User-supplied function to call after each iteration.  It is called
        as ``callback(xk)``, where ``xk`` is the current solution vector.
    m : int, optional
        Number of inner FGMRES iterations per each outer iteration.
        Default: 20
    k : int, optional
        Number of vectors to carry between inner FGMRES iterations.
        According to [2]_, good values are around `m`.
        Default: `m`
    CU : list of tuples, optional
        List of tuples ``(c, u)`` which contain the columns of the matrices
        C and U in the GCROT(m,k) algorithm. For details, see [2]_.
        The list given and vectors contained in it are modified in-place.
        If not given, start from empty matrices. The ``c`` elements in the
        tuples can be ``None``, in which case the vectors are recomputed
        via ``c = A u`` on start and orthogonalized as described in [3]_.
    discard_C : bool, optional
        Discard the C-vectors at the end. Useful if recycling Krylov subspaces
        for different linear systems.
    truncate : {'oldest', 'smallest'}, optional
        Truncation scheme to use. Drop: oldest vectors, or vectors with
        smallest singular values using the scheme discussed in [1,2].
        See [2]_ for detailed comparison.
        Default: 'oldest'

    Returns
    -------
    x : ndarray
        The solution found.
    info : int
        Provides convergence information:

        * 0  : successful exit
        * >0 : convergence to tolerance not achieved, number of iterations

    References
    ----------
    .. [1] E. de Sturler, ''Truncation strategies for optimal Krylov subspace
           methods'', SIAM J. Numer. Anal. 36, 864 (1999).
    .. [2] J.E. Hicken and D.W. Zingg, ''A simplified and flexible variant
           of GCROT for solving nonsymmetric linear systems'',
           SIAM J. Sci. Comput. 32, 172 (2010).
    .. [3] M.L. Parks, E. de Sturler, G. Mackey, D.D. Johnson, S. Maiti,
           ''Recycling Krylov subspaces for sequences of linear systems'',
           SIAM J. Sci. Comput. 28, 1651 (2006).

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.sparse import csc_array
    >>> from scipy.sparse.linalg import gcrotmk
    >>> R = np.random.randn(5, 5)
    >>> A = csc_array(R)
    >>> b = np.random.randn(5)
    >>> x, exit_code = gcrotmk(A, b, atol=1e-5)
    >>> print(exit_code)
    0
    >>> np.allclose(A.dot(x), b)
    True

    z$RHS must contain only finite numbers)rU   smallestzInvalid value for 'truncate': N)NNNr   r   r   c                 S      g | ]\}}d |fqS r   r   .0rL   ur   r   r   
<listcomp>8      zgcrotmk.<locals>.<listcomp>c                 S   s   | d d uS )Nr   r   )cur   r   r   <lambda>=  s    zgcrotmk.<locals>.<lambda>)keyr!   r"   r	   Teconomic)overwrite_amodepivotingg-q=)r   r   g      ?r   r   r   c                 S   s   g | ]\}}|qS r   r   r`   r   r   r   rc     s    )r   r;   r<   rU   r^   c                 S   r_   r   r   )ra   czuzr   r   r   rc     rd   )r   r(   r4   all
ValueErrorr8   r0   r   r
   sortemptyr2   r*   r   popr5   r   listTr/   r6   zipmaxrS   r   r   FloatingPointErrorZeroDivisionErrorr   r   r1   )AAbx0rV   r;   rW   rX   rY   r:   rZ   r[   r\   r]   r   postprocessr8   psolver   r   r   rr   b_normCusrG   rL   rb   rD   rE   Pr<   new_usrK   ycj_outerbetabeta_tolmlrC   r?   r@   rA   presuxrH   byre   bychycxrO   hycrM   gammaDWsigmaVnew_CUrI   cupwpcpupr   r   r   r      s  \

 


(" 



"
"




 &"
)NNr   r   Fr   )numpyr(   numpy.linalgr   scipy.linalgr   r   r   r   r   r   	iterativer
   !scipy.sparse.linalg._isolve.utilsr   __all__rS   r   r   r   r   r   <module>   s    
 +
