B
    &]\~              
   @   s|  d dl mZmZmZ dddddddd	d
dg
Zd dlZd dlmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZ d dlmZ d dlmZ d dlmZ ddlmZmZmZ ddl m!Z!m"Z" ed dZ#dd Z$dd Z%dd Z&d2ddZ'd3ddZ(d dd d dd d dd d!	Z)d"d# Z*d4d%dZ+d5d&dZ,d6d'dZ-d7d(dZ.d8d+d	Z/d9d,dZ0d:d.d/Z1d;d0d
Z2d1d Z3dS )<    )divisionprint_functionabsolute_importeigeigvalseigheigvalsh
eig_bandedeigvals_bandedeigh_tridiagonaleigvalsh_tridiagonal
hessenbergcdf2rdfN)arrayisfiniteinexactnonzeroiscomplexobjcastflatnonzeroconjasarrayargsortemptynewaxisargwhere	iscomplexeyezeroseinsum)xrange)_asarray_validated)string_types   )LinAlgError_datacopiednorm)get_lapack_funcs_compute_lworkFy              ?c             C   s   t j||d}| jdk}|dd  | jdd dk O  < xXt|D ]L}|dd|d f |jdd|f< t|dd|f |dd|d f  qDW |S )zR
    Produce complex-valued eigenvectors from LAPACK DGGEV real-valued output
    )dtyper   Nr#   )numpyr   imagr   r   )wZvinr*   vmi r2   2lib/python3.7/site-packages/scipy/linalg/decomp.py_make_complex_eigvecs$   s    
""*r4   c             C   s   |r0|d kr t | t | fS t | |fS n|d kr<| S t | }| dk}|dk}| }| | ||  ||< t j|| |@ < t | jdkrt j|||@ < ntt jt j|||@ < |S d S )Nr   )	r,   ZvstackZ	ones_likeZ
empty_likeinfallr-   nancomplex)alphabetahomogeneous_eigvalsr.   Z
alpha_zeroZ	beta_zeroZbeta_nonzeror2   r2   r3   _make_eigvals2   s     
r<   c             C   s  t d| |f\}|| }}	|| |dd}
|
d d jtj}|jdkrv|| |||	|||\}}}}}}t|||}n:|| |||	|||\}}}}}}}|t|  }t|||}t|d t	|j
dk}|jdks|s|jj}|rt|||}|rt|||}xtt|jd D ]b}|rH|d d |f  t|d d |f   < |r|d d |f  t|d d |f   < qW |s|s|S |r|r|||fS ||fS ||fS )	N)ggevr+   )lworkr   czz generalized eig algorithm (ggev)g        )r'   realZastyper,   inttypecoder<   _I_check_infor6   r-   r*   charr4   r    shaper&   )a1b1leftrightoverwrite_aoverwrite_br;   r=   ZcvlZcvrZresr>   r9   r:   vlvrZworkinfor.   ZalpharZalphai	only_realtr1   r2   r2   r3   _geneigL   sB    



(.
rS   FTc             C   s  t | |d}t|jdks.|jd |jd kr6td|pBt|| }|dk	rt ||d}	|pdt|	|}t|	jdks|	jd |	jd krtd|	j|jkrtdt||	|||||S td|f\}
}|| }}t||jd ||d	}|
jd
kr|
|||||d\}}}}t	|d|}nF|
|||||d\}}}}}ddd|j
j }|t|  }t	|d|}t|ddd t|jdk}|
jd
ks|s|j
j}|rt|||}|rt|||}|s|s|S |r|r|||fS ||fS ||fS )a  
    Solve an ordinary or generalized eigenvalue problem of a square matrix.

    Find eigenvalues w and right or left eigenvectors of a general matrix::

        a   vr[:,i] = w[i]        b   vr[:,i]
        a.H vl[:,i] = w[i].conj() b.H vl[:,i]

    where ``.H`` is the Hermitian conjugation.

    Parameters
    ----------
    a : (M, M) array_like
        A complex or real matrix whose eigenvalues and eigenvectors
        will be computed.
    b : (M, M) array_like, optional
        Right-hand side matrix in a generalized eigenvalue problem.
        Default is None, identity matrix is assumed.
    left : bool, optional
        Whether to calculate and return left eigenvectors.  Default is False.
    right : bool, optional
        Whether to calculate and return right eigenvectors.  Default is True.
    overwrite_a : bool, optional
        Whether to overwrite `a`; may improve performance.  Default is False.
    overwrite_b : bool, optional
        Whether to overwrite `b`; may improve performance.  Default is False.
    check_finite : bool, optional
        Whether to check that the input matrices 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.
    homogeneous_eigvals : bool, optional
        If True, return the eigenvalues in homogeneous coordinates.
        In this case ``w`` is a (2, M) array so that::

            w[1,i] a vr[:,i] = w[0,i] b vr[:,i]

        Default is False.

    Returns
    -------
    w : (M,) or (2, M) double or complex ndarray
        The eigenvalues, each repeated according to its
        multiplicity. The shape is (M,) unless
        ``homogeneous_eigvals=True``.
    vl : (M, M) double or complex ndarray
        The normalized left eigenvector corresponding to the eigenvalue
        ``w[i]`` is the column vl[:,i]. Only returned if ``left=True``.
    vr : (M, M) double or complex ndarray
        The normalized right eigenvector corresponding to the eigenvalue
        ``w[i]`` is the column ``vr[:,i]``.  Only returned if ``right=True``.

    Raises
    ------
    LinAlgError
        If eigenvalue computation does not converge.

    See Also
    --------
    eigvals : eigenvalues of general arrays
    eigh : Eigenvalues and right eigenvectors for symmetric/Hermitian arrays.
    eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
        band matrices
    eigh_tridiagonal : eigenvalues and right eiegenvectors for
        symmetric/Hermitian tridiagonal matrices

    Examples
    --------
    >>> from scipy import linalg
    >>> a = np.array([[0., -1.], [1., 0.]])
    >>> linalg.eigvals(a)
    array([0.+1.j, 0.-1.j])

    >>> b = np.array([[0., 1.], [1., 1.]])
    >>> linalg.eigvals(a, b)
    array([ 1.+0.j, -1.+0.j])

    >>> a = np.array([[3., 0., 0.], [0., 8., 0.], [0., 0., 7.]])
    >>> linalg.eigvals(a, homogeneous_eigvals=True)
    array([[3.+0.j, 8.+0.j, 7.+0.j],
           [1.+0.j, 1.+0.j, 1.+0.j]])

    >>> a = np.array([[0., -1.], [1., 0.]])
    >>> linalg.eigvals(a) == linalg.eig(a)[0]
    array([ True,  True])
    >>> linalg.eig(a, left=True, right=False)[1] # normalized left eigenvector
    array([[-0.70710678+0.j        , -0.70710678-0.j        ],
           [-0.        +0.70710678j, -0.        -0.70710678j]])
    >>> linalg.eig(a, left=False, right=True)[1] # normalized right eigenvector
    array([[0.70710678+0.j        , 0.70710678-0.j        ],
           [0.        -0.70710678j, 0.        +0.70710678j]])



    )check_finite   r   r#   zexpected square matrixNz a and b must have the same shape)geev
