U
    w»|eˆ°  ã                   @   sâ  d Z ddlm  mZ ddlZedƒZdd„ Z	dd„ Z
dd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdqd!d"„Zdrd#d$„Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Z d5d6„ Z!d7d8„ Z"d9d:„ Z#d;d<„ Z$d=d>„ Z%d?d@„ Z&dAdB„ Z'dCdD„ Z(dEdF„ Z)dGdH„ Z*dIdJ„ Z+dKdL„ Z,dMdN„ Z-dOdP„ Z.dQdR„ Z/dsdSdT„Z0dtdUdV„Z1dWdX„ Z2dYdZ„ Z3d[d\„ Z4d]d^„ Z5d_d`„ Z6dadb„ Z7dcdd„ Z8dedf„ Z9dgdh„ Z:didj„ Z;dkdl„ Z<dmdn„ Z=dodp„ Z>dS )uz0
Direct wrappers for Fortran `id_dist` backend.
é    Nznonzero return codec                 C   s.   t  | ¡} | jjr | jdd�} n
t  | ¡} | S )z6
    Same as np.asfortranarray, but ensure a copy
    ÚF©Úorder)ÚnpÚasarrayÚflagsÚf_contiguousÚcopyÚasfortranarray)ÚA© r   ú`/var/www/website-v5/atlas_env/lib/python3.8/site-packages/scipy/linalg/_interpolative_backend.pyÚ_asfortranarray_copy(   s
    

r   c                 C   s
   t  | ¡S )a  
    Generate standard uniform pseudorandom numbers via a very efficient lagged
    Fibonacci method.

    :param n:
        Number of pseudorandom numbers to generate.
    :type n: int

    :return:
        Pseudorandom numbers.
    :rtype: :class:`numpy.ndarray`
    )Ú_idÚid_srand)Únr   r   r   r   8   s    r   c                 C   s   t  | ¡} t | ¡ dS )z¹
    Initialize seed values for :func:`id_srand` (any appropriately random
    numbers will do).

    :param t:
        Array of 55 seed values.
    :type t: :class:`numpy.ndarray`
    N)r   r
   r   Ú	id_srandi)Útr   r   r   r   H   s    	
r   c                   C   s   t  ¡  dS )z5
    Reset seed values to their original values.
    N)r   Ú	id_srandor   r   r   r   r   U   s    r   c                 C   s   t  | ||¡S )a|  
    Transform real vector via a composition of Rokhlin's random transform,
    random subselection, and an FFT.

    In contrast to :func:`idd_sfrm`, this routine works best when the length of
    the transformed vector is the power-of-two integer output by
    :func:`idd_frmi`, or when the length is not specified but instead
    determined a posteriori from the output. The returned transformed vector is
    randomly permuted.

    :param n:
        Greatest power-of-two integer satisfying `n <= x.size` as obtained from
        :func:`idd_frmi`; `n` is also the length of the output vector.
    :type n: int
    :param w:
        Initialization array constructed by :func:`idd_frmi`.
    :type w: :class:`numpy.ndarray`
    :param x:
        Vector to be transformed.
    :type x: :class:`numpy.ndarray`

    :return:
        Transformed vector.
    :rtype: :class:`numpy.ndarray`
    )r   Úidd_frm©r   ÚwÚxr   r   r   r   `   s    r   c                 C   s   t  | |||¡S )aê  
    Transform real vector via a composition of Rokhlin's random transform,
    random subselection, and an FFT.

    In contrast to :func:`idd_frm`, this routine works best when the length of
    the transformed vector is known a priori.

    :param l:
        Length of transformed vector, satisfying `l <= n`.
    :type l: int
    :param n:
        Greatest power-of-two integer satisfying `n <= x.size` as obtained from
        :func:`idd_sfrmi`.
    :type n: int
    :param w:
        Initialization array constructed by :func:`idd_sfrmi`.
    :type w: :class:`numpy.ndarray`
    :param x:
        Vector to be transformed.
    :type x: :class:`numpy.ndarray`

    :return:
        Transformed vector.
    :rtype: :class:`numpy.ndarray`
    )r   Úidd_sfrm©Úlr   r   r   r   r   r   r   }   s    r   c                 C   s
   t  | ¡S )aC  
    Initialize data for :func:`idd_frm`.

    :param m:
        Length of vector to be transformed.
    :type m: int

    :return:
        Greatest power-of-two integer `n` satisfying `n <= m`.
    :rtype: int
    :return:
        Initialization array to be used by :func:`idd_frm`.
    :rtype: :class:`numpy.ndarray`
    )r   Úidd_frmi©Úmr   r   r   r   š   s    r   c                 C   s   t  | |¡S )a•  
    Initialize data for :func:`idd_sfrm`.

    :param l:
        Length of output transformed vector.
    :type l: int
    :param m:
        Length of the vector to be transformed.
    :type m: int

    :return:
        Greatest power-of-two integer `n` satisfying `n <= m`.
    :rtype: int
    :return:
        Initialization array to be used by :func:`idd_sfrm`.
    :rtype: :class:`numpy.ndarray`
    )r   Ú	idd_sfrmi©r   r   r   r   r   r   ¬   s    r   c                 C   sZ   t |ƒ}t | |¡\}}}|jd }|j ¡ d|||  … j||| fdd�}|||fS )až  
    Compute ID of a real matrix to a specified relative precision.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Rank of ID.
    :rtype: int
    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    é   Nr   r   )r   r   Úiddp_idÚshapeÚTÚravelÚreshape©Úepsr   ÚkÚidxÚrnormsr   Úprojr   r   r   r"   Å   s
    
