U
    {»|e (  ã                
   @   sä   d Z ddlZddlmZmZmZmZ ddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZ d	d
gZdddgZddd	„Ze e¡jZe e¡jZddddddddddœ	ZdddddddœZddgddggZdd„ Zdd„ Zddd
„ZdS )zSchur decomposition functions.é    N)Úasarray_chkfiniteÚsingleÚasarrayÚarray)Únormé   )ÚLinAlgErrorÚ_datacopied)Úget_lapack_funcs)ÚeigvalsÚschurÚrsf2csfÚiÚlÚdÚrealFTc                 C   s  |dkrt dƒ‚|rt| ƒ}nt| ƒ}t|jƒdksH|jd |jd krPt dƒ‚|jj}|dkrŽ|dkrŽ|tkr€| d	¡}d	}n| d
¡}d
}|pšt	|| ƒ}t
d|fƒ\}|dksº|dkrâ|dd„ |dd�}	|	d d j tj¡}|dkrød}
dd„ }nld}
t|ƒ�r|}nX|dk�r dd„ }nD|dk�r4dd„ }n0|dk�rHdd„ }n|dk�r\dd„ }nt dƒ‚||||||
d�}	|	d }|dk �ršt d | ¡ƒ‚nN||jd d k�r¸tdƒ‚n0||jd d k�rÖtdƒ‚n|dk�rètd ƒ‚|
dk�r|	d |	d! fS |	d |	d! |	d fS dS )"aà  
    Compute Schur decomposition of a matrix.

    The Schur decomposition is::

        A = Z T Z^H

    where Z is unitary and T is either upper-triangular, or for real
    Schur decomposition (output='real'), quasi-upper triangular. In
    the quasi-triangular form, 2x2 blocks describing complex-valued
    eigenvalue pairs may extrude from the diagonal.

    Parameters
    ----------
    a : (M, M) array_like
        Matrix to decompose
    output : {'real', 'complex'}, optional
        Construct the real or complex Schur decomposition (for real matrices).
    lwork : int, optional
        Work array size. If None or -1, it is automatically computed.
    overwrite_a : bool, optional
        Whether to overwrite data in a (may improve performance).
    sort : {None, callable, 'lhp', 'rhp', 'iuc', 'ouc'}, optional
        Specifies whether the upper eigenvalues should be sorted. A callable
        may be passed that, given a eigenvalue, returns a boolean denoting
        whether the eigenvalue should be sorted to the top-left (True).
        Alternatively, string parameters may be used::

            'lhp'   Left-hand plane (x.real < 0.0)
            'rhp'   Right-hand plane (x.real > 0.0)
            'iuc'   Inside the unit circle (x*x.conjugate() <= 1.0)
            'ouc'   Outside the unit circle (x*x.conjugate() > 1.0)

        Defaults to None (no sorting).
    check_finite : bool, optional
        Whether to check that the input matrix contains only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.

    Returns
    -------
    T : (M, M) ndarray
        Schur form of A. It is real-valued for the real Schur decomposition.
    Z : (M, M) ndarray
        An unitary Schur transformation matrix for A.
        It is real-valued for the real Schur decomposition.
    sdim : int
        If and only if sorting was requested, a third return value will
        contain the number of eigenvalues satisfying the sort condition.

    Raises
    ------
    LinAlgError
        Error raised under three conditions:

        1. The algorithm failed due to a failure of the QR algorithm to
           compute all eigenvalues.
        2. If eigenvalue sorting was requested, the eigenvalues could not be
           reordered due to a failure to separate eigenvalues, usually because
           of poor conditioning.
        3. If eigenvalue sorting was requested, roundoff errors caused the
           leading eigenvalues to no longer satisfy the sorting condition.

    See Also
    --------
    rsf2csf : Convert real Schur form to complex Schur form

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import schur, eigvals
    >>> A = np.array([[0, 2, 2], [0, 1, 2], [1, 0, 1]])
    >>> T, Z = schur(A)
    >>> T
    array([[ 2.65896708,  1.42440458, -1.92933439],
           [ 0.        , -0.32948354, -0.49063704],
           [ 0.        ,  1.31178921, -0.32948354]])
    >>> Z
    array([[0.72711591, -0.60156188, 0.33079564],
           [0.52839428, 0.79801892, 0.28976765],
           [0.43829436, 0.03590414, -0.89811411]])

    >>> T2, Z2 = schur(A, output='complex')
    >>> T2
    array([[ 2.65896708, -1.22839825+1.32378589j,  0.42590089+1.51937378j],
           [ 0.        , -0.32948354+0.80225456j, -0.59877807+0.56192146j],
           [ 0.        ,  0.                    , -0.32948354-0.80225456j]])
    >>> eigvals(T2)
    array([2.65896708, -0.32948354+0.80225456j, -0.32948354-0.80225456j])

    An arbitrary custom eig-sorting condition, having positive imaginary part,
    which is satisfied by only one eigenvalue

    >>> T3, Z3, sdim = schur(A, output='complex', sort=lambda x: x.imag > 0)
    >>> sdim
    1

    )r   ÚcomplexÚrÚcz%argument must be 'real', or 'complex'é   r   r   zexpected square matrix)r   r   )ÚFÚDr   r   )ÚgeesNéÿÿÿÿc                 S   s   d S ©N© ©Úxr   r   úW/var/www/website-v5/atlas_env/lib/python3.8/site-packages/scipy/linalg/_decomp_schur.pyÚ<lambda>‰   ó    zschur.<locals>.<lambda>)Úlworkéþÿÿÿc                 S   s   d S r   r   r   r   r   r   r   Ž   r    Úlhpc                 S   s
   | j dk S ©Nç        ©r   r   r   r   r   r   ”   r    Úrhpc                 S   s
   | j dkS r$   r&   r   r   r   r   r   –   r    Úiucc                 S   s   t | ƒdkS ©Ng      ð?©Úabsr   r   r   r   r   ˜   r    Úoucc                 S   s   t | ƒdkS r)   r*   r   r   r   r   r   š   r    zZ'sort' parameter must either be 'None', or a callable, or one of ('lhp','rhp','iuc','ouc'))r!   Úoverwrite_aÚsort_tz0illegal value in {}-th argument of internal geesz2Eigenvalues could not be separated for reordering.z2Leading eigenvalues do not satisfy sort condition.z/Schur form not found. Possibly ill-conditioned.éýÿÿÿ)Ú