geev_lwork)
compute_vl
compute_vrr@   )r>   rX   rY   rL   r)   D)fdzeig algorithm (geev)zCdid not converge (only eigenvalues with order >= %d have converged))positiveg        )r!   lenrG   
ValueErrorr%   rS   r'   r(   rC   r<   r*   rF   rD   rE   r,   r6   r-   r4   )abrJ   rK   rL   rM   rT   r;   rH   rI   rV   rW   rX   rY   r>   r.   rN   rO   rP   wrZwirR   rQ   r2   r2   r3   r   v   s^    `""

c
             C   s  t | |	d}
t|
jdks.|
jd |
jd kr6td|pBt|
| }t|
rRd}nd}|dk	rt ||	d}|pvt||}t|jdks|jd |jd krtd|j|
jkrtd	t|jt|
jf t|rd}q|pd}nd}|rd
pd}|dk	rP|\}}|dk s||
jd kr8tdd|
jd d f |d7 }|d7 }||f}|r\d}nd}|rld}nd}|dkr|d }t|f|
f\}|dkr||
||dd|
jd |d\}}}n8|\}}||
||d|||d\}}}|d|| d  }n|dk	r^|d }t|f|
|f\}|\}}||
||||||||d	\}}}}|d|| d  }nt|r|d }t|f|
|f\}||
||||||d\}}}n6|d }t|f|
|f\}||
||||||d\}}}|dkr|r|S ||fS t||dd |dkr|dkrt	dnfd|  k r8|jd krjn n.|dk	r\t	dt
| d nt	d| nt	d||jd   dS )aw  
    Solve an ordinary or generalized eigenvalue problem for a complex
    Hermitian or real symmetric matrix.

    Find eigenvalues w and optionally eigenvectors v of matrix `a`, where
    `b` is positive definite::

                      a v[:,i] = w[i] b v[:,i]
        v[i,:].conj() a v[:,i] = w[i]
        v[i,:].conj() b v[:,i] = 1

    Parameters
    ----------
    a : (M, M) array_like
        A complex Hermitian or real symmetric matrix whose eigenvalues and
        eigenvectors will be computed.
    b : (M, M) array_like, optional
        A complex Hermitian or real symmetric definite positive matrix in.
        If omitted, identity matrix is assumed.
    lower : bool, optional
        Whether the pertinent array data is taken from the lower or upper
        triangle of `a`. (Default: lower)
    eigvals_only : bool, optional
        Whether to calculate only eigenvalues and no eigenvectors.
        (Default: both are calculated)
    turbo : bool, optional
        Use divide and conquer algorithm (faster but expensive in memory,
        only for generalized eigenvalue problem and if eigvals=None)
    eigvals : tuple (lo, hi), optional
        Indexes of the smallest and largest (in ascending order) eigenvalues
        and corresponding eigenvectors to be returned: 0 <= lo <= hi <= M-1.
        If omitted, all eigenvalues and eigenvectors are returned.
    type : int, optional
        Specifies the problem type to be solved:

           type = 1: a   v[:,i] = w[i] b v[:,i]

           type = 2: a b v[:,i] = w[i]   v[:,i]

           type = 3: b a v[:,i] = w[i]   v[:,i]
    overwrite_a : bool, optional
        Whether to overwrite data in `a` (may improve performance)
    overwrite_b : bool, optional
        Whether to overwrite data in `b` (may improve performance)
    check_finite : bool, optional
        Whether to check that the input matrices 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
    -------
    w : (N,) float ndarray
        The N (1<=N<=M) selected eigenvalues, in ascending order, each
        repeated according to its multiplicity.
    v : (M, N) complex ndarray
        (if eigvals_only == False)

        The normalized selected eigenvector corresponding to the
        eigenvalue w[i] is the column v[:,i].

        Normalization:

            type 1 and 3: v.conj() a      v  = w

            type 2: inv(v).conj() a  inv(v) = w

            type = 1 or 2: v.conj() b      v  = I

            type = 3: v.conj() inv(b) v  = I

    Raises
    ------
    LinAlgError
        If eigenvalue computation does not converge,
        an error occurred, or b matrix is not definite positive. Note that
        if input matrices are not symmetric or hermitian, no error is reported
        but results will be wrong.

    See Also
    --------
    eigvalsh : eigenvalues of symmetric or Hermitian arrays
    eig : eigenvalues and right eigenvectors for non-symmetric arrays
    eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
    eigh_tridiagonal : eigenvalues and right eiegenvectors for
        symmetric/Hermitian tridiagonal matrices

    Notes
    -----
    This function does not check the input array for being hermitian/symmetric
    in order to allow for representing arrays with only their upper/lower
    triangular parts.

    Examples
    --------
    >>> from scipy.linalg import eigh
    >>> A = np.array([[6, 3, 1, 5], [3, 0, 5, 1], [1, 5, 6, 2], [5, 1, 2, 2]])
    >>> w, v = eigh(A)
    >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
    True

    )rT   rU   r   r#   zexpected square matrixTFNz#wrong b dimensions %s, should be %sNVzCThe eigenvalue range specified is not valid.
