o
    i?;                     @   s   d dl 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dddd d	d
ddZdd Zdd ZeddddZdd Zddd ddd	dddZdd ZdS )    N)cublas)_dtype)device)_csr)
_interface   LMT)whichv0ncvmaxitertolreturn_eigenvectorsc                C   s  | j d }| jdks| j d | j d krtd| j | jjdvr*td| j|dkr5td|||kr@td||d	vrKtd
||du r^ttd| |d |d }ntt||d |d }|du rrd| }|dkr}t	
| jj}tj|f| jd}	tj|f| jj d}
tj||f| jd}|du rtj|f| j}|t| |d< n|}|t| |d< d}|dkrt| ||}nt}|| |||	|
d| |}t|	|
d||\}}|j| }|
d |dddf  }t|}tj|f| jd}||kr||k rd|
d|< ||	d|< |j|d|< ttjd|d| j|d| ttjd|d| j|d| |t| ||< | ||  |d< tj|| ||	| d ||	| ||  8 }||d| j| 8 }tj||
| d ||
|  ||d < || |||	|
|d | ||| 7 }t|	|
|||\}}|j| }|
d |dddf  }t|}||kr||k s|rt|}|| |dd|f fS t|S )a3  
    Find ``k`` eigenvalues and eigenvectors of the real symmetric square
    matrix or complex Hermitian matrix ``A``.

    Solves ``Ax = wx``, the standard eigenvalue problem for ``w`` eigenvalues
    with corresponding eigenvectors ``x``.

    Args:
        a (ndarray, spmatrix or LinearOperator): A symmetric square matrix with
            dimension ``(n, n)``. ``a`` must :class:`cupy.ndarray`,
            :class:`cupyx.scipy.sparse.spmatrix` or
            :class:`cupyx.scipy.sparse.linalg.LinearOperator`.
        k (int): The number of eigenvalues and eigenvectors to compute. Must be
            ``1 <= k < n``.
        which (str): 'LM' or 'LA' or 'SA'.
            'LM': finds ``k`` largest (in magnitude) eigenvalues.
            'LA': finds ``k`` largest (algebraic) eigenvalues.
            'SA': finds ``k`` smallest (algebraic) eigenvalues.

        v0 (ndarray): Starting vector for iteration. If ``None``, a random
            unit vector is used.
        ncv (int): The number of Lanczos vectors generated. Must be
            ``k + 1 < ncv < n``. If ``None``, default value is used.
        maxiter (int): Maximum number of Lanczos update iterations.
            If ``None``, default value is used.
        tol (float): Tolerance for residuals ``||Ax - wx||``. If ``0``, machine
            precision is used.
        return_eigenvectors (bool): If ``True``, returns eigenvectors in
            addition to eigenvalues.

    Returns:
        tuple:
            If ``return_eigenvectors is True``, it returns ``w`` and ``x``
            where ``w`` is eigenvalues and ``x`` is eigenvectors. Otherwise,
            it returns only ``w``.

    .. seealso:: :func:`scipy.sparse.linalg.eigsh`

    .. note::
        This function uses the thick-restart Lanczos methods
        (https://sdm.lbl.gov/~kewu/ps/trlan.html).

    r         z"expected square matrix (shape: {})fdFDunsupprted dtype (actual: {})%k must be greater than 0 (actual: {})z%k must be smaller than n (actual: {}))r   LASAz*which must be 'LM','LA'or'SA' (actual: {})N    
   dtypefast.out)shapendim
ValueErrorformatr   char	TypeErrorminmaxnumpyfinfoepscupyzerosloweremptyrandomastyper   nrm2_lanczos_fast_lanczos_asis_eigsh_solve_ritzTgemv_cublasCUBLAS_OP_CCUBLAS_OP_Ndotcargsortsort)akr	   r
   r   r   r   r   nalphabetaVuupadte_impllanczositerwsxbeta_kresuuidx rL   ]/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/cupyx/scipy/sparse/linalg/_eigen.pyeigsh   s~   
-

  



rN   c                 C   s   t ||D ]J}| ||  |d< tj|| ||| d ||j|d |d   j |d |d   8 }tj||| d ||d krE d S |||  ||d < qd S )N.r   r   )ranger   r8   r3   conjr/   )r;   r@   rA   r>   r?   i_starti_endirL   rL   rM   r1      s   0r1   c                    s  ddl m  ddlm t t| jjdkr(tj	tj
tjtjnA| jjdkr;tjtjtjtjn.| jjdkrNtjtjtjtjn| jjdkratjtjtjtjntd| jd t| rdrt  jt !d	| jt !d
| jt"#| j j$t%j&
f| jdt%j&|f| jdt%j&
f| jdt%j&d| jdt j!d	| jdt j!d
| jdt j!d| jd	|  	
fdd}|S )Nr   )cusparsefdFDzinvalid dtype ({})spmvg      ?g        r   rL   g      c                    s  | u sJ d ur7j | }j}j|}	 jj|j|jjj|	j	}
t|
tj	}|| d< t
||D ]*}d u rP|  |d< n jj|j|jjj|	j|jj
 ttj z
jjd|jjd|jj||j   W t nt w d ||d  d< ttj z1
|jj||j  jjdjjd 
jj||d  jjdjjd W t nt w 
	jjjjd|jjd tj
