
    VpfZ                       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
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ZddlmZmZ 	 	 d5d6dZ ej        ej        ddg          	 d7d8d            Z ej        ej        g d          	 d7d9d            Zd Zej        j         j!        fdZ"d  Z#d! Z$d" Z%d# Z&d$ Z'd% Z(d& Z)d' Z*d( Z+d) Z,d* Z-d+ Z.d, Z/d- Z0 ej1        d.          Z2e23                     ej        ej4        e2                     e25                    e*            ej6        e2e-dde.           e0ej7        e2<    ej8        e2e+d/0            ej8        e2e,d10           d:d4Z9dS );zSparse linear algebra routines.    )annotations)CallableN)sparse)mlir)xla)core)ad)
gpu_solver)
csr_matrixlinalgd   A,jax.Array | Callable[[jax.Array], jax.Array]X	jax.Arrayminttoljax.Array | float | Nonec                    t          | t          j        t          j        f          rt          | |||d          S t          | |||d          S )a  Compute the top-k standard eigenvalues using the LOBPCG routine.

  LOBPCG [1] stands for Locally Optimal Block Preconditioned Conjugate Gradient.
  The method enables finding top-k eigenvectors in an accelerator-friendly
  manner.

  This initial experimental version has several caveats.

    - Only the standard eigenvalue problem `A U = lambda U` is supported,
      general eigenvalues are not.
    - Gradient code is not available.
    - f64 will only work where jnp.linalg.eigh is supported for that type.
    - Finding the smallest eigenvectors is not yet supported. As a result,
      we don't yet support preconditioning, which is mostly needed for this
      case.

  The implementation is based on [2] and [3]; however, we deviate from these
  sources in several ways to improve robustness or facilitate implementation:

    - Despite increased iteration cost, we always maintain an orthonormal basis
      for the block search directions.
    - We change the convergence criterion; see the `tol` argument.
    - Soft locking [4] is intentionally not implemented; it relies on
      choosing an appropriate problem-specific tolerance to prevent
      blow-up near convergence from catastrophic cancellation of
      near-0 residuals. Instead, the approach implemented favors
      truncating the iteration basis.

  [1]: http://ccm.ucdenver.edu/reports/rep149.pdf
  [2]: https://arxiv.org/abs/1704.07458
  [3]: https://arxiv.org/abs/0705.2626
  [4]: DOI 10.13140/RG.2.2.11794.48327

  Args:
    A : An `(n, n)` array representing a square Hermitian matrix or a
        callable with its action.
    X : An `(n, k)` array representing the initial search directions for the `k`
        desired top eigenvectors. This need not be orthogonal, but must be
        numerically linearly independent (`X` will be orthonormalized).
        Note that we must have `0 < k * 5 < n`.
    m : Maximum integer iteration count; LOBPCG will only ever explore (a
        subspace of) the Krylov basis `{X, A X, A^2 X, ..., A^m X}`.
    tol : A float convergence tolerance; an eigenpair `(lambda, v)` is converged
          when its residual L2 norm `r = |A v - lambda v|` is below
          `tol * 10 * n * (lambda + |A v|)`, which
          roughly estimates the worst-case floating point error for an ideal
          eigenvector. If all `k` eigenvectors satisfy the tolerance
          comparison, then LOBPCG exits early. If left as None, then this is set
          to the float epsilon of `A.dtype`.

  Returns:
    `theta, U, i`, where `theta` is a `(k,)` array
    of eigenvalues, `U` is a `(n, k)` array of eigenvectors, `i` is the
    number of iterations performed.

  Raises:
    ValueError : if `A,X` dtypes or `n` dimensions do not match, or `k` is too
                 large (only `k * 5 < n` supported), or `k == 0`.
  F)debug)
isinstancejaxArraynpndarray_lobpcg_standard_matrix_lobpcg_standard_callable)r   r   r   r   s       ^/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/experimental/sparse/linalg.pylobpcg_standardr    %   sR    B CIrz*++ >"1aCu====	"1aCu	=	=	==    r   )static_argnamesFboolc                X    t          t          j        t          |           ||||          S )z<Computes lobpcg_standard(), possibly with debug diagnostics.)r   	functoolspartial_mm)r   r   r   r   r   s        r   r   r   j   s.     
#QAsE
3 
3 3r!   )r   r   r    Callable[[jax.Array], jax.Array]c                V    |j         \  |j        }t           |           t          j        |          j        t          |          }t          ||j         d                   }  |          }t          j        ||z  dd          }|||z  z
  }	fd}
 fdd}d|||	||f}r*t          j
                            fd|d	          \  }}n!t          j
                            |
