U
    ªÊ¹j�*  ã                	   @   sò   d Z ddgZddlmZmZ ddlZddlmZ ddlmZ	 dd	l
mZmZ deeee ee edœdd„Zdeee ee ee eeeef dœdd„Zdeee ee ee eeeef dœdd„Zdeee eeeeeef dœdd„ZdS )zCImplement various linear algebra algorithms for low rank matrices.
Úsvd_lowrankÚpca_lowranké    )ÚOptionalÚTupleN)ÚTensoré   )Ú_linalg_utils)Úhandle_torch_functionÚhas_torch_functioné   )ÚAÚqÚniterÚMÚreturnc                 C   s  |dkrdn|}| j dd… \}}t | ¡}tj}tj|||| jd�}t | ¡}	|dkr¤tj 	|| |ƒ¡j
}
t|ƒD ],}tj 	||	|
ƒ¡j
}
tj 	|| |
ƒ¡j
}
qtnrt |¡}tj 	|| |ƒ|||ƒ ¡j
}
t|ƒD ]@}tj 	||	|
ƒ|||
ƒ ¡j
}
tj 	|| |
ƒ|||
ƒ ¡j
}
qÔ|
S )a8  Return tensor :math:`Q` with :math:`q` orthonormal columns such
    that :math:`Q Q^H A` approximates :math:`A`. If :math:`M` is
    specified, then :math:`Q` is such that :math:`Q Q^H (A - M)`
    approximates :math:`A - M`.

    .. note:: The implementation is based on the Algorithm 4.4 from
              Halko et al, 2009.

    .. note:: For an adequate approximation of a k-rank matrix
              :math:`A`, where k is not known in advance but could be
              estimated, the number of :math:`Q` columns, q, can be
              choosen according to the following criteria: in general,
              :math:`k <= q <= min(2*k, m, n)`. For large low-rank
              matrices, take :math:`q = k + 5..10`.  If k is
              relatively small compared to :math:`min(m, n)`, choosing
              :math:`q = k + 0..2` may be sufficient.

    .. note:: To obtain repeatable results, reset the seed for the
              pseudorandom number generator

    Args::
        A (Tensor): the input tensor of size :math:`(*, m, n)`

        q (int): the dimension of subspace spanned by :math:`Q`
                 columns.

        niter (int, optional): the number of subspace iterations to
                               conduct; ``niter`` must be a
                               nonnegative integer. In most cases, the
                               default value 2 is more than enough.

        M (Tensor, optional): the input tensor's mean of size
                              :math:`(*, 1, n)`.

    References::
        - Nathan Halko, Per-Gunnar Martinsson, and Joel Tropp, Finding
          structure with randomness: probabilistic algorithms for
          constructing approximate matrix decompositions,
          arXiv:0909.4061 [math.NA; math.PR], 2009 (available at
          `arXiv <http://arxiv.org/abs/0909.4061>`_).
    Nr   éþÿÿÿ©ÚdtypeÚdevice)ÚshapeÚ_utilsÚget_floating_dtypeÚmatmulÚtorchZrandnr   ZtransjugateÚlinalgZqrÚQÚrange)r   r   r   r   ÚmÚnr   r   ÚRZA_Hr   ÚiZM_H© r!   úM/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/_lowrank.pyÚget_approximate_basis   s"    -


 r#   é   c                 C   s\   t j ¡ sL| |f}ttt|ƒƒ t jtdƒf¡sLt|ƒrLt	t
|| |||d�S t| |||d�S )a_  Return the singular value decomposition ``(U, S, V)`` of a matrix,
    batches of matrices, or a sparse matrix :math:`A` such that
    :math:`A \approx U diag(S) V^T`. In case :math:`M` is given, then
    SVD is computed for the matrix :math:`A - M`.

    .. note:: The implementation is based on the Algorithm 5.1 from
              Halko et al, 2009.

    .. note:: To obtain repeatable results, reset the seed for the
              pseudorandom number generator

    .. note:: The input is assumed to be a low-rank matrix.

    .. note:: In general, use the full-rank SVD implementation
              :func:`torch.linalg.svd` for dense matrices due to its 10-fold
              higher performance characteristics. The low-rank SVD
              will be useful for huge sparse matrices that
              :func:`torch.linalg.svd` cannot handle.

    Args::
        A (Tensor): the input tensor of size :math:`(*, m, n)`

        q (int, optional): a slightly overestimated rank of A.

        niter (int, optional): the number of subspace iterations to
                               conduct; niter must be a nonnegative
                               integer, and defaults to 2

        M (Tensor, optional): the input tensor's mean of size
                              :math:`(*, 1, n)`.

    References::
        - Nathan Halko, Per-Gunnar Martinsson, and Joel Tropp, Finding
          structure with randomness: probabilistic algorithms for
          constructing approximate matrix decompositions,
          arXiv:0909.4061 [math.NA; math.PR], 2009 (available at
          `arXiv <https://arxiv.org/abs/0909.4061>`_).

    N)r   r   r   )r   ÚjitÚis_scriptingÚsetÚmapÚtypeÚissubsetr   r
   r	   r   Ú_svd_lowrank)r   r   r   r   Z