Valid range is [%s,%s]LUZheZsyevrA)uplojobzrangeiliurL   Igvx)ri   rm   ityperj   rl   rL   rM   gvd)ri   rp   rj   rL   rM   gv)r]   zunrecoverable internal error.z'the eigenvectors %s failed to converge.zinternal fortran routine failed to converge: %i off-diagonal elements of an intermediate tridiagonal form did not converge to zero.zthe leading minor of order %i of 'b' is not positive definite. The factorization of 'b' could not be completed and no eigenvalues or eigenvectors were computed.)r!   r^   rG   r_   r%   r   strr'   rE   r$   r   )r`   ra   lowereigvals_onlyrL   rM   turbor   typerT   rH   ZcplxrI   Z_joblohiri   Zpfxdriverrg   r.   r/   rP   Zw_totro   ifailrq   rr   r2   r2   r3   r     s    h""








"

rU   )	r   r#   rU   r6   valueindexr`   r/   r1   c       	      C   s  t | tr|  } yt|  } W n tk
r:   tdY nX d\}}d }}| dkr
t|}|jdks|jdks|d |d k rtd| dkr|\}}|dkr|}nb|j	j
 dkrtd|j	|j	j
f |d \}}t||dk st|||krtd	|| d }| |||||fS )
z5Check that select is valid, convert to Fortran style.zinvalid argument for select)g        g      ?r#   r   rU   zBselect_range must be a 2-element array-like in nondecreasing orderZhilqpzLwhen using select="i", select_range must contain integers, got dtype %s (%s)zselect_range out of bounds)
isinstancer"   rt   
_conv_dictKeyErrorr_   r   ndimsizer*   rF   minmax)	selectselect_rangemax_evZmax_lenrN   vurl   rm   srr2   r2   r3   _check_select  s0    

