
    g|=                         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	Zdd
dddddddddd
dZy)    N)LinAlgError)get_blas_funcsqrsolvesvd	qr_insertlstsq   )_get_atol_rtol)make_systemgcrotmkFc	           
         |d }|d }t        g d|f      \  }	}
}}|g}g }d}t        j                  }|t        |      z   }t        j                  t        |      |f|j
                        }t        j                  d|j
                        }t        j                  d|j
                        }t        j                  |j
                        j                  }d}t        |      D ]^  }|r|t        |      k  r	||   \  }}nS|r|t        |      k(  r ||      }d}n8|s)||t        |      z
  k\  r|||t        |      z
  z
     \  }}n ||d	         }d}| | | |            }n|j                         } ||      }t        |      D ].  \  }} |
||      }||||f<    |	|||j                  d
   |       }0 t        j                  |dz   |j
                        }t        |      D ],  \  }} |
||      }|||<    |	|||j                  d
   |       }.  ||      |dz   <   t        j                  dd      5  d|d	   z  }ddd       t        j                        r	 |||      }|d	   ||z  kD  sd}|j                  |       |j                  |       t        j                  |dz   |dz   f|j
                  d      }||d|dz   d|dz   f<   d||dz   |dz   f<   t        j                  |dz   |f|j
                  d      } || d|dz   ddf<   t!        || ||ddd      \  }}t#        |d         }||k  s|s_ n t        j                  ||f         s
t%               t'        |d|dz   d|dz   f   |d
d|dz   f   j)                               \  }}!}!}!|ddd|dz   f   }|||||||fS # 1 sw Y   vxY w)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 N xs    W/var/www/html/venv/lib/python3.12/site-packages/scipy/sparse/linalg/_isolve/_gcrotmk.pylpsolvez_fgmres.<locals>.lpsolve@       H    c                     | S r   r   r   s    r   rpsolvez_fgmres.<locals>.rpsolveC   r   r   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Rr2   	breakdownjzww_normicalphahcurvQ2R2_s"                                     r   _fgmresrW      s   b 		 ++JRERD#tT
B	BA
&&C	CLA 	#b'1RXX.A 	bhh'A
rxx(A
((288

 
 CI 1X K q3w</1:DAqc'l!2AA Q!c'l*:%:1CL 012DAq2AA9q	"A Aa bM 	/DAq1IEAacFQ1771:v.A	/ xx!177+bM 	/DAq1IEDGQ1771:v.A	/ GQqS	[[hx8 	d2hJE	 ;;uUAAR3<' I
		!
		!
 XXqsAaCjs;4AaC4191Q3qs7XXqsAhaggS94AaC46
Rq'+%A1 !D'l :WKZ ;;q1vm $1Q3$t!t)a$1Q3$inn&67KAq!Q	!DQqSD&	AaBAs""k	 	s    	N==O	gh㈵>g        i     oldest)
rtolr?   maxiterMcallbackr>   kCU	discard_Ctruncatec       
            t        | |||      \  } }}}}t        j                  |      j                         st	        d      |dvrt	        d|      | j
                  }|j
                  }|
g }
|	|}	d\  }}}||j                         }n| ||      z
  }t        g d||f      \  }}}} ||      }t        d|||      \  }}|dk(  r|} ||      dfS |r|
D cg c]	  \  }}d|f c}}|
dd |
rw|
j                  d	 
       t        j                  | j                  d   t        |
      f|j                  d      }g }d}|
r@|
j                  d      \  }}| ||      }||dd|f<   |dz  }|j                  |       |
r@t!        |ddd      \  }}}~t#        |j$                        }g } t'        t        |            D ]  }|||      }t'        |      D ]&  }! ||||!      ||j                  d   ||!|f          }( t)        |||f         dt)        |d         z  k  r n$ |d|||f   z  |      }| j                  |        t#        t+        ||             ddd   |
dd |
rVt        ddg|f      \  }}|
D ]?  \  }} |||      }" ||||j                  d   |"      } ||||j                  d   |"       }A t'        |      D ]  }#| ||        ||      }$t-        |||z        }%|$|%k  r|#dkD  s|
r| ||      z
  } ||      }$|$|%k  rd}# nc|t-        |	t        |
      z
  d      z   }&|