tensor_opsr!   r!   r"   r   T   s     -
ÿþ     ÿc                 C   sö  |d krdn|}| j dd … \}}tj}|d kr6d }n
t |¡}t | ¡}||k s\||k�rt||||d�}	t |	¡}
|d krŠ|| |
ƒ}n|| |
ƒ|||
ƒ }|j d |ksºt|j |fƒ‚|j d |ksÖt|j |fƒ‚|j d |j d ksôt|j ƒ‚tjj	|dd�\}}}|j
}|	 |¡}nÐt| |||d�}	t |	¡}
|d k�rL|||
ƒ}n|||
ƒ|||
ƒ }t |¡}|j d |k�sˆt|j |fƒ‚|j d |k�s¦t|j |fƒ‚|j d |j d k�sÆt|j ƒ‚tjj	|dd�\}}}|j
}|	 |¡}|||fS )Nr$   r   ©r   r   éÿÿÿÿF)Zfull_matrices)r   r   r   Ú	transposer#   Ú	conjugateÚAssertionErrorr   r   ZsvdZmH)r   r   r   r   r   r   r   ZM_tZA_tr   ZQ_cZB_tÚUÚSZVhÚVÚBr!   r!   r"   r+   Œ   s@    





 
r+   T)r   r   Úcenterr   r   c                 C   s¶  t j ¡ s8t| ƒt jk	r8t| fƒr8tt| f| |||d�S | jdd… \}}|dkr`t	d||ƒ}n0|dkrv|t	||ƒks�t
d|› dt	||ƒ› �ƒ‚|dks¨t
d|› d	�ƒ‚t | ¡}|sÆt| ||dd
�S t | ¡�r�t| jƒdkrèt
dƒ‚t jj| dd�| }| ¡ d }t jdt|ƒ|j|jd�}	||	d< t j|	| ¡ |df|| jd�}
t j| jdd… d|f || jd�}t t j |
|¡¡}t| |||d
�S | jddd�}t| | ||dd
�S dS )aº  Performs linear Principal Component Analysis (PCA) on a low-rank
    matrix, batches of such matrices, or sparse matrix.

    This function returns a namedtuple ``(U, S, V)`` which is the
    nearly optimal approximation of a singular value decomposition of
    a centered matrix :math:`A` such that :math:`A = U diag(S) V^T`.

    .. note:: The relation of ``(U, S, V)`` to PCA is as follows:

                - :math:`A` is a data matrix with ``m`` samples and
                  ``n`` features

                - the :math:`V` columns represent the principal directions

                - :math:`S ** 2 / (m - 1)` contains the eigenvalues of
                  :math:`A^T A / (m - 1)` which is the covariance of
                  ``A`` when ``center=True`` is provided.

                - ``matmul(A, V[:, :k])`` projects data to the first k
                  principal components

    .. note:: Different from the standard SVD, the size of returned
              matrices depend on the specified rank and q
              values as follows:

                - :math:`U` is m x q matrix

                - :math:`S` is q-vector

                - :math:`V` is n x q matrix

    .. note:: To obtain repeatable results, reset the seed for the
              pseudorandom number generator

    Args:

        A (Tensor): the input tensor of size :math:`(*, m, n)`

        q (int, optional): a slightly overestimated rank of
                           :math:`A`. By default, ``q = min(6, m,
                           n)``.

        center (bool, optional): if True, center the input tensor,
                                 otherwise, assume that the input is
                                 centered.

        niter (int, optional): the number of subspace iterations to
                               conduct; niter must be a nonnegative
                               integer, and defaults to 2.

    References::

        - Nathan Halko, Per-Gunnar Martinsson, and Joel Tropp, Finding
          structure with randomness: probabilistic algorithms for
          constructing approximate matrix decompositions,
          arXiv:0909.4061 [math.NA; math.PR], 2009 (available at
          `arXiv <http://arxiv.org/abs/0909.4061>`_).

    )r   r5   r   r   Nr$   r   zq(=z>) must be non-negative integer and not greater than min(m, n)=zniter(=z) must be non-negative integerr,   r   z8pca_lowrank input is expected to be 2-dimensional tensor)r   )Údimr   r   T)r6   Zkeepdim)r   r%   r&   r)   r   r
   r	   r   r   ÚminÚ
ValueErrorr   r   r+   Z	is_sparseÚlenÚsparseÚsumÚindicesZzerosr   r   Zsparse_coo_tensorÚvaluesZonesr.   ÚmmZmean)r   r   r5   r   r   r   r   ÚcZcolumn_indicesr<   ZC_tZ	ones_m1_tr   ÚCr!   r!   r"   r   ¿   s\    ?
     ÿÿ
ü    ÿ$)r   N)r$   r   N)r$   r   N)NTr   )Ú__doc__Ú__all__Útypingr   r   r   r   Ú r   r   Z	overridesr	   r
   Úintr#   r   r+   Úboolr   r!   r!   r!   r"   Ú<module>   sZ      ÿ   þH   üû:   üû4     ÿ   þ