
    ukiU)                       d Z ddlmZ ddlmZ ddlZddlZddl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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j4                  ej6                  d      	 d	 	 	 	 	 	 	 	 	 	 	 dd       Z ej4                  ej6                  d      	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 dd       ZdddZdddZ ej@                  ejB                  e       y)u  A JIT-compatible library for QDWH-based singular value decomposition.

QDWH is short for QR-based dynamically weighted Halley iteration. The Halley
iteration implemented through QR decompositions is numerically stable and does
not require solving a linear system involving the iteration matrix or
computing its inversion. This is desirable for multicore and heterogeneous
computing systems.

References:
Nakatsukasa, Yuji, and Nicholas J. Higham.
"Stable and efficient spectral divide and conquer algorithms for the symmetric
eigenvalue decomposition and the SVD." SIAM Journal on Scientific Computing 35,
no. 3 (2013): A1325-A1349.
https://epubs.siam.org/doi/abs/10.1137/120876605

Nakatsukasa, Yuji, Zhaojun Bai, and François Gygi.
"Optimizing Halley's iteration for computing the matrix polar decomposition."
SIAM Journal on Matrix Analysis and Applications 31, no. 5 (2010): 2700-2720.
https://epubs.siam.org/doi/abs/10.1137/090774999
    )annotations)SequenceN)Any)api)config)core)dtypes)lax)numpy)mlir)linalg)qdwh)            )static_argnumsc                   t        j                  | ||      \  }}}}t        j                  ||d      \  }}	t	        j
                  |	d      }	t	        j                  |	d      }
|	|
   }|s|S |dd|
f   }||z  }d t        t        j                  | j                        j                        }|d	   | j                  d
   |z  |d   z  k  }d }fd}t        j                  ||||f      \  }}|||fS )ab  Singular value decomposition for m x n matrix and m >= n.

  Args:
    a: A matrix of shape `m x n` with `m >= n`.
    hermitian: True if `a` is Hermitian.
    compute_uv: Whether to also compute `u` and `v` in addition to `s`.
    max_iterations: The predefined maximum number of iterations of QDWH.

  Returns:
    A 3-tuple (`u`, `s`, `v`), where `u` is a unitary matrix of shape `m x n`,
    `s` is vector of length `n` containing the singular values in the descending
    order, `v` is a unitary matrix of shape `n x n`, and
    `a = (u * s) @ v.T.conj()`. For `compute_uv=False`, only `s` is returned.
  )is_hermitianmax_iterationsF)subset_by_indexsort_eigenvaluesg        T)
descendingNc                    t        j                  | d      \  } }| t        j                  t        j                  t        j                  |      dk\  dd            z  } | S )NF)full_matricesr   r   )
lax_linalgqrjnpdiagwhere)u_outrs     R/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/_src/tpu/linalg/svd.pycorrect_rank_deficiencyz;_svd_tall_and_square_input.<locals>.correct_rank_deficiencyl   sH    }}U%8HE1CHHSYYsxx{a'7B?@@EL    r   r   r   c                    | d   S )Nr    argss    r$   <lambda>z,_svd_tall_and_square_input.<locals>.<lambda>s   s
    Q r&   c                     | d         dfS )Nr   Fr(   )r*   r%   s    r$   r+   z,_svd_tall_and_square_input.<locals>.<lambda>t   s    0a95A r&   )tpu_qdwhr   r   eighr   maximumargsortfloatr	   finfodtypeepsshaper
   
while_loop)a	hermitian
compute_uvr   r   u_ph_vssort_idxs_outv_outr"   r4   do_correctioncond_fbody_fr%   s                     @r$   _svd_tall_and_square_inputrE   8   s   . i,#q!Q
 
5
$!Q 
kk!S! [[t,(
H+%	L AxK.%
+%
 	fll177#''(#)qwwqzC/%(::-&A&^^FFUM,BC(%
	r&   )r   r   r   r      c                   t        j                  t        |d      }t        j                  t        |d      }t        j                  t        |d      }t        j                  t        |d      }|t	        |      dk7  rt        d      t        j                  |d         t        j                  |d	         f}|d   |d	   k\  rt        d
      |d   dk  rt        d      | j                  \  }}||k  r|n|}|d	   |kD  rt        d      |r|d|fk7  rt        d      ||d	   z
  ||d   z
  f}| j                  \  }}d}	||k  r+| j                  j                         } | j                  \  }}d}	d}