|          }|\  }}}}}}r|dddf         |||fS |dddf         ||fS )
z6Supports generic lobpcg_standard() callable interface.N   r   T)axiskeepdimsc                P    | \  }}}}}}t          j        |k     |k               S N)jnplogical_and)	statei_X_P_R	converged_kr   s	          r   condz'_lobpcg_standard_callable.<locals>.cond   s/    "'Ar2r9a?1q5)a-000r!   c           
        | \  }}}}}}t          t          j        ||fd          |          }t          j        |||fd          }t          |          \  }}|d d d f         }	t          j                            |	ddd          }
|	|
z  }	t          ||	          }t          j                            |ddd          }||z  }t          j                            |d d f         j                  \  }}t          |d d d f         |          }t          ||          }t          j                            |ddd          }|t          j	        |dk    d|          z  } |          }||t          j
        d f         |z  z
  }t          j                            |dd          }t          j                            |dd          |d          z   }|z  }|d	z  }||z  k     }t          j        |          }|dz   |||||t          j
        d f         f}rt          ||||||||z            }||f}|S )
Nr*   r+      r   Tordr+   r,         ?)r>   r+   
   )_project_outr/   concatenate_rayleigh_ritz_orthr   normr'   qrTwherenewaxissum_generate_diagnostics)r1   r2   r   PRr7   thetaXPRQBnormBnormXqdiff_rayleigh_orthonormPAXresid_normsreltolres_convergedr6   	new_statediagnosticsr   r   r8   nr   s                         r   bodyz'_lobpcg_standard_callable.<locals>.body   se    Aq!Q5 	S_aV!444a88A
/1a)!
,
,
,C #1c**HE1 	
!!!RaR%AJOOA11tO<<EJACAJOOA11tO<<EJA :==2A2qrr6%%DAqa122h**C$%%AJOOA11tO<<E5A:sE	*	**A 
1B
U3;?#a''A*//!/33K$ Z__RQQ_//%);F
aKF
bLF#,.M&&IAq!Q	5bqb+AAI +)
q!Qy+*>@ @kk*ir!   c                     |           S r.    )r1   r7   r]   s     r   <lambda>z+_lobpcg_standard_callable.<locals>.<lambda>   s    e r!   )xslength)shapedtype_check_inputsr/   finfoeps_orthonormalize_extend_basisrI   r   laxscan
while_loop)r   r   r   r   r   dtrK   rV   rM   rL   r9   r6   r1   r[   r2   r4   r5   
_convergedr]   r8   r\   s   ` ```             @@@r   r   r   u   s    
$!Qw"1[
)B--
Ca!Aqwqz""! 	qtt"
'!b&q4
0
0
0%519n!1 1 1 1 1 1M M M M M M M M M^ )aAy%
(%
 2$$$$eQ & @ @E;; GtT511E$)!!QB
E
 *AAA;1k))	q!!!ta	r!   c                   |j         \  }}|j        }|dk    rt          d|           |dz  |k    rt          d|dz   d| d           | t          j        |df|j                            }|j        |k    rt          d	|j         d| d          |j         |dfk    r|j         }t          d
| d| d|           d S )Nr   zmust have search dim > 0, got    z*expected search dim * 5 < matrix dim (got z, )r*   rd   z!A, X must have same dtypes (were zA must be (z) matrix A, got output )rc   rd   
ValueErrorr/   zeros)r   r   r\   r8   rm   test_outputss          r   re   re      s   	
$!Qw"!VV
9a99
:
::UaZZ
O!a%OO1OOO
P
PP#)QF!'22233+"
FK,=FFFFFH H H 1a&  A
E1EEEE!EE
F
FF ! r!   c                H    t           j                            | |||f          S r.   )r   rj   dot)ab	precisions      r   r'   r'   
  s    	QIy1	2	22r!   c                &   |j         d         |j         |j         k    sJ d }fd}t          |j        |          }	 ||	          }
 ||	|
z
            }t          |j        |          } ||          } |||z
            } ||j        |z            }| j         d         t          j        t          j        | dk    d                    z
  }|t          j        t          j        |dk    d                    t          j        t          j        |dk    d                    |d          t          j                            |dd          |t          j        |          t          j	        |          t          j
        |          |||d	S )
