o
    X۷ik1                     @  s   d dl mZ 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Zdd Z	e
dd	d
d Ze
dddd ZdddZdddZdd ZdddZdd ZdddZdS )    )annotationsN)_core)_decomposition)_utilc                 C  s,   t | ||fd}|tj|dddd}|S )NF
compute_uvr   axis)cupymoveaxisr   svd)xrow_axiscol_axisopyresult r   H/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupy/linalg/_norms.py_multi_svd_norm   s   r   
_norm_ord2)z?->lzb->lzB->Lzh->lzH->Lzi->lzI->Lzl->lzL->Lzq->qzQ->Q)ze->e)NNNfloatzf->fzd->d)z	in0 * in0a + bout0 = sqrt(type_out0_raw(a))N_norm_ord2_complex)zF->fzD->d)z1in0.real() * in0.real() + in0.imag() * in0.imag()r   r   NFc                 C  sl  t | jjtjs| t} |du rT| j}|du s(|dkr |dks(|dkrT|dv rT| jjdkr@t	| 
 }||9 }t| }n	t| |   }|rR|d| }|S | j}|du rbtt|}nt|ts|zt|}W n tyx   tdw |f}t|dkr|tjkrt	| j||dS |tj krt	| j||dS |d	kr| d	k| jjj||dS |dkrt	| j||dS |du s|dkr| jjdkrt| ||dS t| ||dS zt| W n ty   td
w t	| }||C }|j||d}|tj||jdC }|S t|dkr2|\}	}
|	d	k r|	|7 }	|
d	k r%|
|7 }
d	|	  kr1|k r@n nd	|
  kr?|k sIn td|| jf |	|
krRtd|dkrgtj tj!d	d}t"| |	|
|}n|dkr|tj tj!dd}t"| |	|
|}n|dkr|
|	kr|
d8 }
t	| j|	dj|
d}n|tjkr|	|
kr|	d8 }	t	| j|
dj|	d}nd|dkr|
|	kr|
d8 }
t	| j|	dj|
d}nI|tj kr|	|
kr|	d8 }	t	| j|
dj|	d}n,|dv r| jjdkrt| |d}nt| |d}n|dkrt"| |	|
tj}ntd|r0t#| j}d||d	 < d||d < ||}|S td)a  Returns one of matrix norms specified by ``ord`` parameter.

    See numpy.linalg.norm for more detail.

    Args:
        x (cupy.ndarray): Array to take norm. If ``axis`` is None,
            ``x`` must be 1-D or 2-D.
        ord (non-zero int, inf, -inf, 'fro'): Norm type.
        axis (int, 2-tuple of ints, None): 1-D or 2-D norm is computed over
            ``axis``.
        keepdims (bool): If this is set ``True``, the axes which are normed
            over are left.

    Returns:
        cupy.ndarray

    N      )ffroc)r   z6'axis' must be None, an integer or a tuple of integersr   keepdimsr   zInvalid norm order for vectors.)dtypez*Invalid axis %r for an array with shape %rzDuplicate axes given.)indicesr   r   r   )Nr!   r    nucz Invalid norm order for matrices.z&Improper number of dimensions to norm.)$
issubclassr%   typenumpyinexactastyper   ndimkindabsravelr   sqrtsumreshapetuplerange
isinstanceint	Exception	TypeErrorleninfmaxminrealr   r   
ValueError
reciprocalshape	functoolspartialtaker   list)r   ordr   r$   r-   sretndabsxr   r   op_maxop_min	ret_shaper   r   r   norm!   s   




6












rN   c           	      C  s  ddl }t| } | jdkrtjd|du s |dks |dkrTtjj| dd}|jdd	 |dkr<|d
 |d  }n|d |d
  }W d   n1 sNw   Y  nGt	|  t
|  t|  t| \}}|jdd	 tj| }t| |ddt||dd }W d   n1 sw   Y  |j|dd}t|}t|}| r|t| jdd M }|jdkrtj||< |S |rtj|d< |S )a  Returns the condition number of a matrix.

    This function computes the condition number using one of several norms,
    depending on the value of `p`.

    Args:
        x (cupy.ndarray): The matrix whose condition number is computed.
        p (str, int, optional): The norm type used.
            The following norms are supported:

            - None: 2-norm
            - 'fro': Frobenius norm.
            - inf: max(sum(abs(x), axis=1)).
            - -inf: min(sum(abs(x), axis=1)).
            - 1: max(sum(abs(x), axis=0)).
            - -1: min(sum(abs(x), axis=0)).
            - 2: 2-norm (largest singular value).
            - -2: smallest singular value.

    Returns:
        cupy.ndarray: The condition number of the matrix. May be infinite.
    r   Nz#cond is not defined on empty arraysr   r   Fr	   ignore)linalg).r   ).r   r   r   copyr   )cupyxr   asarraysizerP   LinAlgErrorr   errstater   _assert_cupy_array_assert_stacked_2d_assert_stacked_squarelinalg_common_typeinvrN   r,   isnananyr-   r;   )	r   prS   rG   rtresult_tinvxnan_maskr   r   r   cond   s@   


	