,r"   c                 C   sV   t | ƒ} t | |¡\}}| jd }| j ¡ d|||  … j||| fdd�}||fS )aQ  
    Compute ID of a real matrix to a specified rank.

    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of ID.
    :type k: int

    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    r!   Nr   r   )r   r   Úiddr_idr#   r$   r%   r&   ©r   r)   r*   r+   r   r,   r   r   r   r-   á   s
    
,r-   c                 C   s<   t  | ¡} |jdkr"t | ||¡S | dd…t  |¡f S dS )as  
    Reconstruct matrix from real ID.

    :param B:
        Skeleton matrix.
    :type B: :class:`numpy.ndarray`
    :param idx:
        Column index array.
    :type idx: :class:`numpy.ndarray`
    :param proj:
        Interpolation coefficients.
    :type proj: :class:`numpy.ndarray`

    :return:
        Reconstructed matrix.
    :rtype: :class:`numpy.ndarray`
    r   N)r   r
   Úsizer   Úidd_reconidÚargsort©ÚBr*   r,   r   r   r   r0   ú   s    

r0   c                 C   s   t  | |¡S )a6  
    Reconstruct interpolation matrix from real ID.

    :param idx:
        Column index array.
    :type idx: :class:`numpy.ndarray`
    :param proj:
        Interpolation coefficients.
    :type proj: :class:`numpy.ndarray`

    :return:
        Interpolation matrix.
    :rtype: :class:`numpy.ndarray`
    )r   Úidd_reconint©r*   r,   r   r   r   r4     s    r4   c                 C   s   t  | ¡} t | ||¡S )aN  
    Reconstruct skeleton matrix from real ID.

    :param A:
        Original matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of ID.
    :type k: int
    :param idx:
        Column index array.
    :type idx: :class:`numpy.ndarray`

    :return:
        Skeleton matrix.
    :rtype: :class:`numpy.ndarray`
    )r   r
   r   Úidd_copycols©r   r)   r*   r   r   r   r6   %  s    
r6   c                 C   s2   t  | ¡} t | ||¡\}}}}|r(t‚|||fS )a  
    Convert real ID to SVD.

    :param B:
        Skeleton matrix.
    :type B: :class:`numpy.ndarray`
    :param idx:
        Column index array.
    :type idx: :class:`numpy.ndarray`
    :param proj:
        Interpolation coefficients.
    :type proj: :class:`numpy.ndarray`

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    )r   r
   r   Ú
idd_id2svdÚ_RETCODE_ERROR©r3   r*   r,   ÚUÚVÚSÚierr   r   r   r8   ?  s
    