Nr*   c                N    t          j        t          j        |                     S r.   )r/   diag)xs    r   r`   z'_generate_diagnostics.<locals>.<lambda>  s    sx,, r!   c                \    t          j        |                                           dz  z  S Nr<   )r/   absrI   )r   r8   s    r   r`   z'_generate_diagnostics.<locals>.<lambda>  s"    SWQZZ^^%%a0 r!           r   r;   r<   )r+   r>   )z
basis rankzX zeroszP zeroszlambda historyzresidual historyr6   zadjusted residual maxzadjusted residual p50zadjusted residual minzX orthzP orthzP.X)rc   r'   rF   r/   rI   allr   rD   maxmedianmin)prev_XPRr   rK   rL   rM   r6   	adj_residdiagdiagabserrXTXDXorthXPTPDPorthPPX
prev_basisr8   s                    @r   rJ   rJ     s   gaj!	
AG				,,(0000&AC#x}}"
&r

%AC#x}}"
&r

%vacAg"~a 37378s?+K+K+K#L#LL* c22233c22233bqb	*//!!/;;"wy11"z)44"wy11
 
 r!   c                z    t           j                            |           \  }}|d d d         |d d d d df         fS )N)r/   r   eigh)r   wVs      r   _eigh_ascendingr   .  s@    			$!Q	
44R4!AAAtttG*	r!   c                   t           j                            | ddd          }| t          j        |dk    d|          z  } t	          | j        |           }t          |          \  }}t          j        | j                  j	        |d         z  }t          j
        ||          }t          j        |dk    |d          dz  }||t           j        ddf         z  }t	          | |          }	||k    t          j        |          dk    z  t           j        ddf         }
|	|
                    |	j                  z  }	t           j                            |	ddd          }|
|dk    z  }
|	t          j        |
|d          z  }	|	S )	aA  Derives a truncated orthonormal basis for `X`.

  SVQB [1] is an accelerator-friendly orthonormalization procedure, which
  squares the matrix `C = X.T @ X` and computes an eigenbasis for a smaller
  `(k, k)` system; this offloads most of the work in orthonormalization
  to the first multiply when `n` is large.

  Importantly, if diagonalizing the squared matrix `C` reveals rank deficiency
  of X (which would be evidenced by near-0 then), eigenvalues corresponding
  columns are zeroed out.

  [1]: https://sdm.lbl.gov/~kewu/ps/45577.html

  Args:
    X : An `(n, k)` array which describes a linear subspace of R^n, possibly
        numerically degenerate with some rank less than `k`.

  Returns:
    An orthonormal space `V` described by a `(n, k)` array, with trailing
    columns possibly zeroed out if `X` is of low rank.
  r<   r   Tr=   r?         Nr   )r/   r   rD   rG   r'   rF   r   rf   rd   rg   maximumrH   r~   astype)r   normsinnerr   r   taupaddedsqrtedscaledVorthoXkeeps              r   _svqbr   3  sY   4 *//!T/
:
:%sy!S%(((!
ac1++%			$!Q 		!'1%#;q#& 9S1Wfc**t4& s{AAA~&&'q'??&s7sx,
-s{AAA~	>$DKK%%%&
*//&aa$/
?
?%%#+$CIdE3'''&	-r!   c           	        t          d          D ]7}|t          | t          | j        |                    z  }t          |          }8t          d          D ](}|t          | t          | j        |                    z  })t          j                            |ddd          }||dk                        |j                  z  }|S )a  Derives component of U in the orthogonal complement of basis.

  This method iteratively subtracts out the basis component and orthonormalizes
  the remainder. To an extent, these two operations can oppose each other
  when the remainder norm is near-zero (since normalization enlarges a vector
  which may possibly lie in the subspace `basis` to be subtracted).

  We make sure to prioritize orthogonality between `basis` and `U`, favoring
  to return a lower-rank space thank `rank(U)`, in this tradeoff.

  Args:
    basis : An `(n, m)` array which describes a linear subspace of R^n, this
        is assumed to be orthonormal but zero columns are allowed.
    U : An `(n, k)` array representing another subspace of R^n, whose `basis`
        component is to be projected out.

  Returns:
    An `(n, k)` array, with some columns possibly zeroed out, representing
    the component of `U` in the complement of `basis`. The nonzero columns
    are mutually orthonormal.
  r<   r   Tr=   gGz?)	ranger'   rF   rh   r/   r   rD   r   rd   )basisUr7   normUs       r   rA   rA   l  s    L 88  aUCOO	$	$$AAA 88 % %aUCOO	$	$$AA
*//!T/
:
:%ag&&&!	
(r!   c                H    t          d          D ]}t          |           } | S r   )r   r   )r   r7   s     r   rh   rh     s)    88  a%LLEE	,r!   c                \    t          |j         | |                    }t          |          S )a  Solve the Rayleigh-Ritz problem for `A` projected to `S`.

  Solves the local eigenproblem for `A` within the subspace `S`, which is
  assumed to be orthonormal (with zero columns allowed), identifying `w, V`
  satisfying

  (1) `S.T A S V ~= diag(w) V`
  (2) `V` is standard orthonormal

  Note that (2) is simplified to be standard orthonormal because `S` is.

  Args:
    A: An operator representing the action of an `n`-sized square matrix.
    S: An orthonormal subspace of R^n represented by an `(n, k)` array, with
       zero columns allowed.

  Returns:
    Eigenvectors `V` and eigenvalues `w` satisfying the size-`k` system
    described in this method doc. Note `V` will be full rank, even if `S` isn't.
  )r'   rF   r   )r   SSASs      r   rC   rC     s+    , 	AC1# 
		r!   c                   | j         \  }}t          j        | |gd          \  }}t          j                            |          \  }}}t          j        |t          ||          z   |gd          }	t          j        t          j        || j                  t          j	        ||z
  |z
  |f| j                  gd          }