|rD||kD  r?t        j                  | dd      \  }}|ddd|f   }|dd|df   }|d|ddf   } d}
n%|d|z  kD  rt        j                  | dd      \  }} d}
|s.t        j                  d      5  t        | ||||      cddd       S t        j                  d      5  t        | ||||      \  |
rz  ddd       |r||kD  rt!        j"                  f      t!        j$                  t!        j&                  |             }d }fd}t)        j*                  |||f      \  }|	rj                  j                         fS j                  j                         fS # 1 sw Y   xY w# 1 sw Y   xY w)a#  Singular value decomposition.

  Args:
    a: A matrix of shape `m x n`.
    full_matrices: If True, `u` and `vh` have the shapes `m x m` and `n x n`,
      respectively. If False, the shapes are `m x k` and `k x n`, respectively,
      where `k = min(m, n)`.
    compute_uv: Whether to also compute `u` and `v` in addition to `s`.
    hermitian: True if `a` is Hermitian.
    max_iterations: The predefined maximum number of iterations of QDWH.
    subset_by_index: Optional 2-tuple [start, end] indicating the range of
      indices of singular components to compute. For example, if
      ``subset_by_index`` = [0,2], then ``svd`` computes the two largest
      singular values (and their singular vectors if `compute_uv` is true.

  Returns:
    A 3-tuple (`u`, `s`, `vh`), where `u` and `vh` are unitary matrices,
    `s` is vector of length `k` containing the singular values in the
    non-increasing order, and `k = min(m, n)`. The shapes of `u` and `vh`
    depend on the value of `full_matrices`. For `compute_uv=False`,
    only `s` is returned.
  zbThe `full_matrices` argument must be statically specified to use `svd` within JAX transformations.z_The `compute_uv` argument must be statically specified to use `svd` within JAX transformations.z^The `hermitian` argument must be statically specified to use `svd` within JAX transformations.zcThe `max_iterations` argument must be statically specified to use `svd` within JAX transformations.Nr   z*subset_by_index must be a tuple of size 2.r   r   z)Got empty index range in subset_by_index.z0Indices in subset_by_index must be non-negative.z0Index in subset_by_index[1] exceeds matrix size.z8full_matrices and subset_by_index cannot be both be set.FT)pivotingr   gffffff?float32c                2    t        j                  | d         S )Nr   )r   logical_notr)   s    r$   r+   zsvd.<locals>.<lambda>   s    Q0 r&   c                   t        j                  d      t        j                  t        j                        t        j                  t        j                        t        j                  t        j                        fS )NT)r   array	full_likenpnan)r*   r@   r"   rA   s    r$   r+   zsvd.<locals>.<lambda>   sK    	iio	mmE266"	mmE266"	mmE266"	 r&   )r   concrete_or_errorboolintlen
ValueErroroperatorindexr5   Tconjr   r   r   default_matmul_precisionrE   r   hstackallisfiniter
   r6   )r7   r   r9   r8   r   r   mnrankis_flipreduce_to_squareq_fulla_fullq
u_out_null	is_finiterC   rD   r<   r@   r"   rA   s                      @@@r$   svdrh   y   sS   > ((
M ;<- %%
J ;<* $$
;) ))	;.  
?q CDD 	q)*q)*O q_Q//BCCqAIJJ77DAqA11DqD IJJQI5
D  oa00$9K2KLO	
$!Q'U	
A77DAqGq1u]]1uDINFFq"1"uA12Jrr1uA 	4!8|]]1uEBda			(	(	3 '
Y
NO 
 &&y1 4	9j./E5% %ie q1uJJz*+Eggcll1o&)0&& >>fy%6!UE5 5%'',,.))
	''= 
 s   8K5&L5K>L
)	algorithmc               F   |(|t         j                  j                  k7  rt        d      | j                  d d }t        j                  t        |||      }t        t        |            D ]  }t        j                  |      } |r ||       \  }}	}
|	||
gS  ||       }	|	gS )Nz6The SVD algorithm parameter is not implemented on TPU.r   r9   r   )r   SvdAlgorithmDEFAULTNotImplementedErrorr5   	functoolspartialrh   rangerT   r   vmap)r7   r   r9   r   ri   
batch_dimsfnr<   ur>   vhs              r$   _svd_tpurx      s    yJ,C,C,K,KK
@B B wws|*	!%	" Z! a	"B !uHAq"q":
1A3Jr&   c                  | j                   \  }|j                  dd  \  }}|A|t        j                  j                  t        j                  j
                  fvrt        d      |dk(  s|dk(  r/ t        j                  t        j                  d      | |||      S  t        j                  t        d      | ||||      S )Nrk   zPOnly the POLAR (which is also DEFAULT on TPU) SVD algorithm is supported on TPU.r   T)multiple_results)r   r9   rl   )avals_inr5   r   rm   rn   POLARro   r   	lower_fun
_empty_svdrx   )	ctxoperandr   r9   r   ri   operand_avalr^   r_   s	            r$   _svd_tpu_lowering_ruler     s     ,,-,			BC	 $!Qy%%##1   	 
 !VqAvG4>>*//$G#	  
94	8	!%
 r&   )N)r7   r   r8   rR   r9   rR   r   rS   r   tuple[int, int] | NonereturnAny | Sequence[Any])TF
   N)r7   r   r   rR   r9   rR   r8   rR   r   rS   r   r   r   r   )"__doc__
__future__r   collections.abcr   rp   rV   typingr   r   rO   jax._srcr   r   r   r	   r
   r   jax._src.interpretersr   jax._src.laxr   r   jax._src.tpu.linalgr   r-   rq   jitrE   rh   rx   r   register_loweringsvd_pr(   r&   r$   <module>r      sR  * # $          ! & - 0 377<8 /3=
== = 	=
 ,= = 9=@ 377?; .2A(
A(A( A( 	A(
 A( ,A( A( <A(H JN 0 LP>   z'')? @r&   