r8   é   c                 C   s   t  | ||||¡\}}|S )a  
    Estimate spectral norm of a real matrix by the randomized power method.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matvect:
        Function to apply the matrix transpose to a vector, with call signature
        `y = matvect(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvect: function
    :param matvec:
        Function to apply the matrix to a vector, with call signature
        `y = matvec(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec: function
    :param its:
        Number of power method iterations.
    :type its: int

    :return:
        Spectral norm estimate.
    :rtype: float
    )r   Ú	idd_snorm)r   r   ÚmatvectÚmatvecÚitsÚsnormÚvr   r   r   r@   b  s    r@   c              	   C   s   t  | ||||||¡S )a0  
    Estimate spectral norm of the difference of two real matrices by the
    randomized power method.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matvect:
        Function to apply the transpose of the first matrix to a vector, with
        call signature `y = matvect(x)`, where `x` and `y` are the input and
        output vectors, respectively.
    :type matvect: function
    :param matvect2:
        Function to apply the transpose of the second matrix to a vector, with
        call signature `y = matvect2(x)`, where `x` and `y` are the input and
        output vectors, respectively.
    :type matvect2: function
    :param matvec:
        Function to apply the first matrix to a vector, with call signature
        `y = matvec(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec: function
    :param matvec2:
        Function to apply the second matrix to a vector, with call signature
        `y = matvec2(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec2: function
    :param its:
        Number of power method iterations.
    :type its: int

    :return:
        Spectral norm estimate of matrix difference.
    :rtype: float
    )r   Úidd_diffsnorm)r   r   rA   Zmatvect2rB   Úmatvec2rC   r   r   r   rF   ‚  s    'rF   c                 C   s0   t  | ¡} t | |¡\}}}}|r&t‚|||fS )a›  
    Compute SVD of a real matrix to a specified rank.

    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of SVD.
    :type k: int

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    )r   r
   r   Úiddr_svdr9   ©r   r)   r;   r<   r=   r>   r   r   r   rH   °  s
    
rH   c                 C   sª   t  |¡}|j\}}t | |¡\}}}}}}	|	r4t‚||d |||  d … j||fdd�}
||d |||  d … j||fdd�}||d || d … }|
||fS )a¶  
    Compute SVD of a real matrix to a specified relative precision.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    r!   r   r   )r   r
   r#   r   Úiddp_svdr9   r&   ©r(   r   r   r   r)   ÚiUÚiVÚiSr   r>   r;   r<   r=   r   r   r   rJ   Ì  s    

**rJ   c           	      C   sˆ   t  |¡}|j\}}t|ƒ\}}t j|d| d  | d dd�}t | |||¡\}}}|d|||  … j||| fdd�}|||fS )a¸  
    Compute ID of a real matrix to a specified relative precision using random
    sampling.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Rank of ID.
    :rtype: int
    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    é   r!   r   r   N)r   r
   r#   r   Úemptyr   Úiddp_aidr&   ©	r(   r   r   r   Ún2r   r,   r)   r*   r   r   r   rQ   ð  s    

"&rQ   c                 C   sZ   t  |¡}|j\}}t|ƒ\}}t j|| |d |d   dd�}t | |||¡\}}|S )ae  
    Estimate rank of a real matrix to a specified relative precision using
    random sampling.

    The output rank is typically about 8 higher than the actual rank.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Rank estimate.
    :rtype: int
    r!   r   r   )r   r
   r#   r   rP   r   Úidd_estrank©r(   r   r   r   rS   r   Úrar)   r   r   r   rT     s    

"rT   c                 C   s  t  |¡}|j\}}t |¡\}}t jtt||ƒd d| d|  d  dt||ƒd   d| d |d  ƒdd�}t | |||¡\}}}	}
}}|ršt	‚||d |||  d … j
||fdd�}||	d |	||  d … j
||fdd�}||
d |
| d … }|||fS )aÐ  
    Compute SVD of a real matrix to a specified relative precision using random
    sampling.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    r!   é   é   é   rO   r   r   )r   r
   r#   r   r   rP   ÚmaxÚminÚ	iddp_asvdr9   r&   ©r(   r   r   r   rS   Zwinitr   r)   rL   rM   rN   r>   r;   r<   r=   r   r   r   r\   -  s     