t          |	|j
        dd|z   z  dz  t          j        ddf         z            }dt          j                            |||dddf         j
        |
gt          j        j        j        	          z  }|j        |d                             |
          S )
a  Extend the basis of `X` with `m` addition dimensions.

  Given an orthonormal `X` of dimension `k`, a typical strategy for deriving
  an extended basis is to generate a random one and project it out.

  We instead generate a basis using block householder reflectors [1] [2] to
  leverage the favorable properties of determinism and avoiding the chance that
  the generated random basis has overlap with the starting basis, which may
  happen with non-negligible probability in low-dimensional cases.

  [1]: https://epubs.siam.org/doi/abs/10.1137/0725014
  [2]: https://www.jstage.jst.go.jp/article/ipsjdc/2/0/2_0_298/_article

  Args:
    X : An `(n, k)` array representing a `k`-rank orthonormal basis for a linear
        subspace of R^n.
    m : A nonnegative integer such that `k + m <= n` telling us how much to
        extend the basis by.

  Returns:
    An `(n, m)` array representing an extension to the basis of `X` such that
    their union is orthonormal.
  r   r;   rr   r<   r*   r   N)r{   )rc   r/   splitr   svdrB   r'   eyerd   rt   rF   rH   	multi_dotr   rj   	PrecisionHIGHESTatadd)r   r   r\   r8   XupperXlowerurv   vtyotherr   hs                r   ri   ri     s\   0 
$!Q9Q!,,,.&&Z^^F##(!Q
 
ovAr

*F3!<<<!  /
wq   
y!a%!)Qqw///178: : :% 
!RTa1q5kt,ck111n==>>!3:!ABBE(*e(9(A   C C C!	
abbe		r!   c          
        | j         |j         k    rt          d| j         d|j                   t          j        |j         t          j                  r$t          j        |j         t          j                  st          d|j         d|j                   | j        |j        cxk    r|j        cxk    r|j        cxk    rdk    s1n t          d| j        d|j        d|j        d	|j                  |j        |j        dz   k    s| j        |j        k    r't          d
| j        d|j        d|j                  |dvrt          d|d          t          |          }|S )Nz$data types do not match: data.dtype=z	 b.dtype=z6index arrays must be integer typed; got indices.dtype=z indptr.dtype=r*   z/Arrays must be one-dimensional. Got data.shape=z indices.shape=z indptr.shape=z	 b.shape=z%Invalid CSR buffer sizes: data.shape=)r   r*   r<      zreorder=z' not valid, must be one of [1, 2, 3, 4])	rd   rs   r/   
issubdtypeintegerndimrc   sizefloatdataindicesindptrrz   r   reorders         r   _spsolve_abstract_evalr     s   	Z17
IIIqwII
J
JJ
.
4
4 bVYVa9b9b b
```QWQ]``
a
aa	gl	@	@	@	@fk	@	@	@	@QV	@	@	@	@q	@	@	@	@
 V JV V*1-V V;A<V VKL7V V W W W[AFQJ4:#>#>
`$*````QWQ]``
a
aaL  
IIII
J
JJc

#	
(r!   c          	     X    | j         \  }}}}t          j        |j        ||||||          S r.   )avals_inr
   cuda_csrlsvqrrd   )	ctxr   r   r   rz   r   r   	data_avalr7   s	            r   _spsolve_gpu_loweringr     s8    )Q1		!)/4"(!S'