re   c                 C  s   t | \}}|t| S )a  Returns the determinant of an array.

    Args:
        a (cupy.ndarray): The input matrix with dimension ``(..., N, N)``.

    Returns:
        cupy.ndarray: Determinant of ``a``. Its shape is ``a.shape[:-2]``.

    .. seealso:: :func:`numpy.linalg.det`
    )slogdetr   exp)asignlogdetr   r   r   det   s   rk   c                 C  st   | j dk r| dk tS tj| dd}|du r0|jdddt| jd	d  t	|j
j }||kjdtjd
S )aB  Return matrix rank of array using SVD method

    Args:
        M (cupy.ndarray): Input array. Its `ndim` must be less than or equal to
            2.
        tol (None or float): Threshold of singular value of `M`.
            When `tol` is `None`, and `eps` is the epsilon value for datatype
            of `M`, then `tol` is set to `S.max() * max(M.shape) * eps`,
            where `S` is the singular value of `M`.
            It obeys :func:`numpy.linalg.matrix_rank`.

    Returns:
        cupy.ndarray: Rank of `M`.

    .. seealso:: :func:`numpy.linalg.matrix_rank`
    r   r   Fr	   Nr   Tr#   r   )r   r%   )r-   r^   r,   r7   r   r   r<   rA   r*   finfor%   epsr2   intp)MtolSr   r   r   matrix_rank   s   
rr   c                 C  sx  t |  t |  t | \}}t|j }| j}|dd }|d }| j	dkr;t
||}t
||}||fS t| |\}	}
}t
j|	ddd}t
t
|jdd}t
j|
t
d|d kdd}|jdkrw|t
j|dk dd7 }|d	 d d }|jd
kr|t
j|t
| dd }||}|j|dd}|dk}t
||d||t
||d||fS )a  Returns sign and logarithm of the determinant of an array.

    It calculates the natural logarithm of the determinant of a given value.

    Args:
        a (cupy.ndarray): The input matrix with dimension ``(..., N, N)``.

    Returns:
        tuple of :class:`~cupy.ndarray`:
            It returns a tuple ``(sign, logdet)``. ``sign`` represents each
            sign of the determinant as a real number ``0``, ``1`` or ``-1``.
            'logdet' represents the natural logarithm of the absolute of the
            determinant.
            If the determinant is zero, ``sign`` will be ``0`` and ``logdet``
            will be ``-inf``.
            The shapes of both ``sign`` and ``logdet`` are equal to
            ``a.shape[:-2]``.

    .. warning::
        This function calls one or more cuSOLVER routine(s) which may yield
        invalid results if input conditions are not met.
        To detect these invalid results, you can set the `linalg`
        configuration to a value that is not `ignore` in
        :func:`cupyx.errstate` or :func:`cupyx.seterr`.

    .. warning::
        To produce the same results as :func:`numpy.linalg.slogdet` for
        singular inputs, set the `linalg` configuration to `raise`.

    .. seealso:: :func:`numpy.linalg.slogdet`
    Nr   r   r   )axis1axis2r   r   r    r   r"   FrQ   z-inf)r   rY   rZ   r[   r*   r%   charlowerrA   rU   r   oneszerosr   
_lu_factordiagonallogr/   r2   count_nonzeroaranger.   prodr,   wherer)   r3   )rh   r%   
sign_dtypelogdet_dtypea_shaperA   nri   rj   luipivdev_infodiagnon_zerosingularr   r   r   rf   	  s4   
 




rf   r   c                 C  s   |  |||||S )a  Returns the sum along the diagonals of an array.

    It computes the sum along the diagonals at ``axis1`` and ``axis2``.

    Args:
        a (cupy.ndarray): Array to take trace.
        offset (int): Index of diagonals. Zero indicates the main diagonal, a
            positive value an upper diagonal, and a negative value a lower
            diagonal.
        axis1 (int): The first axis along which the trace is taken.
        axis2 (int): The second axis along which the trace is taken.
        dtype: Data type specifier of the output.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The trace of ``a`` along axes ``(axis1, axis2)``.

    .. seealso:: :func:`numpy.trace`

    )trace)rh   offsetrs   rt   r%   outr   r   r   r   W  s   r   )NNF)N)r   r   r   NN)
__future__r   r*   r   r   cupy.linalgr   r   rB   r   create_reduction_funcr   r   rN   re   rk   rr   rf   r   r   r   r   r   <module>   s4    
 
>
N