B
    &]\N(              
   @   s  d Z ddlmZmZm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 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.    )divisionprint_functionabsolute_importN)asarray_chkfinitesingleasarrayarray)norm)callable   )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
}|pt	|| }t
d|f\}|dks|dkr|dd |dd}	|	d d jtj}|dkrd}
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 rt d| nN||jd d krtdn0||jd d krtdn|dkrt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
    --------
    >>> 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   )geesNc             S   s   d S )N )xr   r   8lib/python3.7/site-packages/scipy/linalg/decomp_schur.py<lambda>   s    zschur.<locals>.<lambda>)lworkc             S   s   d S )Nr   )r   r   r   r    r!      s    Zlhpc             S   s
   | j dk S )Ng        )r   )r   r   r   r    r!      s    Zrhpc             S   s
   | j dkS )Ng        )r   )r   r   r   r    r!      s    Ziucc             S   s   t | dkS )Ng      ?)abs)r   r   r   r    r!      s    Zoucc             S   s   t | dkS )Ng      ?)r$   )r   r   r   r    r!      s    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.z0Schur form not found.  Possibly ill-conditioned.)
ValueErrorr   r   lenshapedtypechar_double_precisionastyper   r   r   numpyintr
   formatr   )aoutputr"   r%   sortcheck_finiteZa1typr   resultr&   Z	sfunctioninfor   r   r    r      sb    c
"

















)	bhBr   r   fr   r   r   )r   r   r<   r   r   r   r<   r   r   c              G   sF   d}d}x0| D ](}|j j}t|t| }t|t| }qW t| | S )Nr   )r+   r,   max_array_kind_array_precision_array_type)arraysZkindZ	precisionr2   tr   r   r    _commonType   s    
rC   c             G   sZ   d}x8|D ]0}|j j| kr*|| f }q
||| f }q
W t|dkrR|d S |S d S )Nr   r   r   )r+   r,   copyr.   r)   )typerA   Zcast_arraysr2   r   r   r    	_castCopy   s    
rF   c             C   s  |rt t|| f\}} nt t|| f\}} xHt|| gD ]8\}}|jdks^|jd |jd kr8tdd| q8W | jd |jd krtd|j| j| jd }t|| t	dgd}t
||| \}} xt|d dd	D ]}t| ||d f tt| |d |d f t| ||f   kr~t| |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< qW | |fS )a6  
    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
    --------
    >>> 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   )r+   Ng        )mapr   r   	enumeratendimr*   r(   r1   rC   r   rF   ranger$   epsr   r	   ZconjdotT)rM   Zr5   ZindXNrB   mZmur   r   sGr   r   r    r      s0    5
B4BH@)r   NFNT)T)"__doc__Z
__future__r   r   r   r/   r   r   r   r   Znumpy.linalgr	   Zscipy._lib.sixr
   Zmiscr   r   Zlapackr   Zdecompr   __all__r-   r   ZfinfofloatrK   Zfepsr>   r?   r@   rC   rF   r   r   r   r   r    <module>   s,   
 
 !