$r   r`   c             C   s  |s|r$t | |d}|p t|| }n.t| }t|jjtrNt| sNt	dd}t
|jdkrht	dt||||jd \}}	}
}}}~|dkr|jjdkrd}nd	}t|f|f\}||| ||d
\}}}n|rd}|jjdkrtdtdddf\}ntdtdddf\}d|d }|jjdkr4d}nd}t|f|f\}|||	|
||| |||||d\}}}}}|d| }|s|ddd|f }t|| |r|S ||fS )a  
    Solve real symmetric or complex hermitian band matrix eigenvalue problem.

    Find eigenvalues w and optionally right eigenvectors v of a::

        a v[:,i] = w[i] v[:,i]
        v.H v    = identity

    The matrix a is stored in a_band either in lower diagonal or upper
    diagonal ordered form:

        a_band[u + i - j, j] == a[i,j]        (if upper form; i <= j)
        a_band[    i - j, j] == a[i,j]        (if lower form; i >= j)

    where u is the number of bands above the diagonal.

    Example of a_band (shape of a is (6,6), u=2)::

        upper form:
        *   *   a02 a13 a24 a35
        *   a01 a12 a23 a34 a45
        a00 a11 a22 a33 a44 a55

        lower form:
        a00 a11 a22 a33 a44 a55
        a10 a21 a32 a43 a54 *
        a20 a31 a42 a53 *   *

    Cells marked with * are not used.

    Parameters
    ----------
    a_band : (u+1, M) array_like
        The bands of the M by M matrix a.
    lower : bool, optional
        Is the matrix in the lower form. (Default is upper form)
    eigvals_only : bool, optional
        Compute only the eigenvalues and no eigenvectors.
        (Default: calculate also eigenvectors)
    overwrite_a_band : bool, optional
        Discard data in a_band (may enhance performance)
    select : {'a', 'v', 'i'}, optional
        Which eigenvalues to calculate

        ======  ========================================
        select  calculated
        ======  ========================================
        'a'     All eigenvalues
        'v'     Eigenvalues in the interval (min, max]
        'i'     Eigenvalues with indices min <= i <= max
        ======  ========================================
    select_range : (min, max), optional
        Range of selected eigenvalues
    max_ev : int, optional
        For select=='v', maximum number of eigenvalues expected.
        For other values of select, has no meaning.

        In doubt, leave this parameter untouched.

    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
    -------
    w : (M,) ndarray
        The eigenvalues, in ascending order, each repeated according to its
        multiplicity.
    v : (M, M) float or complex ndarray
        The normalized eigenvector corresponding to the eigenvalue w[i] is
        the column v[:,i].

    Raises
    ------
    LinAlgError
        If eigenvalue computation does not converge.

    See Also
    --------
    eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
    eig : eigenvalues and right eigenvectors of general arrays.
    eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
    eigh_tridiagonal : eigenvalues and right eiegenvectors for
        symmetric/Hermitian tridiagonal matrices

    Examples
    --------
    >>> from scipy.linalg import eig_banded
    >>> A = np.array([[1, 5, 2, 0], [5, 2, 5, 2], [2, 5, 3, 5], [0, 2, 5, 4]])
    >>> Ab = np.array([[1, 2, 3, 4], [5, 5, 5, 0], [2, 2, 0, 0]])
    >>> w, v = eig_banded(Ab, lower=True)
    >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
    True
    >>> w = eig_banded(Ab, lower=True, eigvals_only=True)
    >>> w
    array([-4.26200532, -2.22987175,  3.95222349, 12.53965359])

    Request only the eigenvalues between ``[-3, 4]``

    >>> w, v = eig_banded(Ab, lower=True, select='v', select_range=[-3, 4])
    >>> w
    array([-2.22987175,  3.95222349])

    )rT   z#array must not contain infs or NaNsr#   rU   zexpected two-dimensional arrayr   GFDZhbevdZsbevd)	compute_vrt   overwrite_abZfF)lamchr[   )r*   r\   sZhbevxZsbevx)r   Zmmaxrk   rt   r   abstolN)r!   r%   r   
issubclassr*   rw   r   r   r6   r_   r^   rG   r   rF   r'   rE   )a_bandrt   ru   overwrite_a_bandr   r   r   rT   rH   rN   r   rl   rm   internal_nameZbevdr.   r/   rP   r   r   Zbevxr0   r{   r2   r2   r3   r	     sP    k
c          	   C   s   t | |dd|||dS )a  
    Compute eigenvalues from an ordinary or generalized eigenvalue problem.

    Find eigenvalues of a general matrix::

        a   vr[:,i] = w[i]        b   vr[:,i]

    Parameters
    ----------
    a : (M, M) array_like
        A complex or real matrix whose eigenvalues and eigenvectors
        will be computed.
    b : (M, M) array_like, optional
        Right-hand side matrix in a generalized eigenvalue problem.
        If omitted, identity matrix is assumed.
    overwrite_a : bool, optional
        Whether to overwrite data in a (may improve performance)
    check_finite : bool, optional
        Whether to check that the input matrices 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.
    homogeneous_eigvals : bool, optional
        If True, return the eigenvalues in homogeneous coordinates.
        In this case ``w`` is a (2, M) array so that::

            w[1,i] a vr[:,i] = w[0,i] b vr[:,i]

        Default is False.

    Returns
    -------
    w : (M,) or (2, M) double or complex ndarray
        The eigenvalues, each repeated according to its multiplicity
        but not in any specific order. The shape is (M,) unless
        ``homogeneous_eigvals=True``.

    Raises
    ------
    LinAlgError
        If eigenvalue computation does not converge

    See Also
    --------
    eig : eigenvalues and right eigenvectors of general arrays.
    eigvalsh : eigenvalues of symmetric or Hermitian arrays
    eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
    eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
        matrices

    Examples
    --------
    >>> from scipy import linalg
    >>> a = np.array([[0., -1.], [1., 0.]])
    >>> linalg.eigvals(a)
    array([0.+1.j, 0.-1.j])

    >>> b = np.array([[0., 1.], [1., 1.]])
    >>> linalg.eigvals(a, b)
    array([ 1.+0.j, -1.+0.j])

    >>> a = np.array([[3., 0., 0.], [0., 8., 0.], [0., 0., 7.]])
    >>> linalg.eigvals(a, homogeneous_eigvals=True)
    array([[3.+0.j, 8.+0.j, 7.+0.j],
           [1.+0.j, 1.+0.j, 1.+0.j]])

    r   )ra   rJ   rK   rL   rT   r;   )r   )r`   ra   rL   rT   r;   r2   r2   r3   r     s    Ec	       	      C   s   t | ||d||||||d