4ÿý**r\   c                 C   s~   t j|d d| t||ƒd   dd�}t | ||||¡\}}}}|dkrNt‚|d|||  … j||| fdd�}|||fS )aë  
    Compute ID of a real matrix to a specified relative precision using random
    matrix-vector multiplication.

    :param eps:
        Relative precision.
    :type eps: float
    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matvect:
        Function to apply the matrix transpose to a vector, with call signature
        `y = matvect(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvect: function

    :return:
        Rank of ID.
    :rtype: int
    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    r!   rO   r   r   r   N)r   rP   r[   r   Úiddp_ridr9   r&   )r(   r   r   rA   r,   r)   r*   r>   r   r   r   r^   W  s    (&r^   c                 C   s"   t  | |||¡\}}}|rt‚|S )aQ  
    Estimate rank of a real matrix to a specified relative precision using
    random matrix-vector multiplication.

    :param eps:
        Relative precision.
    :type eps: float
    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matvect:
        Function to apply the matrix transpose to a vector, with call signature
        `y = matvect(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvect: function

    :return:
        Rank estimate.
    :rtype: int
    )r   Úidd_findrankr9   )r(   r   r   rA   r)   rV   r>   r   r   r   r_   }  s    r_   c                 C   sœ   t  | ||||¡\}}}}}	}
|
r&t‚|	|d |||  d … j||fdd�}|	|d |||  d … j||fdd�}|	|d || d … }|||fS )aÚ  
    Compute SVD of a real matrix to a specified relative precision using random
    matrix-vector multiplication.

    :param eps:
        Relative precision.
    :type eps: float
    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matvect:
        Function to apply the matrix transpose to a vector, with call signature
        `y = matvect(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvect: function
    :param matvec:
        Function to apply the matrix to a vector, with call signature
        `y = matvec(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec: function

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    r!   r   r   )r   Ú	iddp_rsvdr9   r&   )r(   r   r   rA   rB   r)   rL   rM   rN   r   r>   r;   r<   r=   r   r   r   r`   Ÿ  s    #**r`   c                 C   sr   t  | ¡} | j\}}t|||ƒ}t | ||¡\}}||krTt j||| fddd�}n|j||| fdd�}||fS )ag  
    Compute ID of a real matrix to a specified rank using random sampling.

    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of ID.
    :type k: int

    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    Úfloat64r   ©Údtyper   r   )r   r
   r#   Ú	iddr_aidir   Úiddr_aidrP   r&   ©r   r)   r   r   r   r*   r,   r   r   r   re   Ï  s    

re   c                 C   s   t  | ||¡S )aO  
    Initialize array for :func:`iddr_aid`.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param k:
        Rank of ID.
    :type k: int

    :return:
        Initialization array to be used by :func:`iddr_aid`.
    :rtype: :class:`numpy.ndarray`
    )r   rd   ©r   r   r)   r   r   r   rd   ì  s    rd   c           
      C   s”   t  | ¡} | j\}}t jd| d | d| d |  d|d   d dd�}t|||ƒ}||d	|j…< t | ||¡\}}}}	|	d
krŠt‚|||fS )a±  
    Compute SVD of a real matrix to a specified rank using random sampling.

    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of SVD.
    :type k: int

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    rO   é   é   é   rY   éd   r   r   Nr   )	r   r
   r#   rP   rd   r/   r   Ú	iddr_asvdr9   ©
r   r)   r   r   r   Zw_r;   r<   r=   r>   r   r   r   rl     s    