|d jj|jj
|jjdjjjjd tj
|d 	jj|jj
jjdjj|jjd ||  | 7  < ttj z
|jjd|jj||j   W t nt w ||d krd d S t|||
| qBd S )N.r   r   )SpMatDescriptorcreateDnVecDescriptorspMV_bufferSizectypesdatadescr)   r,   int8rO   spMVptrr5   setPointerModeCUBLAS_POINTER_MODE_DEVICEitemsizefillr6   r7   _kernel_normalize)Ar@   rA   r>   r?   rQ   rR   spmv_desc_Aspmv_desc_vspmv_desc_u	buff_size	spmv_buffrS   	_cusparseaxpybcublas_handlecublas_pointer_moderT   cusparse_handler8   r4   moner=   r/   oneouter_Aspmv_alg
spmv_alpha	spmv_betaspmv_cuda_dtype	spmv_op_arJ   vvvzerorL   rM   aux   s   




z_lanczos_fast.<locals>.aux)'cupy_backends.cuda.libsrT   cupyxr   get_cublas_handler5   getPointerModer   r"   sdotsnrm2sgemvsaxpyddotdnrm2dgemvdaxpycdotcscnrm2cgemvcaxpyzdotcdznrm2zgemvzaxpyr#   r!   r   isspmatrix_csrcheck_availabilityget_cusparse_handle CUSPARSE_OPERATION_NON_TRANSPOSEr&   arrayr   to_cuda_dtypeCUSPARSE_MV_ALG_DEFAULTr)   r,   )ri   r=   r   r   rL   ro   rM   r0      sV   
8Ur0   z!T u, raw S beta, int32 j, int32 nzT v, raw T Vz&v = u / beta[j]; V[i + (j+1) * n] = v;cupy_eigsh_normalizec                 C   sh  t | } t |}t| }|tj|d d dd }|tj|d d dd }|d urBt |}|||d |f< ||d ||f< tj|\}}|dkrjt|}||| d   }	|d d || d  f }
n@|dkrtt|}||| d   }	|d d || d  f }
n|dkrt|}||d |  }	|d d |d | f }
t |	t |
fS )Nr   r   )r<   r   r   r   )	r)   asnumpyr&   diaglinalgeighr9   absoluter   )r>   r?   rH   r<   r	   trE   rF   rK   wkskrL   rL   rM   r2   +  s.   





r2   )r   r   r	   r   return_singular_vectorsc             	   C   s  | j dkrtd| j| jjdvrtd| j| j\}}|dkr+td||t||kr9td|t	| } ||krI| j
| }	} n| | j
}	} |rat|	|  |||||dd	\}
}nt|	|  |||||d
d	}
t|
d}
|
jj }ddd}|| t|j }|t|
 }|
|k}|  }t|
}t|
| |d|< |s|S |dd|f }||kr|}| | |d|  }n|}| | |d|  }t||| }t||| }||| jfS )a  Finds the largest ``k`` singular values/vectors for a sparse matrix.

    Args:
        a (ndarray, spmatrix or LinearOperator): A real or complex array with
            dimension ``(m, n)``. ``a`` must :class:`cupy.ndarray`,
            :class:`cupyx.scipy.sparse.spmatrix` or
            :class:`cupyx.scipy.sparse.linalg.LinearOperator`.
        k (int): The number of singular values/vectors to compute. Must be
            ``1 <= k < min(m, n)``.
        ncv (int): The number of Lanczos vectors generated. Must be
            ``k + 1 < ncv < min(m, n)``. If ``None``, default value is used.
        tol (float): Tolerance for singular values. If ``0``, machine precision
            is used.
        which (str): Only 'LM' is supported. 'LM': finds ``k`` largest singular
            values.
        maxiter (int): Maximum number of Lanczos update iterations.
            If ``None``, default value is used.
        return_singular_vectors (bool): If ``True``, returns singular vectors
            in addition to singular values.

    Returns:
        tuple:
            If ``return_singular_vectors`` is ``True``, it returns ``u``, ``s``
            and ``vt`` where ``u`` is left singular vectors, ``s`` is singular
            values and ``vt`` is right singular vectors. Otherwise, it returns
            only ``s``.

    .. seealso:: :func:`scipy.sparse.linalg.svds`

    .. note::
        This is a naive implementation using cupyx.scipy.sparse.linalg.eigsh as
        an eigensolver on ``a.H @ a`` or ``a @ a.H``.

    r   zexpected 2D (shape: {})r   r   r   r   z-k must be smaller than min(m, n) (actual: {})T)r<   r	   r   r   r   r   Fg     @@g    .A)rU   rV   N)r   r    r!   r   r   r"   r#   r$   r   aslinearoperatorHrN   r)   maximumr+   r&   r'   r(   r%   sumitem
zeros_likesqrt_augmented_orthnormal_colsrP   r3   )r;   r<   r   r   r	   r   r   mr=   aHrE   rG   r   factorcondcutoffabove_cutoffn_largerF   r~   rA   rL   rL   rM   svdsO  sT   
$



r   c                 C   s   |dkr| S | j \}}tj||| f| jd}| |d d d |f< t||| D ]6}tj|f| j}|||d d d |f   |d d d |f j 8 }|tj	
| |d d |f< q(|S )Nr   r   )r   r)   r,   r   rO   r-   r.   rP   r3   r   norm)rG   n_augr   r=   yrS   r~   rL   rL   rM   r     s   
6r   )r   )r&   r)   r   
cupy._corer   	cupy.cudar   r   r5   cupyx.scipy.sparser   cupyx.scipy.sparse.linalgr   rN   r1   r0   ElementwiseKernelrh   r2   r   r   rL   rL   rL   rM   <module>   s0    
  	
$U