
    Vpf$                        d Z 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mZ ddZddZdd	Zd
 Zd Zd Z ej        ej        d          ddddddd            ZdS )u0  A JIT-compatible library for QDWH-based polar decomposition.

QDWH is short for QR-based dynamically weighted Halley iteration. The Halley
iteration implemented through QR decmopositions does not require matrix
inversion. This is desirable for multicore and heterogeneous computing systems.

Reference: 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
    )annotationsN)lax)core)linalgc                   t          j        |           t          |          k    sJ d}t          |          D ]9\  }}|2t	          j        t           j        | j        |          |k     }||n||z  }:|| nt          j        || |          S )zMasks `x` up to the dynamic shape `dims`.

  Replaces values outside those dimensions with `alternative`. `alternative` is
  broadcast with `x`.
  N)	jnpndimlen	enumerater   broadcasted_iotaint32shapewhere)xdimsalternativemaskid
mask_dim_is          Q/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/_src/lax/qdwh.py_maskr   '   s     
!D			!	!	!	!	$oo A Ada}'	17A>>Bj<ZZdZ.?dl	$; ? ??    c                    dg| j         z  }|||f||<   t          j        | t          j        || j                  |          S )N)r   r   r   )r	   r   padr   arraydtype)r   lowhighinterior
fill_valueaxispadss          r   _pad_in_dimr$   5   sB    
qv	$T8$$t*	CIj!'22D	9	99r   c                    |t          j        | |g|          S t          j        t	          | |j        |         |          |||          S )zIConcatenates padded arrays `a` and `b` where the true size of `a` is `m`.Nr"   )r   r"   )r   concatenater   dynamic_update_slice_in_dimr$   r   )abmr"   s       r   _dynamic_concatr,   :   sV    Y?Aq6----		(!!'$-d333Q4
A 
A Ar   c           	        |\  }}}| j         \  }}t          || z  t          j        |t          j        |                     |          }	t          j        |	d          \  }
}t          t          j	        |
d||f          ||f          }t          j
        |
||d          }t          |||f          j                                        }|| z  |||z  z  z   S )zQDWH iteration using QR decomposition.

  Args:
  u: a matrix, with static (padded) shape M x N.
  m, n: the dynamic shape of the matrix, where m <= M and n <= N.
  params: the QDWH parameters.
  r   F)full_matrices)r   r   r   r&   )r   r,   r   eyer   
lax_linalgqrr   r   slicedynamic_slice_in_dimTconj)ur+   nparamsa_minus_e_by_sqrt_csqrt_ceMNyq_q1q2s                 r   _use_qrrD   B   s     $* vq	
$!Qfqj#'!39Q<<"@"@"@!DD!	q	.	.	.$!QSYq&1a&))Aq622"
1aa000"R!Q!!"	
Q$R0	00r   c                   |\  }}}| j         \  }}|| j                                        | z  z  t          j        |t          j        |                     z   }	t          |	||ft          j        ||	j                            }	t          j        |	d          }
t          j	        |
| j        ddd                                          }t          j	        |
|dddd          j                                        }|| z  ||z  z   S )zQDWH iteration using Cholesky decomposition.

  Args:
  u: a matrix, with static (padded) shape M x N
  m, n: the dynamic shape of the matrix, where m <= M and n <= N.
  params: the QDWH parameters.
  r.   F)symmetrize_inputT)	left_sidelowerconjugate_a)rG   rH   transpose_arI   )
r   r5   r6   r   r0   r   r   r1   choleskytriangular_solve)r7   r+   r8   r9   	a_minus_ecr<   rA   r>   r   r?   zs               r   _use_choleskyrP   W   s	    /)Q	
$!Q1388::>SWQcill;;;;! A1vswq00011! !e444!!Dd< < <<@DFF  !!Q$d.2F F FFG  
QQ	r   c                     |+t          t          j         j                  j                  }t          j                             d          }t          j                             t          j                  }t          j	        |          t          j	        |          z  }t          j
        |dk    d|          } |                     j                  z  }|}	d|z  dz  }
t          j        |
           d }d d	}g }g }d}|	|
z   dk     r|k     r|dz  }|	|	z  }d
d|z  dz
  z  |z  dz  }d|z   dz  }|d|z
  dd|z
  z  ||z  z  z   dz  z   }|dz
  dz  d
z  }||z   dz
  }|	|||z  z   z  d||z  z   z  }	||k    r!|                     ||||                     n |                     |||                     |	|
z   dk     r|k      fd fd} |||t          d          \  }} |||t          d          \  }}fd}fd}t!          |          t!          |          z   }t          j        |||||f          \  }}}d|z  d|z  |j                                        |z  z  z
  }|j                                         z  }||j                                        z   dz  }t          j        |          }||||fS )zGQR-based dynamically weighted Halley iteration for polar decomposition.N   )ordr   g      $@g       @c                0    ||z  }| |z
  }|dz  }||z  ||fS )N      ? )r)   r*   rN   r<   rM   r;   s         r   get_qr_paramsz_qdwh.<locals>.get_qr_params   s/    	AAAI5\F**r   c                     ||z  }| |z
  }|||fS NrV   )r)   r*   rN   r<   rM   s        r   get_chol_paramsz_qdwh.<locals>.get_chol_params   s!    	AAAIq!r   d      gUUUUUU?g      ?rU      c                    |\  }}| 