D cg c]  \  }}|	 }}}	 t/        |||$z  |&|t-        |||z        |$z  |      \  }}}'}(})}*}+|*|$z  }*|)d   |*d   z  },t+        |)dd |*dd       D ]  \  }-}" ||-|,|,j                  d   |"      }, |'j3                  |*      }.t+        |
|.      D ]#  \  }/}0|/\  }} |||,|,j                  d   |0       },% |j3                  |j3                  |*            }1|(d   |1d   z  }2t+        |(dd |1dd       D ]  \  }3}4 ||3|2|2j                  d   |4      }2 	 d ||2      z  }5t        j                  |5      s
t5               	  ||5|2      }2 ||5|,      }, ||2|      }6 ||2||j                  d   |6       } ||,||j                  d   |6      }|dk(  r)t        |
      |	k\  r|
r|
d= t        |
      |	k\  rn|
rni|dk(  rct        |
      |	k\  rT|
rQt9        |ddddf   j$                  |'j$                        j$                  }7t;        |7      \  }8}9}:g };t=        |8ddd|	dz
  f   j$                        D ]  \  }}<|
d   \  }}||<d   z  }||<d   z  }t+        |
dd |<dd       D ]:  \  }=}>|=\  }?}@ ||?||j                  d   |>      } ||@||j                  d   |>      }< |;D ]@  \  }?}@ ||?|      }5 ||?||j                  d   |5       } ||@||j                  d   |5       }B  ||      }5 |d|5z  |      } |d|5z  |      }|;j                  ||f        |;|
dd |
j                  |2|,f        |
j                  d|j                         f       |r|
D ABcg c]	  \  }A}Bd|Bf c}B}A|
dd  ||      #dz   fS c c}}w c c}}w # t0        $ r Y  bw xY w# t4        t6        f$ r Y )w xY wc c}B}Aw )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)rY   smallestzInvalid value for 'truncate': N)NNNr   r   r   c                     | d   d uS )Nr   r   )cus    r   <lambda>zgcrotmk.<locals>.<lambda>=  s    r!uD0 r   )keyr%   r&   r
   Teconomic)overwrite_amodepivotingg-q=)r   r   g      ?r    r   r   )r   r?   r@   rY   rc   )r   r,   r8   all
ValueErrorr<   r4   r   r   sortemptyr6   r.   r   popr9   r   listTr3   r:   zipmaxrW   r   r   FloatingPointErrorZeroDivisionErrorr   r   r5   )CAbx0rZ   r?   r[   r\   r]   r>   r^   r_   r`   ra   r   postprocessr<   psolver   r   r   rr   b_normrP   uCusrK   rH   rI   Pr@   new_usrO   ycj_outerbetabeta_tolmlrG   rC   rD   rE   presuxrL   byre   bychycxrS   hycrQ   gammaDWsigmaVnew_CUrM   cupwpcpupczuzsC                                                                      r   r   r      s   x &a"Q/Aa!K;;q>?@@--9(FGGXXFXXF	zy&OD#t	zFFHq	M*+JQPQFSD#tT!WF  	64>JD${A""')*tq!$*1 

01 HHaggaj#b'*!''E66!9DAqy1IAacFFAIIaL  QDzDI1a !##Y s2w 	A1Q4A1X ;AaD1aggaj1QqS6':;1QqS6{US3[00S1Q3Z#AMM!	 SV_%dd+1	"FE?QD9	c  	,DAqQBQ1771:r*AQ1771:s+A	, > |QKAw tTF]+81F1IA7D8GQR[!$$DAqa	'.v/0v/17=47d6k4J44O24(6$Aq!RQ IA4 U1Q4ZAB12' 	.EAraRXXa["-B	.UU1X2r{ 	0GBDAqaRXXa[3$/B	0
 UU1558_URU]"QR&"QR&) 	/FAsaRXXa[#.B	/
	d2hJE;;u%(** & %_%_ B
Q
UF+Q
E* xb'Q,2qE b'Q,2#2w!|!CRCE(**acc*,,!!f5! %a$1Q3$ikk2 *DAqa5DAqAaDAAaDA#&r!"vqu#5 8R!$B Q
B7 Q
B78 #) <B #B
 Q
UF; Q
UF;< !GESY*ASY*AMM1a&))** 1 			2r(y|~ IItQVVX*,-B$-1q>7Q;&&} +`    	 	Z #$56 		j .s6   [?[1[*[(*[>	[%$[%([;:[;)NNr   r   Fr   )numpyr,   numpy.linalgr   scipy.linalgr   r   r   r   r   r	   	iterativer   !scipy.sparse.linalg._isolve.utilsr   __all__rW   r   r   r   r   <module>r      sU     $ K K % 9 + MO!g#T~'4b$$QUDTUX~'r   