; 
; ;r!   c           	     n    ~~||||g}d }t          j        | |d || j        | j        d          \  }	}
}
|	S )Nc                    t          | ||f|j        |j        f          }t          j        ||                              |j                  fS )N)rc   )r   r   r   spsolver   rd   )r   r   r   rz   kwargsr   s         r   	_callbackz(_spsolve_cpu_lowering.<locals>._callback!  sI    D'6*16162BCCCAN1a  ''0022r!   F)has_side_effect)r   emit_python_callbackr   	avals_out)r   r   r   r   rz   r   r   argsr   resultr7   s              r   _spsolve_cpu_loweringr     s^    	7
	#$3 3 3 *	9dD#,  ,&!Q 
-r!   c           
         t          ||||fi |}t          j                            | ||||j        dz
  t          |          fd          }t          ||||fi | S )Nr*   F)rc   	transpose)r   r   csr_matvec_pbindr   len)data_dotr   r   r   rz   kwdsprS   s           r   _spsolve_jvp_lhsr   +  sz    gvq11D11A  7FA(.aQ'@+0 	! 	2 	2A D'61555555r!   c                "    t          |||| fi |S r.   )r   )b_dotr   r   r   rz   r   s         r   _spsolve_jvp_rhsr   4  s    4&%884888r!   c                   |j         dz
  }t          j        t          j        |          j        |                             d                    dz
  }t          j                            ||| fd          \  }}}t          j        |          j        dd          	                    t          j        t          j
        ||                                        |j                            }|||fS )Nr*   r<   )num_keys)rb   )r   r/   cumsum
zeros_liker   r   r   rj   sortsetbincountr   rd   )	r   r   r   r   rowrow_T	indices_Tdata_Tindptr_Ts	            r   _csr_transposer   9  s    kAo!
3>'**-f599!<<==A# W\\7C*>\KK%F^F##&qrr*..	jeA...//66v|DDF F(	H	$$r!   c                    t          j        |          rJ t          j        |          rJ t          j        |          r+t          |||          \  }}}t          |||| fi |}	||||	fS t	          d          )Nz&spsolve transpose with respect to data)r	   is_undefined_primalr   r   NotImplementedError)
ctr   r   r   rz   r   r   r   r   ct_outs
             r   _spsolve_transposer   C  s    #G,,,,,#F+++++A H"0w"G"GFIxVY"====F&&(( F
G
GGr!   r   cuda)platformcpuư>r*   c                B    t                               | |||||          S )a   A sparse direct solver using QR factorization.

  Accepts a sparse matrix in CSR format `data, indices, indptr` arrays.
  Currently only the CUDA GPU backend is implemented.

  Args:
    data : An array containing the non-zero entries of the CSR matrix.
    indices : The column indices of the CSR matrix.
    indptr : The row pointer array of the CSR matrix.
    b : The right hand side of the linear system.
    tol : Tolerance to decide if singular or not. Defaults to 1e-6.
    reorder : The reordering scheme to use to reduce fill-in. No reordering if
      ``reorder=0``. Otherwise, symrcm, symamd, or csrmetisnd (``reorder=1,2,3``),
      respectively. Defaults to symrcm.

  Returns:
    An array with the same dtype and size as b representing the solution to
    the sparse linear system.
  )r   r   )	spsolve_pr   r   s         r   r   r   Y  s"    ( 
gvqc7	K	KKr!   )r   N)r   r   r   r   r   r   r   r   )F)
r   r   r   r   r   r   r   r   r   r#   )
r   r(   r   r   r   r   r   r   r   r#   )r  r*   ):__doc__
__future__r   collections.abcr   r%   r   	jax.numpynumpyr/   jax.experimentalr   jax.interpretersr   r   jax._srcr   jax._src.interpretersr	   jax._src.libr
   r   scipy.sparser   r   r    r&   jitr   r   re   rj   r   r   r'   rJ   r   r   rA   rh   rC   ri   r   r   r   r   r   r   r   	Primitiver  def_implapply_primitivedef_abstract_evaldefjvpprimitive_transposesregister_loweringr   r_   r!   r   <module>r     s}   & % " " " " " " $ $ $ $ $ $     



       # # # # # # ! ! ! ! ! !                   $ $ $ $ $ $ # # # # # #     + + + + + + + + $(	C> C> C> C> C>J 37S'N;;; 3 3 3 3 <;3 37,?,?,?@@@ | | | | A@|~G G G* )1 3 3 3 3  B  
6 6 6r; ; ;z    :6 6 6t   ; ; ;  6 6 69 9 9
% % %
H 
H 
H DN9%%	 	  $9$S%8)DD E E E 	  2 3 3 3 		)%tT3C D D D%7 	 "  y"7& I I I I  y"7% H H H HL L L L L Lr!   