U
    Gv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	 ddl
mZ dd	l
mZ dd
l
mZ ddl
mZ ejejejejdZejejejejdZdddZG dd dZdddZdS )a  
Python wrapper for PROPACK
--------------------------

PROPACK is a collection of Fortran routines for iterative computation
of partial SVDs of large matrices or linear operators.

Based on BSD licensed pypropack project:
  http://github.com/jakevdp/pypropack
  Author: Jake Vanderplas <vanderplas@astro.washington.edu>

PROPACK source is BSD licensed, and available at
  http://soi.stanford.edu/~rmunk/PROPACK/
_svdp    N)check_random_state)aslinearoperator)LinAlgError   )	_spropack)	_dpropack)	_cpropack)	_zpropack)fdFDLS)LMSMc                   @   s8   e Zd ZdZdd Zdd Zedd Zedd	 Zd
S )_AProdz
    Wrapper class for linear operator

    The call signature of the __call__ method matches the callback of
    the PROPACK routines.
    c                 C   s8   zt || _W n$ tk
r2   t t|| _Y nX d S N)r   A	TypeErrornpZasarray)selfr    r   =/tmp/pip-unpacked-wheel-96ln3f52/scipy/sparse/linalg/_svdp.py__init__:   s    z_AProd.__init__c                 C   s6   |dkr| j ||d d < n| j ||d d < d S )Nn)r   matvecZrmatvec)r   Ztransamr   xyZsparmiparmr   r   r   __call__@   s    z_AProd.__call__c                 C   s   | j jS r   )r   shaper   r   r   r   r#   F   s    z_AProd.shapec              	   C   s@   z
| j jW S  tk
r:   | j t| j jd j Y S X d S )Nr   )r   dtypeAttributeErrorr   r   zerosr#   r$   r   r   r   r%   J   s    
z_AProd.dtypeN)	__name__
__module____qualname____doc__r   r"   propertyr#   r%   r   r   r   r   r   3   s   
r   r   TFMb`?c           +      C   s  t | r"t djdk r"tdt|}| }|dkrBtd|sV|dkrVtdt| }|j	j
}zt| }t| }W nR tk
r   t t jd|drt 	tj
}nt 	tj
}t| }t| }Y nX |j\}}|d	k s|t||krtd
|dkrd| }|dkrd}t|d	 |d	 |}||k rJtd| d| d|rTdnd}|rbdnd}t j||d	 fd|d}t j||fd|d}|dkr|j|d|dddf< t t jd|dr*|dddf  d|j|d 7  < n:z||dddf< W n$ tk
r(   td| Y nX |
dkrFt t |j}
|dkr`t |jd }|rt j|
|||f| d}|dkr|| }|t|| ||krtdn|dk rtdnt j|
||f| d}t jtt|tt|fdd}d}|s|rb|| d|  d| |  d td | | d|  d |t||  } d| }!nB|| d|  d!| |  d t|| d| d  } d!| d	 }!t j| | d}"t j|!t jd}#t jd	| d}$t jd	t jd}%| rt j|| d"|  |d}&|"|&|#f}'n|"|#f}'|rd|t| |||||||||||	f|'|||$|%f \}}(})}}*n2||||||||||	f	|'|||$|%f \}}(})}}*|*dkrt d#|* d$n |*dk rt d%| d&| d'|ddd|f |(|ddd|f ! j"|)fS )(a;  
    Compute the singular value decomposition of a linear operator using PROPACK

    Parameters
    ----------
    A : array_like, sparse matrix, or LinearOperator
        Operator for which SVD will be computed.  If `A` is a LinearOperator
        object, it must define both ``matvec`` and ``rmatvec`` methods.
    k : int
        Number of singular values/vectors to compute
    which : {"LM", "SM"}
        Which singluar triplets to compute:
        - 'LM': compute triplets corresponding to the `k` largest singular
                values
        - 'SM': compute triplets corresponding to the `k` smallest singular
                values
        `which='SM'` requires `irl_mode=True`.  Computes largest singular
        values by default.
    irl_mode : bool, optional
        If `True`, then compute SVD using IRL (implicitly restarted Lanczos)
        mode.  Default is `True`.
    kmax : int, optional
        Maximal number of iterations / maximal dimension of the Krylov
        subspace. Default is ``10 * k``.
    compute_u : bool, optional
        If `True` (default) then compute left singular vectors, `u`.
    compute_v : bool, optional
        If `True` (default) then compute right singular vectors, `v`.
    tol : float, optional
        The desired relative accuracy for computed singular values.
        If not specified, it will be set based on machine precision.
    v0 : array_like, optional
        Starting vector for iterations: must be of length ``A.shape[0]``.
        If not specified, PROPACK will generate a starting vector.
    full_output : bool, optional
        If `True`, then return sigma_bound.  Default is `False`.
    delta : float, optional
        Level of orthogonality to maintain between Lanczos vectors.
        Default is set based on machine precision.
    eta : float, optional
        Orthogonality cutoff.  During reorthogonalization, vectors with
        component larger than `eta` along the Lanczos vector will be purged.
        Default is set based on machine precision.
    anorm : float, optional
        Estimate of ``||A||``.  Default is `0`.
    cgs : bool, optional
        If `True`, reorthogonalization is done using classical Gram-Schmidt.
        If `False` (default), it is done using modified Gram-Schmidt.
    elr : bool, optional
        If `True` (default), then extended local orthogonality is enforced
        when obtaining singular vectors.
    min_relgap : float, optional
        The smallest relative gap allowed between any shift in IRL mode.
        Default is `0.001`.  Accessed only if ``irl_mode=True``.
    shifts : int, optional
        Number of shifts per restart in IRL mode.  Default is determined
        to satisfy ``k <= min(kmax-shifts, m, n)``.  Must be
        >= 0, but choosing 0 might lead to performance degredation.
        Accessed only if ``irl_mode=True``.
    maxiter : int, optional
        Maximum number of restarts in IRL mode.  Default is `1000`.
        Accessed only if ``irl_mode=True``.
    random_state : {None, int, `numpy.random.Generator`,
                    `numpy.random.RandomState`}, optional

        Pseudorandom number generator state used to generate resamples.

        If `random_state` is ``None`` (or `np.random`), the
        `numpy.random.RandomState` singleton is used.
        If `random_state` is an int, a new ``RandomState`` instance is used,
        seeded with `random_state`.
        If `random_state` is already a ``Generator`` or ``RandomState``
        instance then that instance is used.

    Returns
    -------
    u : ndarray
        The `k` largest (``which="LM"``) or smallest (``which="SM"``) left
        singular vectors, ``shape == (A.shape[0], 3)``, returned only if
        ``compute_u=True``.
    sigma : ndarray
        The top `k` singular values, ``shape == (k,)``
    vt : ndarray
        The `k` largest (``which="LM"``) or smallest (``which="SM"``) right
        singular vectors, ``shape == (3, A.shape[1])``, returned only if
        ``compute_v=True``.
    sigma_bound : ndarray
        the error bounds on the singular values sigma, returned only if
        ``full_output=True``.

    r      zBPROPACK complex-valued SVD methods not available for 32-bit builds>   r   r   z#`which` must be either 'LM' or 'SM'r   z#`which`='SM' requires irl_mode=True)r%   r   z.k must be positive and not greater than m or nN
   i  z3kmax must be greater than or equal to k, but kmax (z) < k ()r    r   r   )orderr%   )sizey              ?zv0 must be of length g      ?z0shifts must satisfy k <= min(kmax-shifts, m, n)!zshifts must be >= 0!i   	                   z#An invariant subspace of dimension z was found.zk=z0 singular triplets did not converge within kmax=z iterations)#r   ZiscomplexobjZintpitemsizer   r   upper
ValueErrorr   r%   char_lansvd_irl_dict_lansvd_dictKeyErroremptycomplexfloatr#   minr'   uniformsqrtZfinfoZepsarraylowerintboolmaxZint32isupper_which_converterr   ZconjT)+r   kwhichZirl_modeZkmaxZ	compute_uZ	compute_vZv0Zfull_outputZtoldeltaetaZanormZcgsZelrZ
min_relgapZshiftsmaxiterZrandom_stateZaprodtypZ
lansvd_irlZlansvdr   r   ZjobuZjobvuvZdoptionZioption	blocksizeZlworkZliworkZworkZiworkZdparmr!   ZzworkZworkssigmaZbndinfor   r   r   r   R   s    a




&





"	 
6

               


)r   TNTTNFr   NNr   FTr-   NNN)r+   __all__Znumpyr   Zscipy._lib._utilr   Zscipy.sparse.linalgr   Zscipy.linalgr   Z_propackr   r   r	   r
   ZslansvdZdlansvdZclansvdZzlansvdr@   Zslansvd_irlZdlansvd_irlZclansvd_irlZzlansvd_irlr?   rN   r   r   r   r   r   r   <module>   sN   	                          