S )a  
    Solve an ordinary or generalized eigenvalue problem for a complex
    Hermitian or real symmetric matrix.

    Find eigenvalues w of matrix a, where b is positive definite::

                      a v[:,i] = w[i] b v[:,i]
        v[i,:].conj() a v[:,i] = w[i]
        v[i,:].conj() b v[:,i] = 1


    Parameters
    ----------
    a : (M, M) array_like
        A complex Hermitian or real symmetric matrix whose eigenvalues and
        eigenvectors will be computed.
    b : (M, M) array_like, optional
        A complex Hermitian or real symmetric definite positive matrix in.
        If omitted, identity matrix is assumed.
    lower : bool, optional
        Whether the pertinent array data is taken from the lower or upper
        triangle of `a`. (Default: lower)
    turbo : bool, optional
        Use divide and conquer algorithm (faster but expensive in memory,
        only for generalized eigenvalue problem and if eigvals=None)
    eigvals : tuple (lo, hi), optional
        Indexes of the smallest and largest (in ascending order) eigenvalues
        and corresponding eigenvectors to be returned: 0 <= lo < hi <= M-1.
        If omitted, all eigenvalues and eigenvectors are returned.
    type : int, optional
        Specifies the problem type to be solved:

           type = 1: a   v[:,i] = w[i] b v[:,i]

           type = 2: a b v[:,i] = w[i]   v[:,i]

           type = 3: b a v[:,i] = w[i]   v[:,i]
    overwrite_a : bool, optional
        Whether to overwrite data in `a` (may improve performance)
    overwrite_b : bool, optional
        Whether to overwrite data in `b` (may improve performance)
    check_finite : bool, optional
        Whether to check that the input matrices 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
    -------
    w : (N,) float ndarray
        The N (1<=N<=M) selected eigenvalues, in ascending order, each
        repeated according to its multiplicity.

    Raises
    ------
    LinAlgError
        If eigenvalue computation does not converge,
        an error occurred, or b matrix is not definite positive. Note that
        if input matrices are not symmetric or hermitian, no error is reported
        but results will be wrong.

    See Also
    --------
    eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
    eigvals : eigenvalues of general arrays
    eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
    eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
        matrices

    Notes
    -----
    This function does not check the input array for being hermitian/symmetric
    in order to allow for representing arrays with only their upper/lower
    triangular parts.

    Examples
    --------
    >>> from scipy.linalg import eigvalsh
    >>> A = np.array([[6, 3, 1, 5], [3, 0, 5, 1], [1, 5, 6, 2], [5, 1, 2, 2]])
    >>> w = eigvalsh(A)
    >>> w
    array([-3.74637491, -0.76263923,  6.08502336, 12.42399079])

    T)	ra   rt   ru   rL   rM   rv   r   rw   rT   )r   )	r`   ra   rt   rL   rM   rv   r   rw   rT   r2   r2   r3   r     s    V
c          	   C   s   t | |d||||dS )a  
    Solve real symmetric or complex hermitian band matrix eigenvalue problem.

    Find eigenvalues w of a::

        a v[:,i] = w[i] v[:,i]
        v.H v    = identity

    The matrix a is stored in a_band either in lower diagonal or upper
    diagonal ordered form:

        a_band[u + i - j, j] == a[i,j]        (if upper form; i <= j)
        a_band[    i - j, j] == a[i,j]        (if lower form; i >= j)

    where u is the number of bands above the diagonal.

    Example of a_band (shape of a is (6,6), u=2)::

        upper form:
        *   *   a02 a13 a24 a35
        *   a01 a12 a23 a34 a45
        a00 a11 a22 a33 a44 a55

        lower form:
        a00 a11 a22 a33 a44 a55
        a10 a21 a32 a43 a54 *
        a20 a31 a42 a53 *   *

    Cells marked with * are not used.

    Parameters
    ----------
    a_band : (u+1, M) array_like
        The bands of the M by M matrix a.
    lower : bool, optional
        Is the matrix in the lower form. (Default is upper form)
    overwrite_a_band : bool, optional
        Discard data in a_band (may enhance performance)
    select : {'a', 'v', 'i'}, optional
        Which eigenvalues to calculate

        ======  ========================================
        select  calculated
        ======  ========================================
        'a'     All eigenvalues
        'v'     Eigenvalues in the interval (min, max]
        'i'     Eigenvalues with indices min <= i <= max
        ======  ========================================
    select_range : (min, max), optional
        Range of selected eigenvalues
    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
    -------
    w : (M,) ndarray
        The eigenvalues, in ascending order, each repeated according to its
        multiplicity.

    Raises
    ------
    LinAlgError
        If eigenvalue computation does not converge.

    See Also
    --------
    eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
        band matrices
    eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
        matrices
    eigvals : eigenvalues of general arrays
    eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
    eig : eigenvalues and right eigenvectors for non-symmetric arrays

    Examples
    --------
    >>> from scipy.linalg import eigvals_banded
    >>> A = np.array([[1, 5, 2, 0], [5, 2, 5, 2], [2, 5, 3, 5], [0, 2, 5, 4]])
    >>> Ab = np.array([[1, 2, 3, 4], [5, 5, 5, 0], [2, 2, 0, 0]])
    >>> w = eigvals_banded(Ab, lower=True)
    >>> w
    array([-4.26200532, -2.22987175,  3.95222349, 12.53965359])
    r#   )rt   ru   r   r   r   rT   )r	   )r   rt   r   r   r   rT   r2   r2   r3   r
   `  s    W        autoc          
   C   s   t | |d|||||dS )aH
  
    Solve eigenvalue problem for a real symmetric tridiagonal matrix.

    Find eigenvalues `w` of ``a``::

        a v[:,i] = w[i] v[:,i]
        v.H v    = identity

    For a real symmetric matrix ``a`` with diagonal elements `d` and
    off-diagonal elements `e`.

    Parameters
    ----------
    d : ndarray, shape (ndim,)
        The diagonal elements of the array.
    e : ndarray, shape (ndim-1,)
        The off-diagonal elements of the array.
    select : {'a', 'v', 'i'}, optional
        Which eigenvalues to calculate

        ======  ========================================
        select  calculated
        ======  ========================================
        'a'     All eigenvalues
        'v'     Eigenvalues in the interval (min, max]
        'i'     Eigenvalues with indices min <= i <= max
        ======  ========================================
    select_range : (min, max), optional
        Range of selected eigenvalues
    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.
    tol : float
        The absolute tolerance to which each eigenvalue is required
        (only used when ``lapack_driver='stebz'``).
        An eigenvalue (or cluster) is considered to have converged if it
        lies in an interval of this width. If <= 0. (default),
        the value ``eps*|a|`` is used where eps is the machine precision,
        and ``|a|`` is the 1-norm of the matrix ``a``.
    lapack_driver : str
        LAPACK function to use, can be 'auto', 'stemr', 'stebz',  'sterf',
        or 'stev'. When 'auto' (default), it will use 'stemr' if ``select='a'``
        and 'stebz' otherwise. 'sterf' and 'stev' can only be used when
        ``select='a'``.

    Returns
    -------
    w : (M,) ndarray
        The eigenvalues, in ascending order, each repeated according to its
        multiplicity.

    Raises
    ------
    LinAlgError
        If eigenvalue computation does not converge.

    See Also
    --------
    eigh_tridiagonal : eigenvalues and right eiegenvectors for
        symmetric/Hermitian tridiagonal matrices

    Examples
    --------
    >>> from scipy.linalg import eigvalsh_tridiagonal, eigvalsh
    >>> d = 3*np.ones(4)
    >>> e = -1*np.ones(3)
    >>> w = eigvalsh_tridiagonal(d, e)
    >>> A = np.diag(d) + np.diag(e, k=1) + np.diag(e, k=-1)
    >>> w2 = eigvalsh(A)  # Verify with other eigenvalue routines
    >>> np.allclose(w - w2, np.zeros(4))
    True
    T)ru   r   r   rT   tollapack_driver)r   )r\   er   r   rT   r   r   r2   r2   r3   r     s    K