ValueErrorr   r   ÚlenÚshapeÚdtypeÚcharÚ_double_precisionÚastyper	   r
   r   ÚnumpyÚint_ÚcallableÚformatr   )ÚaÚoutputr!   r-   ÚsortÚcheck_finiteÚa1Útypr   Úresultr.   Ú	sfunctionÚinfor   r   r   r      sf    d
"












ÿ
ÿ



)	ÚbÚhÚBr   r   Úfr   r   r   )r   r   rG   r   r   r   rG   r   r   c                  G   sB   d}d}| D ](}|j j}t|t| ƒ}t|t| ƒ}qt| | S )Nr   )r3   r4   ÚmaxÚ_array_kindÚ_array_precisionÚ_array_type)ÚarraysÚkindÚ	precisionr;   Útr   r   r   Ú_commonType¼   s    rP   c                 G   sV   d}|D ]0}|j j| kr(|| ¡ f }q|| | ¡f }qt|ƒdkrN|d S |S d S )Nr   r   r   )r3   r4   Úcopyr6   r1   )ÚtyperL   Zcast_arraysr;   r   r   r   Ú	_castCopyÆ   s    rS   c                 C   s�  |rt t|| fƒ\}} nt t|| fƒ\}} t|| gƒD ]8\}}|jdks\|jd |jd kr6td d| ¡ƒ‚q6| jd |jd kr˜td |j| j¡ƒ‚| jd }t|| t	dgdƒƒ}t
||| ƒ\}} t|d dd	ƒD �]®}t| ||d f ƒtt| |d |d f ƒt| ||f ƒ  k�rvt| |d |d …|d |d …f ƒ| ||f  }t|d | ||d f gƒ}	|d |	 }
| ||d f |	 }t	|
 ¡ |g| |
gg|d
�}| | |d |d …|d d…f ¡| |d |d …|d d…f< | d|d …|d |d …f  | ¡ j¡| d|d …|d |d …f< |dd…|d |d …f  | ¡ j¡|dd…|d |d …f< d| ||d f< qÖ| |fS )aQ  
    Convert real Schur form to complex Schur form.

    Convert a quasi-diagonal real-valued Schur form to the upper-triangular
    complex-valued Schur form.

    Parameters
    ----------
    T : (M, M) array_like
        Real Schur form of the original array
    Z : (M, M) array_like
        Schur transformation matrix
    check_finite : bool, optional
        Whether to check that the input arrays contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.

    Returns
    -------
    T : (M, M) ndarray
        Complex Schur form of the original array
    Z : (M, M) ndarray
        Schur transformation matrix corresponding to the complex form

    See Also
    --------
    schur : Schur decomposition of an array

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import schur, rsf2csf
    >>> A = np.array([[0, 2, 2], [0, 1, 2], [1, 0, 1]])
    >>> T, Z = schur(A)
    >>> T
    array([[ 2.65896708,  1.42440458, -1.92933439],
           [ 0.        , -0.32948354, -0.49063704],
           [ 0.        ,  1.31178921, -0.32948354]])
    >>> Z
    array([[0.72711591, -0.60156188, 0.33079564],
           [0.52839428, 0.79801892, 0.28976765],
           [0.43829436, 0.03590414, -0.89811411]])
    >>> T2 , Z2 = rsf2csf(T, Z)
    >>> T2
    array([[2.65896708+0.j, -1.64592781+0.743164187j, -1.21516887+1.00660462j],
           [0.+0.j , -0.32948354+8.02254558e-01j, -0.82115218-2.77555756e-17j],
           [0.+0.j , 0.+0.j, -0.32948354-0.802254558j]])
    >>> Z2
    array([[0.72711591+0.j,  0.28220393-0.31385693j,  0.51319638-0.17258824j],
           [0.52839428+0.j,  0.24720268+0.41635578j, -0.68079517-0.15118243j],
           [0.43829436+0.j, -0.76618703+0.01873251j, -0.03063006+0.46857912j]])

    r   r   r   zInput '{}' must be square.ZZTz.Input array shapes must match: Z: {} vs. T: {}g      @r   r   )r3   Nr%   )Úmapr   r   Ú	enumerateÚndimr2   r0   r:   rP   r   rS   Úranger+   Úepsr   r   ÚconjÚdotÚT)r[   ÚZr>   ÚindÚXÚNrO   ÚmÚmur   r   ÚsÚGr   r   r   r   Ó   s4    6 ÿ
B4BH@)r   NFNT)T)Ú__doc__r7   r   r   r   r   Únumpy.linalgr   Ú_miscr   r	   Úlapackr
   Ú_decompr   Ú__all__r5   r   ÚfinfoÚfloatrX   ZfepsrI   rJ   rK   rP   rS   r   r   r   r   r   Ú<module>   s2   
  ÿ
 #
   ÿ
