U
    Kc!                     @   s  d dl mZ d dlmZmZmZmZ d dlZd dlm	Z
 d dlmZ d dlmZ d dlm  mZ d dlmZ d dlmZmZmZmZmZmZ d dlmZ ddd	d
gZeej ejedddZd dl m!Z! e!ej"j#j$eddd'ddee%ee e&eej edddZ'dd Z(dd Z)eddd(ddeee%ef ee&eej eddd	Z*eddd)ddeeee%ef  ee e&eej eddd
Z+edd d!ddd*ee&eeeef d"d#dZ,eddeed$d%d&Z-dS )+    )partial)ListOptionalTupleUnionN)Tensor)checkcheck_fp_or_complexcheck_is_matrixDimsType
NumberTypeTensorLikeType)out_wrappersvdvector_normmatrix_normnormdtypex_dtypefn_namec                    sv    dk	rrt t pt  fdd t t tk fdd t t  kfdd dS )zG
    Checks related to the dtype kwarg in `linalg.*norm` functions
    Nc                      s    d  S )Nz1: dtype should be floating point or complex. Got  r   )r   r   r   ?/tmp/pip-unpacked-wheel-gikjz4vx/torch/_refs/linalg/__init__.py<lambda>&       z"check_norm_dtype.<locals>.<lambda>c                      s   dj trdnd dS )Nz:{fn_name}: dtype should be {d} for {d} inputs. Got {dtype}complexreal)r   dr   )formatutilsis_complex_dtyper   r   r   r   r   r   r   *   s   c                      s     d dS )Nz: the dtype of the input (zJ) should be convertible without narrowing to the specified dtype ({dtype})r   r   )r   r   r   r   r   2   r   )r   r   is_float_dtyper    Zget_higher_dtyper   r   r!   r   check_norm_dtype   s    r#   )register_decompositionT)Zexact_dtype       @Fr   )xorddimkeepdimr   returnc          
         s  t | jd t|tr|g}nt|ts8|d k	r8t|}|  dkrdk sXtdkrt|d k	olt	|dkfdd | j
}|d k	st|D ]  t|  dk fdd qt|| jd t| tjj|\}}ttj|d}dkrtjt| d|||d	S tdkr0|tjt| ||d
S tdkrX|tjt| ||d
S t| |} ttj||d
}	d dkrt| jst| } |t|	t| d S d S )Nzlinalg.vector_normr           infc                      s   d  dS )N&linalg.vector_norm cannot compute the zH norm on an empty tensor because the operation does not have an identityr   r   )r(   r   r   r   Q   r   zvector_norm.<locals>.<lambda>c                      s   d d  dS )Nr.   z norm on the dimension zL because this dimension is empty and the operation does not have an identityr   r   r   r(   r   r   r   Y   r   r&   r)   r*   r   )r)   r*   z-infr%         ?)r	   r   
isinstanceintr   listZnumelfloatr   lenshapeAssertionErrorr#   r   Zreduction_dtypesZREDUCTION_OUTPUT_TYPE_KINDZCOMPLEX_TO_FLOATr   primsconvert_element_typerefssumneamaxtorchabsaminr"   pow)
r'   r(   r)   r*   r   r7   Zcomputation_dtypeZresult_dtypeZto_result_dtypeZ
reduce_sumr   r/   r   r   ;   sF    
 

  

c                    s*    fddt |D }| f |S )Nc                    s    g | ]}| kr|kr|qS r   r   ).0idim0dim1r   r   
<listcomp>y   s       z)backshift_permutation.<locals>.<listcomp>)rangeextend)rF   rG   ndimretr   rE   r   backshift_permutationv   s    rM   c                 C   s   dd t t| dd dD S )Nc                 S   s   g | ]\}}|qS r   r   )rC   rD   jr   r   r   rH      s     z'inverse_permutation.<locals>.<listcomp>c                 S   s   | d S )N   r   )Zi_jr   r   r   r      r   z%inverse_permutation.<locals>.<lambda>)key)sorted	enumerate)permr   r   r   inverse_permutation~   s    rT   fro)Ar(   r)   r*   r   r+   c                C   s>  t | d t| j|}t|tr(|f}tt|dkdd  t|d |d kdd  t|| j	d t|t
r t|dkd	d  t| j	d|d
kd |dkrt| d|||dS |d k	rt| |} t|d |d | j}ttt| |d|}|rt|}tt|d|}|S nt|}t|ddtdfkdd  t| j	d|dkd t|dkrjtjntj|d}	|dkr|d k	rt| |} t|d |d | j}|	tt| |dd}|rt|}tt|d|}|S |\}
}|tdkr
||
 }
}|s"|
|k r"|d8 }|	t| d|
||d|S d S )Nzlinalg.matrix_norm   c                   S   s   dS )Nz4linalg.matrix_norm: dim must be a 2-tuple. Got {dim}r   r   r   r   r   r      r   zmatrix_norm.<locals>.<lambda>r   rO   c                   S   s   dS )NzDlinalg.matrix_norm: dims must be different. Got ({dim[0]}, {dim[1]})r   r   r   r   r   r      r   )rU   nucc                   S   s   dS Nz.linalg.matrix_norm: Order {ord} not supported.r   r   r   r   r   r      r   r[   )Zallow_low_precision_dtypesrU   r&   rX   r-   c                   S   s   dS r\   r   r   r   r   r   r      r   r,   )r*   r%   )r)   r1   r0   )r
   r   Zcanonicalize_dimsrK   r2   r3   r   r6   r#   r   strr	   r   r9   r:   rM   r?   r<   svdvalsZ	transposerT   Z	unsqueezer@   r5   r   r>   rA   )rY   r(   r)   r*   r   rS   resultZinv_permZabs_ordZmax_minrF   rG   r   r   r   r      sv    


    


 c                C   s   |d k	r0t |tr|f}tt|dkdd  n|d k	rLt| jdkdd  |d k	r|d k	rht|dksz|d kr| jdkr|d krd}t| ||||dS |d krd}t| ||||dS d S )	N)rO   rZ   c                   S   s   dS )NzHlinalg.norm: If dim is specified, it must be of length 1 or 2. Got {dim}r   r   r   r   r   r      r   znorm.<locals>.<lambda>c                   S   s   dS )NzZlinalg.norm: If dim is not specified but ord is, the input must be 1D or 2D. Got {A.ndim}Dr   r   r   r   r   r      r   rZ   )r   rO   r&   r%   )r2   r3   r   r6   rK   r   r   )rY   r(   r)   r*   r   r   r   r   r      s6    	


USZVh)rY   full_matricesr+   c                 C   s   t j| |dS )Nrb   )r9   r   )rY   rb   r   r   r   r      s    )rY   r+   c                 C   s   t | ddd S )NFrc   rO   )r   )rY   r   r   r   r^      s    r^   )r%   NF)rU   rV   F)NNF)T).	functoolsr   typingr   r   r   r   r?   Ztorch._primsZ_primsr9   Ztorch._prims_commonZ_prims_commonr   Ztorch._refsZ_refsr;   Ztorch._refs.linalgZlinalgr   r   r	   r
   r   r   r   Ztorch._prims_common.wrappersr   __all__r   r]   r#   Ztorch._decompr$   opsZatenZlinalg_vector_normr5   boolr   rM   rT   r   r   r   r^   r   r   r   r   <module>   s       9   
O   " 