c             C   s  t | |d} t ||d}x6| |fD ]*}|jdkr8td|jjdkr"tdq"W | j|jd krttd| j|jf t||d| j\}}	}
}}}t|t	stdd	}||krtd
||f |dkr|dkrdnd}t
|f| |f\}| }|dkr2|dkr
td|std|| |\}}t|}n|dkrl|dkrNtd|| ||d\}}}t|}n|dkrt|}d}t
|f| |f\}|rdnd}|| |||	|
||||	\}}}}}nzt|jd |j}||dd< t
d| |f\}|| |||	|
|||d\}}}t|d || |||	|
|||||d
\}}}}t||d  |d| }|rd|S |dkrt
d| |f\}|| ||||\}}t|ddd t|}|| |dd|f  }}n|ddd|f }||fS dS ) a  
    Solve eigenvalue problem for a real symmetric tridiagonal matrix.

    Find eigenvalues `w` and optionally right eigenvectors `v` of ``a``::

        a v[:,i] = w[i] v[:,i]
        v.H v    = identity

    For a real symmetric matrix ``a`` with diagonal elements `d` and
    off-diagonal elements `e`.

    Parameters
    ----------
    d : ndarray, shape (ndim,)
        The diagonal elements of the array.
    e : ndarray, shape (ndim-1,)
        The off-diagonal elements of the array.
    select : {'a', 'v', 'i'}, optional
        Which eigenvalues to calculate

        ======  ========================================
        select  calculated
        ======  ========================================
        'a'     All eigenvalues
        'v'     Eigenvalues in the interval (min, max]
        'i'     Eigenvalues with indices min <= i <= max
        ======  ========================================
    select_range : (min, max), optional
        Range of selected eigenvalues
    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.
    tol : float
        The absolute tolerance to which each eigenvalue is required
        (only used when 'stebz' is the `lapack_driver`).
        An eigenvalue (or cluster) is considered to have converged if it
        lies in an interval of this width. If <= 0. (default),
        the value ``eps*|a|`` is used where eps is the machine precision,
        and ``|a|`` is the 1-norm of the matrix ``a``.
    lapack_driver : str
        LAPACK function to use, can be 'auto', 'stemr', 'stebz', 'sterf',
        or 'stev'. When 'auto' (default), it will use 'stemr' if ``select='a'``
        and 'stebz' otherwise. When 'stebz' is used to find the eigenvalues and
        ``eigvals_only=False``, then a second LAPACK call (to ``?STEIN``) is
        used to find the corresponding eigenvectors. 'sterf' can only be
        used when ``eigvals_only=True`` and ``select='a'``. 'stev' can only
        be used when ``select='a'``.

    Returns
    -------
    w : (M,) ndarray
        The eigenvalues, in ascending order, each repeated according to its
        multiplicity.
    v : (M, M) ndarray
        The normalized eigenvector corresponding to the eigenvalue ``w[i]`` is
        the column ``v[:,i]``.

    Raises
    ------
    LinAlgError
        If eigenvalue computation does not converge.

    See Also
    --------
    eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
        matrices
    eig : eigenvalues and right eigenvectors for non-symmetric arrays
    eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
    eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
        band matrices

    Notes
    -----
    This function makes use of LAPACK ``S/DSTEMR`` routines.

    Examples
    --------
    >>> from scipy.linalg import eigh_tridiagonal
    >>> d = 3*np.ones(4)
    >>> e = -1*np.ones(3)
    >>> w, v = eigh_tridiagonal(d, e)
    >>> A = np.diag(d) + np.diag(e, k=1) + np.diag(e, k=-1)
    >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
    True
    )rT   r#   zexpected one-dimensional arrayr   z$Only real arrays currently supportedz-d (%s) must have one more element than e (%s)r   zlapack_driver must be str)r   stemrsterfstebzstevz'lapack_driver must be one of %s, got %sr   r   r   r   z)sterf can only be used when select == "a"z0sterf can only be used when eigvals_only is Truer   z(stev can only be used when select == "a")r   EBNr+   )stemr_lworkr   )r   r>   liworkz (eigh_tridiagonal))Zsteinzstein (eigh_tridiagonal)z"%d eigenvectors failed to converge)r]   )r!   r   r_   r*   rF   	TypeErrorr   r   r~   r"   r'   r^   floatr   rE   r   )r\   r   ru   r   r   rT   r   r   ZcheckrN   r   rl   rm   _Zdriversfuncr   r.   rP   r0   r/   r   r   orderZiblockZisplitZe_r   r>   r   r2   r2   r3   r     s|    X