ddd          }nt          j        || d          }|} |||          }d}	|r&t          j                            ||z
            k    }	||	fS )N   rR   F)keepdimsT)r   dynamic_index_in_dimr   r   norm)kstate	update_fncoefstest_convergencer7   rA   r9   u_previs_not_convergedrZ   r+   r8   tol_norms             r   	iterationz_qdwh.<locals>.iteration   s    DAq}q!Q''ff'q5AAAfF	!Q6""A @V44x?r   c                    |s| dfS t          j        |                              j                  }t	          j        fd|i|}t          j        dt          |          || df          S )NTrf   r   )	r   r   astyper   	functoolspartialr   	fori_loopr
   )r7   rf   kwargsbodyrk   r   s       r   iteratez_qdwh.<locals>.iterate   sp     WnIe##AG,,EY>>e>v>>D=CJJq$i888r   Frf   re   rg   Tc                B    | \  }}}t          j        ||k               S rY   )r   logical_and)rd   rc   rA   ri   max_iterationss       r   cond_funz_qdwh.<locals>.cond_fun   s(    "Aq
?+Q-?@@@r   c                T    | \  }}} |||fd t           d          \  }}|dz   ||fS )NTrt   rR   )rP   )rd   rc   r7   ri   rk   s       r   body_funz_qdwh.<locals>.body_fun   sU    "Aq
#)		
  A q5!%%%r   g      ?)floatr   finfor   epsr   rb   infr   rsqrtr   rm   cbrtappendrD   rP   r
   
while_loopr5   r6   logical_not)!r   r+   r8   rw   r}   one_norminf_normalpha_inverser7   ltol_lrW   CHOLESKY_CUTOFFqr_coefs
chol_coefsrc   l2ddsqdr)   r*   rN   rs   rA   ri   rx   rz   	num_itershis_convergedrZ   rk   rj   s!   ````                          @@@r   _qdwhr   s   s    	[
	!'""&
'
'CZ__QA_&&(Z__QCG_,,()H%%	((;(;;-)HM1m<<--

qw
'
''!	! *s
%Xe__(+ + +  
 /(*!	E	A!n,,FA	
QB
q2vz
R
U	+B8
Cq2vQVS11u==A	
Q1qA	A	A	QRZABJ'A?oommAq!,,----1a00111 	
E	A!n,,       "9 9 9 9 9 9 
x7U
 
 
$!Q  z]T  !A A A A A	& 	& 	& 	& 	& 
(mmc*oo%!#&>1a!12$ $ )Q 
 
Aga1388::>**!chhjj1n!1388::~! !122,	
Ay,	&&r   )is_hermitianrw   r}   )static_argnamesF)r   rw   r}   dynamic_shaper   boolrw   
int | Noner}   float | Noner   tuple[int, int] | Nonec                  t          j        t          |d          }|d}nt          j        t          |d          }| j        \  }}||k     rt          d          ||\  }}t          | ||f          } n||}}t          j        d          5  t          | ||||          \  }	}
}}ddd           n# 1 swxY w Y   |	|
||fS )a  QR-based dynamically weighted Halley iteration for polar decomposition.

  Args:
    x: A full-rank matrix, with shape `M x N`. The matrix may be padded up to
      that size from a smaller true shape (``dynamic_shape``).
    is_hermitian: True if `x` is Hermitian. Default to `False`. This parameter
      is currently unused, but exists for backward compatibility.
    eps: The final result will satisfy ``|x_k - x_k-1| < |x_k| *
      (4*eps)**(1/3)`` where `x_k` is the iterate.
    max_iterations: Iterations will terminate after this many steps even if the
      above is unsatisfied.
    dynamic_shape: the unpadded shape as an ``(m, n)`` tuple; optional.

  Returns:
    A four-tuple of (u, h, num_iters, is_converged) containing the
    polar decomposition of `x = u * h`, the number of iterations to compute `u`,
    and `is_converged`, whose value is `True` when the convergence is achieved
    within the maximum number of iterations.
  zbThe `is_hermitian` argument must be statically specified to use `qdwh` within JAX transformations.N
   zdThe `max_iterations` argument must be statically specified to use `qdwh` within JAX transformations.z1The input matrix of shape M x N must have M >= N.float32)
r   concrete_or_errorr   intr   
ValueErrorr   jaxdefault_matmul_precisionr   )r   r   rw   r}   r   r=   r>   r+   r8   r7   r   r   r   s                r   qdwhr      sC   > '
L <= =, NN+^ >? ?N 
$!QUU
H
I
IIDAqa!QAAaqA
#I.. H H$)!Q>3$G$G!Aq)\H H H H H H H H H H H H H H H 
Ay,	&&s   B22B69B6)r   )r   r   r   r   r   )r   r   rw   r   r}   r   r   r   )__doc__
__future__r   rn   r   	jax.numpynumpyr   r   jax._srcr   jax._src.laxr   r1   r   r$   r,   rD   rP   r   ro   jitr   rV   r   r   <module>r      sV  
 
 # " " " " "     



                   - - - - - -@ @ @ @: : : :
A A A A1 1 1*  8p' p' p'h GF   !%,03' 3' 3' 3' 3' 3' 3' 3'r   