U
    Hvf                     @   s   d Z dgZddlZddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZmZ G d	d
 d
ejjZddlmZ dddZdddZdS )zz
Matrix square root for general matrices and for upper triangular matrices.

This module exists to avoid cyclic imports.

sqrtm    N)_asarray_validated   )norm)ztrsyldtrsyl)schurrsf2csfc                   @   s   e Zd ZdS )
SqrtmErrorN)__name__
__module____qualname__ r   r   @/tmp/pip-unpacked-wheel-96ln3f52/scipy/linalg/_matfuncs_sqrtm.pyr
      s   r
   )within_block_loop@   c              
   C   s\  t | }t | o t |dk}|sJt j| t jdd} t j|t jd}n"t j| t jdd} t j|t jd}t t |}| j\}}t	|| d}t
||\}}|d }	|| }
|
| ||	  |krtdg }d}|
|f||	ffD ]0\}}t|D ]}|||| f ||7 }qqzt|| || W n0 tk
rZ } zt|j |W 5 d}~X Y nX t|D ]}|| \}}t|d ddD ]}|| \}}| ||||f }|| dkr||||||f |||||f  }|||||f }|||||f }|r&t|||\}}}nt|||\}}}|| |||||f< qqd|S )	a  
    Matrix square root of an upper triangular matrix.

    This is a helper function for `sqrtm` and `logm`.

    Parameters
    ----------
    T : (N, N) array_like upper triangular
        Matrix whose square root to evaluate
    blocksize : int, optional
        If the blocksize is not degenerate with respect to the
        size of the input array, then use a blocked algorithm. (Default: 64)

    Returns
    -------
    sqrtm : (N, N) ndarray
        Value of the sqrt function at `T`

    References
    ----------
    .. [1] Edvin Deadman, Nicholas J. Higham, Rui Ralha (2013)
           "Blocked Schur Algorithms for Computing the Matrix Square Root,
           Lecture Notes in Computer Science, 7782. pp. 171-182.

    r   C)dtypeorder)r   r   zinternal inconsistencyN)npZdiag	isrealobjminasarrayZ
complex128Zfloat64sqrtshapemaxdivmod	Exceptionrangeappendr   RuntimeErrorr
   argsdotr   r   )T	blocksizeZT_diagkeep_it_realRnZnblocksZbsmallZnlargeZblargeZnsmallZstart_stop_pairsstartcountsizeiejZjstartZjstopistartistopSZRiiZRjjxZscaleinfor   r   r   _sqrtm_triu   sT    

  r4   Tc                 C   s  t | jj}t| ddd} t| jdkr2td|dk rBtdt | }|r~t	| \}}t 
|t |st||\}}nt	| dd\}}d	}zt||d
}t |j}	|||	}
t |
s|
jdt |dd d	d}
nRtt dr|
jdt |d dd d	d}
n"|
jdt |d dd d	d}
W n0 tk
rj   d}t | }
|
t j Y nX |r|rtd |
S z&t|
|
|  dd t| d }W n tk
r   t j}Y nX |
|fS dS )a  
    Matrix square root.

    Parameters
    ----------
    A : (N, N) array_like
        Matrix whose square root to evaluate
    disp : bool, optional
        Print warning if error in the result is estimated large
        instead of returning estimated error. (Default: True)
    blocksize : integer, optional
        If the blocksize is not degenerate with respect to the
        size of the input array, then use a blocked algorithm. (Default: 64)

    Returns
    -------
    sqrtm : (N, N) ndarray
        Value of the sqrt function at `A`. The dtype is float or complex.
        The precision (data size) is determined based on the precision of
        input `A`. When the dtype is float, the precision is same as `A`.
        When the dtype is complex, the precition is double as `A`. The
        precision might be cliped by each dtype precision range.

    errest : float
        (if disp == False)

        Frobenius norm of the estimated error, ||err||_F / ||A||_F

    References
    ----------
    .. [1] Edvin Deadman, Nicholas J. Higham, Rui Ralha (2013)
           "Blocked Schur Algorithms for Computing the Matrix Square Root,
           Lecture Notes in Computer Science, 7782. pp. 171-182.

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.linalg import sqrtm
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> r = sqrtm(a)
    >>> r
    array([[ 0.75592895,  1.13389342],
           [ 0.37796447,  1.88982237]])
    >>> r.dot(r)
    array([[ 1.,  3.],
           [ 1.,  4.]])

    T)Zcheck_finiteZ
as_inexact   z$Non-matrix input to matrix function.r   z#The blocksize should be at least 1.complex)outputF)r%   f   )copyZ
complex256c       zFailed to find a square root.ZfroN)r   r   r   itemsizer   lenr   
ValueErrorr   r   Zarray_equalZtriur	   r4   	conjugater$   r#   ZiscomplexobjZastypeZcliphasattrr
   Z
empty_likefillnanprintr   inf)AZdispr%   Z	byte_sizer&   r$   ZZfailflagr'   ZZHXZarg2r   r   r   r   u   sF    1

 $&
&)r   )Tr   )__doc____all__Znumpyr   Zscipy._lib._utilr   Z_miscr   Zlapackr   r   Z_decomp_schurr   r	   ZlinalgZLinAlgErrorr
   Z_matfuncs_sqrtm_triur   r4   r   r   r   r   r   <module>   s   
Z