!did not converge (LAPACK info=%d)c             C   s>   | dk rt d|  |f | dkr:|r:td| || f dS )zCheck info return value.r   z+illegal value in argument %d of internal %sz%s N)r_   r$   )rP   rz   r]   r2   r2   r3   rE     s
    rE   c             C   sL  t | |d}t|jdks.|jd |jd kr6td|pBt|| }|jd dkrn|rj|t|jd fS |S td|f\}}}||d|d\}}	}
}}t|dd	d
 t|}t	||jd |	|
d}|||	|
|dd\}}}t|dd	d
 t
|d}|s|S td|f\}}t	|||	|
d}||||	|
|dd\}}t|dd	d
 ||fS )a  
    Compute Hessenberg form of a matrix.

    The Hessenberg decomposition is::

        A = Q H Q^H

    where `Q` is unitary/orthogonal and `H` has only zero elements below
    the first sub-diagonal.

    Parameters
    ----------
    a : (M, M) array_like
        Matrix to bring into Hessenberg form.
    calc_q : bool, optional
        Whether to compute the transformation matrix.  Default is False.
    overwrite_a : bool, optional
        Whether to overwrite `a`; may improve performance.
        Default is False.
    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
    -------
    H : (M, M) ndarray
        Hessenberg form of `a`.
    Q : (M, M) ndarray
        Unitary/orthogonal similarity transformation matrix ``A = Q H Q^H``.
        Only returned if ``calc_q=True``.

    Examples
    --------
    >>> from scipy.linalg import hessenberg
    >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
    >>> H, Q = hessenberg(A, calc_q=True)
    >>> H
    array([[  2.        , -11.65843866,   1.42005301,   0.25349066],
           [ -9.94987437,  14.53535354,  -5.31022304,   2.43081618],
           [  0.        ,  -1.83299243,   0.38969961,  -0.51527034],
           [  0.        ,   0.        ,  -3.83189513,   1.07494686]])
    >>> np.allclose(Q @ H @ Q.conj().T - A, np.zeros((4, 4)))
    True
    )rT   rU   r   r#   zexpected square matrix)gehrdgebalgehrd_lwork)ZpermuterL   zgebal (hessenberg)F)r]   )rx   ry   )rx   ry   r>   rL   zgehrd (hessenberg)r+   )orghrorghr_lwork)r`   taurx   ry   r>   rL   zorghr (hessenberg))r!   r^   rG   r_   r%   r,   r   r'   rE   r(   Ztriu)r`   Zcalc_qrL   rT   rH   r   r   r   Zbarx   ry   ZpivscalerP   nr>   Zhqr   hr   r   qr2   r2   r3   r     s0    ."c             C   s0  t | t | } }| jdk r$td|jdk r6td|j| jd krNtd| jd }| jdd }|jd |jd krtd	|jd |krtd