:rl   c                 C   sB   t  | |||¡\}}|d|||  … j||| fdd�}||fS )až  
    Compute ID of a real matrix to a specified rank using random matrix-vector
    multiplication.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matvect:
        Function to apply the matrix transpose to a vector, with call signature
        `y = matvect(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvect: function
    :param k:
        Rank of ID.
    :type k: int

    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    Nr   r   )r   Úiddr_ridr&   )r   r   rA   r)   r*   r,   r   r   r   rn   )  s    &rn   c           	      C   s0   t  | ||||¡\}}}}|dkr&t‚|||fS )a¿  
    Compute SVD of a real matrix to a specified rank using random matrix-vector
    multiplication.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matvect:
        Function to apply the matrix transpose to a vector, with call signature
        `y = matvect(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvect: function
    :param matvec:
        Function to apply the matrix to a vector, with call signature
        `y = matvec(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec: function
    :param k:
        Rank of SVD.
    :type k: int

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    r   )r   Ú	iddr_rsvdr9   )	r   r   rA   rB   r)   r;   r<   r=   r>   r   r   r   ro   M  s    #ro   c                 C   s   t  | ||¡S )a  
    Transform complex vector via a composition of Rokhlin's random transform,
    random subselection, and an FFT.

    In contrast to :func:`idz_sfrm`, this routine works best when the length of
    the transformed vector is the power-of-two integer output by
    :func:`idz_frmi`, or when the length is not specified but instead
    determined a posteriori from the output. The returned transformed vector is
    randomly permuted.

    :param n:
        Greatest power-of-two integer satisfying `n <= x.size` as obtained from
        :func:`idz_frmi`; `n` is also the length of the output vector.
    :type n: int
    :param w:
        Initialization array constructed by :func:`idz_frmi`.
    :type w: :class:`numpy.ndarray`
    :param x:
        Vector to be transformed.
    :type x: :class:`numpy.ndarray`

    :return:
        Transformed vector.
    :rtype: :class:`numpy.ndarray`
    )r   Úidz_frmr   r   r   r   rp   z  s    rp   c                 C   s   t  | |||¡S )aí  
    Transform complex vector via a composition of Rokhlin's random transform,
    random subselection, and an FFT.

    In contrast to :func:`idz_frm`, this routine works best when the length of
    the transformed vector is known a priori.

    :param l:
        Length of transformed vector, satisfying `l <= n`.
    :type l: int
    :param n:
        Greatest power-of-two integer satisfying `n <= x.size` as obtained from
        :func:`idz_sfrmi`.
    :type n: int
    :param w:
        Initialization array constructed by :func:`idd_sfrmi`.
    :type w: :class:`numpy.ndarray`
    :param x:
        Vector to be transformed.
    :type x: :class:`numpy.ndarray`

    :return:
        Transformed vector.
    :rtype: :class:`numpy.ndarray`
    )r   Úidz_sfrmr   r   r   r   rq   —  s    rq   c                 C   s
   t  | ¡S )aC  
    Initialize data for :func:`idz_frm`.

    :param m:
        Length of vector to be transformed.
    :type m: int

    :return:
        Greatest power-of-two integer `n` satisfying `n <= m`.
    :rtype: int
    :return:
        Initialization array to be used by :func:`idz_frm`.
    :rtype: :class:`numpy.ndarray`
    )r   Úidz_frmir   r   r   r   rr   ´  s    rr   c                 C   s   t  | |¡S )a•  
    Initialize data for :func:`idz_sfrm`.

    :param l:
        Length of output transformed vector.
    :type l: int
    :param m:
        Length of the vector to be transformed.
    :type m: int

    :return:
        Greatest power-of-two integer `n` satisfying `n <= m`.
    :rtype: int
    :return:
        Initialization array to be used by :func:`idz_sfrm`.
    :rtype: :class:`numpy.ndarray`
    )r   Ú	idz_sfrmir    r   r   r   rs   Æ  s    rs   c                 C   sZ   t |ƒ}t | |¡\}}}|jd }|j ¡ d|||  … j||| fdd�}|||fS )a¡  
    Compute ID of a complex matrix to a specified relative precision.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Rank of ID.
    :rtype: int
    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    r!   Nr   r   )r   r   Úidzp_idr#   r$   r%   r&   r'   r   r   r   rt   ß  s
    
,rt   c                 C   sV   t | ƒ} t | |¡\}}| jd }| j ¡ d|||  … j||| fdd�}||fS )aT  
    Compute ID of a complex matrix to a specified rank.

    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of ID.
    :type k: int

    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    r!   Nr   r   )r   r   Úidzr_idr#   r$   r%   r&   r.   r   r   r   ru   û  s
    
,ru   c                 C   s<   t  | ¡} |jdkr"t | ||¡S | dd…t  |¡f S dS )av  
    Reconstruct matrix from complex ID.

    :param B:
        Skeleton matrix.
    :type B: :class:`numpy.ndarray`
    :param idx:
        Column index array.
    :type idx: :class:`numpy.ndarray`
    :param proj:
        Interpolation coefficients.
    :type proj: :class:`numpy.ndarray`

    :return:
        Reconstructed matrix.
    :rtype: :class:`numpy.ndarray`
    r   N)r   r
   r/   r   Úidz_reconidr1   r2   r   r   r   rv     s    

rv   c                 C   s   t  | |¡S )a9  
    Reconstruct interpolation matrix from complex ID.

    :param idx:
        Column index array.
    :type idx: :class:`numpy.ndarray`
    :param proj:
        Interpolation coefficients.
    :type proj: :class:`numpy.ndarray`

    :return:
        Interpolation matrix.
    :rtype: :class:`numpy.ndarray`
    )r   Úidz_reconintr5   r   r   r   rw   -  s    rw   c                 C   s   t  | ¡} t | ||¡S )aQ  
    Reconstruct skeleton matrix from complex ID.

    :param A:
        Original matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of ID.
    :type k: int
    :param idx:
        Column index array.
    :type idx: :class:`numpy.ndarray`

    :return:
        Skeleton matrix.
    :rtype: :class:`numpy.ndarray`
    )r   r
   r   Úidz_copycolsr7   r   r   r   rx   ?  s    
rx   c                 C   s2   t  | ¡} t | ||¡\}}}}|r(t‚|||fS )a  
    Convert complex ID to SVD.

    :param B:
        Skeleton matrix.
    :type B: :class:`numpy.ndarray`
    :param idx:
        Column index array.
    :type idx: :class:`numpy.ndarray`
    :param proj:
        Interpolation coefficients.
    :type proj: :class:`numpy.ndarray`

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    )r   r
   r   Ú
idz_id2svdr9   r:   r   r   r   ry   Y  s
    
ry   c                 C   s   t  | ||||¡\}}|S )a  
    Estimate spectral norm of a complex matrix by the randomized power method.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matveca:
        Function to apply the matrix adjoint to a vector, with call signature
        `y = matveca(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matveca: function
    :param matvec:
        Function to apply the matrix to a vector, with call signature
        `y = matvec(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec: function
    :param its:
        Number of power method iterations.
    :type its: int

    :return:
        Spectral norm estimate.
    :rtype: float
    )r   Ú	idz_snorm)r   r   ÚmatvecarB   rC   rD   rE   r   r   r   rz   |  s    rz   c              	   C   s   t  | ||||||¡S )a/  
    Estimate spectral norm of the difference of two complex matrices by the
    randomized power method.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matveca:
        Function to apply the adjoint of the first matrix to a vector, with
        call signature `y = matveca(x)`, where `x` and `y` are the input and
        output vectors, respectively.
    :type matveca: function
    :param matveca2:
        Function to apply the adjoint of the second matrix to a vector, with
        call signature `y = matveca2(x)`, where `x` and `y` are the input and
        output vectors, respectively.
    :type matveca2: function
    :param matvec:
        Function to apply the first matrix to a vector, with call signature
        `y = matvec(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec: function
    :param matvec2:
        Function to apply the second matrix to a vector, with call signature
        `y = matvec2(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec2: function
    :param its:
        Number of power method iterations.
    :type its: int

    :return:
        Spectral norm estimate of matrix difference.
    :rtype: float
    )r   Úidz_diffsnorm)r   r   r{   Úmatveca2rB   rG   rC   r   r   r   r|   œ  s    'r|   c                 C   s0   t  | ¡} t | |¡\}}}}|r&t‚|||fS )až  
    Compute SVD of a complex matrix to a specified rank.

    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of SVD.
    :type k: int

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    )r   r
   r   Úidzr_svdr9   rI   r   r   r   r~   Ê  s
    
r~   c                 C   sª   t  |¡}|j\}}t | |¡\}}}}}}	|	r4t‚||d |||  d … j||fdd�}
||d |||  d … j||fdd�}||d || d … }|
||fS )a¹  
    Compute SVD of a complex matrix to a specified relative precision.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    r!   r   r   )r   r
   r#   r   Úidzp_svdr9   r&   rK   r   r   r   r   æ  s    

**r   c           	      C   sŠ   t  |¡}|j\}}t|ƒ\}}t j|d| d  | d ddd�}t | |||¡\}}}|d|||  … j||| fdd�}|||fS )a»  
    Compute ID of a complex matrix to a specified relative precision using
    random sampling.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Rank of ID.
    :rtype: int
    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    rO   r!   Ú
complex128r   rb   Nr   )r   r
   r#   rr   rP   r   Úidzp_aidr&   rR   r   r   r   r�   
  s    

$&r�   c                 C   s\   t  |¡}|j\}}t|ƒ\}}t j|| |d |d   ddd�}t | |||¡\}}|S )ah  
    Estimate rank of a complex matrix to a specified relative precision using
    random sampling.

    The output rank is typically about 8 higher than the actual rank.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Rank estimate.
    :rtype: int
    r!   r€   r   rb   )r   r
   r#   rr   rP   r   Úidz_estrankrU   r   r   r   r‚   )  s    

$r‚   c                 C   s  t  |¡}|j\}}t |¡\}}t jtt||ƒd d| d|  d  dt||ƒd   d| d |d  ƒt jdd�}t 	| |||¡\}}}	}
}}|ržt
‚||d |||  d … j||fdd	�}||	d |	||  d … j||fdd	�}||
d |
| d … }|||fS )
aÓ  
    Compute SVD of a complex matrix to a specified relative precision using
    random sampling.

    :param eps:
        Relative precision.
    :type eps: float
    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    r!   rW   rX   é   é   rO   r   rb   r   )r   r
   r#   r   rr   rP   rZ   r[   r€   Ú	idzp_asvdr9   r&   r]   r   r   r   r…   G  s"    

4ÿ ý**r…   c                 C   s~   t j|d d| t||ƒd   t jdd�}t | ||||¡\}}}}|rNt‚|d|||  … j||| fdd�}|||fS )aì  
    Compute ID of a complex matrix to a specified relative precision using
    random matrix-vector multiplication.

    :param eps:
        Relative precision.
    :type eps: float
    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matveca:
        Function to apply the matrix adjoint to a vector, with call signature
        `y = matveca(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matveca: function

    :return:
        Rank of ID.
    :rtype: int
    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    r!   rO   r   rb   Nr   )r   rP   r[   r€   r   Úidzp_ridr9   r&   )r(   r   r   r{   r,   r)   r*   r>   r   r   r   r†   q  s     þ&r†   c                 C   s"   t  | |||¡\}}}|rt‚|S )aR  
    Estimate rank of a complex matrix to a specified relative precision using
    random matrix-vector multiplication.

    :param eps:
        Relative precision.
    :type eps: float
    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matveca:
        Function to apply the matrix adjoint to a vector, with call signature
        `y = matveca(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matveca: function

    :return:
        Rank estimate.
    :rtype: int
    )r   Úidz_findrankr9   )r(   r   r   r{   r)   rV   r>   r   r   r   r‡   ™  s    r‡   c                 C   sœ   t  | ||||¡\}}}}}	}
|
r&t‚|	|d |||  d … j||fdd�}|	|d |||  d … j||fdd�}|	|d || d … }|||fS )aÛ  
    Compute SVD of a complex matrix to a specified relative precision using
    random matrix-vector multiplication.

    :param eps:
        Relative precision.
    :type eps: float
    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matveca:
        Function to apply the matrix adjoint to a vector, with call signature
        `y = matveca(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matveca: function
    :param matvec:
        Function to apply the matrix to a vector, with call signature
        `y = matvec(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec: function

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    r!   r   r   )r   Ú	idzp_rsvdr9   r&   )r(   r   r   r{   rB   r)   rL   rM   rN   r   r>   r;   r<   r=   r   r   r   rˆ   »  s    #**rˆ   c                 C   sr   t  | ¡} | j\}}t|||ƒ}t | ||¡\}}||krTt j||| fddd�}n|j||| fdd�}||fS )aj  
    Compute ID of a complex matrix to a specified rank using random sampling.

    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of ID.
    :type k: int

    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    r€   r   rb   r   )r   r
   r#   Ú	idzr_aidir   Úidzr_aidrP   r&   rf   r   r   r   rŠ   ë  s    

rŠ   c                 C   s   t  | ||¡S )aO  
    Initialize array for :func:`idzr_aid`.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param k:
        Rank of ID.
    :type k: int

    :return:
        Initialization array to be used by :func:`idzr_aid`.
    :rtype: :class:`numpy.ndarray`
    )r   r‰   rg   r   r   r   r‰     s    r‰   c           
      C   sš   t  | ¡} | j\}}t jd| d | d| d |  d|d   d|  d dd	d
�}t|||ƒ}||d|j…< t | ||¡\}}}}	|	r�t‚|||fS )a´  
    Compute SVD of a complex matrix to a specified rank using random sampling.

    :param A:
        Matrix.
    :type A: :class:`numpy.ndarray`
    :param k:
        Rank of SVD.
    :type k: int

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    rO   é   ri   rj   r„   é
   éZ   r€   r   rb   N)	r   r
   r#   rP   r‰   r/   r   Ú	idzr_asvdr9   rm   r   r   r   rŽ   !  s    

6 þrŽ   c                 C   sB   t  | |||¡\}}|d|||  … j||| fdd�}||fS )aŸ  
    Compute ID of a complex matrix to a specified rank using random
    matrix-vector multiplication.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matveca:
        Function to apply the matrix adjoint to a vector, with call signature
        `y = matveca(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matveca: function
    :param k:
        Rank of ID.
    :type k: int

    :return:
        Column index array.
    :rtype: :class:`numpy.ndarray`
    :return:
        Interpolation coefficients.
    :rtype: :class:`numpy.ndarray`
    Nr   r   )r   Úidzr_ridr&   )r   r   r{   r)   r*   r,   r   r   r   r�   G  s    &r�   c           	      C   s,   t  | ||||¡\}}}}|r"t‚|||fS )aÀ  
    Compute SVD of a complex matrix to a specified rank using random
    matrix-vector multiplication.

    :param m:
        Matrix row dimension.
    :type m: int
    :param n:
        Matrix column dimension.
    :type n: int
    :param matveca:
        Function to apply the matrix adjoint to a vector, with call signature
        `y = matveca(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matveca: function
    :param matvec:
        Function to apply the matrix to a vector, with call signature
        `y = matvec(x)`, where `x` and `y` are the input and output vectors,
        respectively.
    :type matvec: function
    :param k:
        Rank of SVD.
    :type k: int

    :return:
        Left singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Right singular vectors.
    :rtype: :class:`numpy.ndarray`
    :return:
        Singular values.
    :rtype: :class:`numpy.ndarray`
    )r   Ú	idzr_rsvdr9   )	r   r   r{   rB   r)   r;   r<   r=   r>   r   r   r   r�   k  s    #r�   )r?   )r?   )r?   )r?   )?Ú__doc__Zscipy.linalg._interpolativeÚlinalgZ_interpolativer   Únumpyr   ÚRuntimeErrorr9   r   r   r   r   r   r   r   r   r"   r-   r0   r4   r6   r8   r@   rF   rH   rJ   rQ   rT   r\   r^   r_   r`   re   rd   rl   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r|   r~   r   r�   r‚   r…   r†   r‡   rˆ   rŠ   r‰   rŽ   r�   r�   r   r   r   r   Ú<module>   sr   #
 
.$*&"0$$-#
 
.$*("0&$