t| }|jdd}|d dk stdt|}|dd }|d }|ddd }	|ddd }
d}xL|D ]D}|ddd |ddd k s4td||ddd f7 }qW t	|||f | j
jd}t|}| j
|d||f< | ||	f  j|||	|
f < | ||
f  j|||
|	f < t	|||f tjd}d|d||f< d|||	|	f < d|||	|
f < d|||
|	f < d|||
|
f < td||j
}||fS )a	  
    Converts complex eigenvalues ``w`` and eigenvectors ``v`` to real
    eigenvalues in a block diagonal form ``wr`` and the associated real
    eigenvectors ``vr``, such that::

        vr @ wr = X @ vr

    continues to hold, where ``X`` is the original array for which ``w`` and
    ``v`` are the eigenvalues and eigenvectors.

    .. versionadded:: 1.1.0

    Parameters
    ----------
    w : (..., M) array_like
        Complex or real eigenvalues, an array or stack of arrays

        Conjugate pairs must not be interleaved, else the wrong result
        will be produced. So ``[1+1j, 1, 1-1j]`` will give a correct result, but
        ``[1+1j, 2+1j, 1-1j, 2-1j]`` will not.

    v : (..., M, M) array_like
        Complex or real eigenvectors, a square array or stack of square arrays.

    Returns
    -------
    wr : (..., M, M) ndarray
        Real diagonal block form of eigenvalues
    vr : (..., M, M) ndarray
        Real eigenvectors associated with ``wr``

    See Also
    --------
    eig : Eigenvalues and right eigenvectors for non-symmetric arrays
    rsf2csf : Convert real Schur form to complex Schur form

    Notes
    -----
    ``w``, ``v`` must be the eigenstructure for some *real* matrix ``X``.
    For example, obtained by ``w, v = scipy.linalg.eig(X)`` or
    ``w, v = numpy.linalg.eig(X)`` in which case ``X`` can also represent
    stacked arrays.

    .. versionadded:: 1.1.0

    Examples
    --------
    >>> X = np.array([[1, 2, 3], [0, 4, 5], [0, -5, 4]])
    >>> X
    array([[ 1,  2,  3],
           [ 0,  4,  5],
           [ 0, -5,  4]])

    >>> from scipy import linalg
    >>> w, v = linalg.eig(X)
    >>> w
    array([ 1.+0.j,  4.+5.j,  4.-5.j])
    >>> v
    array([[ 1.00000+0.j     , -0.01906-0.40016j, -0.01906+0.40016j],
           [ 0.00000+0.j     ,  0.00000-0.64788j,  0.00000+0.64788j],
           [ 0.00000+0.j     ,  0.64788+0.j     ,  0.64788-0.j     ]])

    >>> wr, vr = linalg.cdf2rdf(w, v)
    >>> wr
    array([[ 1.,  0.,  0.],
           [ 0.,  4.,  5.],
           [ 0., -5.,  4.]])
    >>> vr
    array([[ 1.     ,  0.40016, -0.01906],
           [ 0.     ,  0.64788,  0.     ],
           [ 0.     ,  0.     ,  0.64788]])

    >>> vr @ wr
    array([[ 1.     ,  1.69593,  1.9246 ],
           [ 0.     ,  2.59153,  3.23942],
           [ 0.     , -3.23942,  2.59153]])
    >>> X @ vr
    array([[ 1.     ,  1.69593,  1.9246 ],
           [ 0.     ,  2.59153,  3.23942],
           [ 0.     , -3.23942,  2.59153]])
    r#   z)expected w to be at least one-dimensionalrU   z)expected v to be at least two-dimensionalzUexpected eigenvectors array to have exactly one dimension more than eigenvalues arrayr+   Nr?   zVexpected v to be a square matrix or stacked square matrices: v.shape[-2] = v.shape[-1]z7expected the same number of eigenvalues as eigenvectors)Zaxisr   z/expected complex-conjugate pairs of eigenvaluesr2   z(Conjugate pair spanned different arrays!)r*   .g      ?y              ?g      ?y             z...ij,...jk->...ik)r!   r   r_   rG   r   sumr6   r   AssertionErrorr   rA   r*   rk   r-   r,   Zcdoubler   )r.   r/   r   MZcomplex_maskZ	n_complexidxZ	idx_stackZidx_elemjkZ	stack_indr1   rb   ZdiurO   r2   r2   r3   r     sN    R



*)NFTFFTF)	NTFFFTNr#   T)FFFr`   Nr   T)NFTF)NTFFTNr#   T)FFr`   NT)r`   NTr   r   )Fr`   NTr   r   )r   )FFT)4Z
__future__r   r   r   __all__r,   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zscipy._lib.sixr    Zscipy._lib._utilr!   r"   Zmiscr$   r%   r&   Zlapackr'   r(   rD   r4   r<   rS   r   r   r   r   r	   r   r   r
   r   r   rE   r   r   r2   r2   r2   r3   <module>   sV   L* 
   
 a  
 % 
I  
Z 
[ 
O 
 !
	
P