
    Vpf$             	      
   d dl mZ d dlmZ d dlZd dlZd dlmZm	Z	m
Z
 d dlZd dlmZ d dlmZmZ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mZmZmZ d dlmZmZ  ej         d          Z!e!dz   Z" eed          dd            Z#	 	 dddZ$	 	 dddZ% eed          dd             Z&	 ddd$Z'edd*            Z(edd,            Z(edd.            Z( eed/          dd0            Z(e	 	 	 ddd4            Z)e	 	 ddd5            Z)edddd1d6dd7            Z)e	 	 	 ddd8            Z)	 	 	 ddd9Z)ddd:Z*eddA            Z+eddC            Z+eddE            Z+ eedF          ddG            Z+e	 	 	 	 dddJ            Z,eddddddHddKddL            Z,e	 	 	 dddM            Z,e	 	 	 	 dddN            Z,	 	 	 	 dddOZ, eedP          ddR            Z-dddTZ.dddUZ/ eedV          dddW            Z0 eedX          	 	 ddd\            Z1edd^            Z2edd_            Z2edda            Z2 eedbc          ddd            Z2e	 	 ddde            Z3e	 	 dddf            Z3e	 	 dddg            Z3 eedh          	 	 dddi            Z3eddn            Z4eddp            Z4eddr            Z4 eeds          ddt            Z4e	 	 dddx            Z5e	 dddy            Z5eddddzdd{            Z5e	 	 ddd|            Z5	 	 ddd}Z5 eed~          d d            Z6	 	 	 dddZ7 eed          dd            Z8	 	 	 dddZ9 eed          ddddd            Z:edd            Z;dd	dZ<d
dZ= eedc          dd            Z>ddZ?ddZ@ddZAddZBddZCeddddd            ZDedddd            ZDeddddd            ZD eed          ddddd            ZDedd            ZE eed          ddddddd            ZF eed           ejG        d          ddddddd                        ZHedd            ZIedd            ZJdbddZK eedì          dddń            ZLedddVddǄ            ZMedddVddȄ            ZM eedɬ          ddddʜdd˄            ZMddd̈́ZN eedά          ddЄ            ZOdS (      )annotations)partialN)overloadAnyLiteral)jitvmapjvp)lax)dtypes)linalg)qdwh)check_arraylikepromote_dtypespromote_dtypes_inexactpromote_dtypes_complex)Array	ArrayLikez
Does not support the Scipy argument ``check_finite=True``,
because compiled JAX code cannot perform checks of array values at runtime.
z:
Does not support the Scipy argument ``overwrite_*=True``.lower)static_argnamesar   r   boolreturnr   c                    t          t          j        |                     \  } t          j        |r| nt          j        | j                  d          }|r|nt          j        |j                  S )NF)symmetrize_input)r   jnpasarray
lax_linalgcholeskyconjmT)r   r   ls      U/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/_src/scipy/linalg.py	_choleskyr%   *   sZ    ck!nn--"!u8!!#(14..5QQQ!	'!$'    FToverwrite_acheck_finitec                &    ~~t          | |          S )a  Compute the Cholesky decomposition of a matrix.

  JAX implementation of :func:`scipy.linalg.cholesky`.

  The Cholesky decomposition of a matrix `A` is:

  .. math::

     A = U^HU = LL^H

  where `U` is an upper-triangular matrix and `L` is a lower-triangular matrix.

  Args:
    a: input array, representing a (batched) positive-definite hermitian matrix.
      Must have shape ``(..., N, N)``.
    lower: if True, compute the lower Cholesky decomposition `L`. if False
      (default), compute the upper Cholesky decomposition `U`.
    overwrite_a: unused by JAX
    check_finite: unused by JAX

  Returns:
    array of shape ``(..., N, N)`` representing the cholesky decomposition
    of the input.

  See Also:
   - :func:`jax.numpy.linalg.cholesky`: NumPy-stype Cholesky API
   - :func:`jax.lax.linalg.cholesky`: XLA-style Cholesky API
   - :func:`jax.scipy.linalg.cho_factor`
   - :func:`jax.scipy.linalg.cho_solve`

  Examples:
    A small real Hermitian positive-definite matrix:

    >>> x = jnp.array([[2., 1.],
    ...                [1., 2.]])

    Upper Cholesky factorization:

    >>> jax.scipy.linalg.cholesky(x)
    Array([[1.4142135 , 0.70710677],
           [0.        , 1.2247449 ]], dtype=float32)

    Lower Cholesky factorization:

    >>> jax.scipy.linalg.cholesky(x, lower=True)
    Array([[1.4142135 , 0.        ],
           [0.70710677, 1.2247449 ]], dtype=float32)

    Reconstructing ``x`` from its factorization:

    >>> L = jax.scipy.linalg.cholesky(x, lower=True)
    >>> jnp.allclose(x, L @ L.T)
    Array(True, dtype=bool)
  )r%   r   r   r'   r(   s       r$   r    r    1   s    p <	1e		r&   tuple[Array, bool]c                ,    ~~t          | |          |fS )a  Factorization for Cholesky-based linear solves

  JAX implementation of :func:`scipy.linalg.cho_factor`. This function returns
  a result suitable for use with :func:`jax.scipy.linalg.cho_solve`. For direct
  Cholesky decompositions, prefer :func:`jax.scipy.linalg.cholesky`.

  Args:
    a: input array, representing a (batched) positive-definite hermitian matrix.
      Must have shape ``(..., N, N)``.
    lower: if True, compute the lower triangular Cholesky decomposition (default: False).
    overwrite_a: unused by JAX
    check_finite: unused by JAX

  Returns:
    ``(c, lower)``: ``c`` is an array of shape ``(..., N, N)`` representing the lower or
    upper cholesky decomposition of the input; ``lower`` is a boolean specifying whether
    this is the lower or upper decomposition.

  See Also:
    - :func:`jax.scipy.linalg.cholesky`
    - :func:`jax.scipy.linalg.cho_solve`

  Examples:
    A small real Hermitian positive-definite matrix:

    >>> x = jnp.array([[2., 1.],
    ...                [1., 2.]])

    Compute the cholesky factorization via :func:`~jax.scipy.linalg.cho_factor`,
    and use it to solve a linear equation via :func:`~jax.scipy.linalg.cho_solve`.

    >>> b = jnp.array([3., 4.])
    >>> cfac = jax.scipy.linalg.cho_factor(x)
    >>> y = jax.scipy.linalg.cho_solve(cfac, b)
    >>> y
    Array([0.6666666, 1.6666666], dtype=float32)

    Check that the result is consistent:

    >>> jnp.allclose(x @ y, b)
    Array(True, dtype=bool)
  r   )r    r*   s       r$   
cho_factorr-   m   s"    X <
1E
"
"
"E	**r&   cbc                
   t          t          j        |           t          j        |                    \  } }t          j        | |           t          j        | |d|| |           }t          j        | |d|||          }|S )NT)	left_sider   transpose_aconjugate_a)r   r   r   r   _check_solve_shapestriangular_solve)r.   r/   r   s      r$   
_cho_solver6      s    	AA	?	?$!Q A&&&!!Q$e27iYP P P!!!Q$e.3H H H!	
(r&   c_and_lowertuple[ArrayLike, bool]overwrite_bc                2    ~~| \  }}t          |||          S )a:  Solve a linear system using a Cholesky factorization

  JAX implementation of :func:`scipy.linalg.cho_solve`. Uses the output
  of :func:`jax.scipy.linalg.cho_factor`.

  Args:
    c_and_lower: ``(c, lower)``, where ``c`` is an array of shape ``(..., N, N)``
      representing the lower or upper cholesky decomposition of the matrix, and
      ``lower`` is a boolean specifying whether this is the lower or upper decomposition.
    b: right-hand-side of linear system. Must have shape ``(..., N)``
    overwrite_a: unused by JAX
    check_finite: unused by JAX

  Returns:
    Array of shape ``(..., N)`` representing the solution of the linear system.

  See Also:
    - :func:`jax.scipy.linalg.cholesky`
    - :func:`jax.scipy.linalg.cho_factor`

  Examples:
    A small real Hermitian positive-definite matrix:

    >>> x = jnp.array([[2., 1.],
    ...                [1., 2.]])

    Compute the cholesky factorization via :func:`~jax.scipy.linalg.cho_factor`,
    and use it to solve a linear equation via :func:`~jax.scipy.linalg.cho_solve`.

    >>> b = jnp.array([3., 4.])
    >>> cfac = jax.scipy.linalg.cho_factor(x)
    >>> y = jax.scipy.linalg.cho_solve(cfac, b)
    >>> y
    Array([0.6666666, 1.6666666], dtype=float32)

    Check that the result is consistent:

    >>> jnp.allclose(x @ y, b)
    Array(True, dtype=bool)
  )r6   )r7   r/   r9   r(   r.   r   s         r$   	cho_solver;      s%    T <(!U	Aq%	 	  r&   xfull_matrices
compute_uvLiteral[True]tuple[Array, Array, Array]c                   d S N r<   r=   r>   s      r$   _svdrE      s    ililr&   Literal[False]c                   d S rB   rC   rD   s      r$   rE   rE      s    UXUXr&   "Array | tuple[Array, Array, Array]c                   d S rB   rC   rD   s      r$   rE   rE      s    hkhkr&   r=   r>   c               v    t          t          j        |                     \  } t          j        | ||          S )NrJ   )r   r   r   r   svd)r   r=   r>   s      r$   rE   rE      s0    ck!nn--"!	:	N	N	NNr&   gesddlapack_driverstrc                    d S rB   rC   r   r=   r>   r'   r(   rN   s         r$   rL   rL      s     FISr&   c                    d S rB   rC   rQ   s         r$   rL   rL      	     14r&   )r'   r(   rN   c                   d S rB   rC   rQ   s         r$   rL   rL      rS   r&   c                    d S rB   rC   rQ   s         r$   rL   rL      s     NQSr&   c                ,    ~~~t          | ||          S )a	  Compute the singular value decomposition.

  JAX implementation of :func:`scipy.linalg.svd`.

  The SVD of a matrix `A` is given by

  .. math::

     A = U\Sigma V^H

  - :math:`U` contains the left singular vectors and satisfies :math:`U^HU=I`
  - :math:`V` contains the right singular vectors and satisfies :math:`V^HV=I`
  - :math:`\Sigma` is a diagonal matrix of singular values.

  Args:
    a: input array, of shape ``(..., N, M)``
    full_matrices: if True (default) compute the full matrices; i.e. ``u`` and ``vh`` have
      shape ``(..., N, N)`` and ``(..., M, M)``. If False, then the shapes are
      ``(..., N, K)`` and ``(..., K, M)`` with ``K = min(N, M)``.
    compute_uv: if True (default), return the full SVD ``(u, s, vh)``. If False then return
      only the singular values ``s``.
    overwrite_a: unused by JAX
    check_finite: unused by JAX
    lapack_driver: unused by JAX

  Returns:
    A tuple of arrays ``(u, s, vh)`` if ``compute_uv`` is True, otherwise the array ``s``.

    - ``u``: left singular vectors of shape ``(..., N, N)`` if ``full_matrices`` is True
      or ``(..., N, K)`` otherwise.
    - ``s``: singular values of shape ``(..., K)``
    - ``vh``: conjugate-transposed right singular vectors of shape ``(..., M, M)``
      if ``full_matrices`` is True or ``(..., K, M)`` otherwise.

    where ``K = min(N, M)``.

  See also:
    - :func:`jax.numpy.linalg.svd`: NumPy-style SVD API
    - :func:`jax.lax.linalg.svd`: XLA-style SVD API

  Examples:
    Consider the SVD of a small real-valued array:

    >>> x = jnp.array([[1., 2., 3.],
    ...                [6., 5., 4.]])
    >>> u, s, vt = jax.scipy.linalg.svd(x, full_matrices=False)
    >>> s  # doctest: +SKIP
    Array([9.361919 , 1.8315067], dtype=float32)

    The singular vectors are in the columns of ``u`` and ``v = vt.T``. These vectors are
    orthonormal, which can be demonstrated by comparing the matrix product with the
    identity matrix:

    >>> jnp.allclose(u.T @ u, jnp.eye(2), atol=1E-5)
    Array(True, dtype=bool)
    >>> v = vt.T
    >>> jnp.allclose(v.T @ v, jnp.eye(2), atol=1E-5)
    Array(True, dtype=bool)

    Given the SVD, ``x`` can be reconstructed via matrix multiplication:

    >>> x_reconstructed = u @ jnp.diag(s) @ vt
    >>> jnp.allclose(x_reconstructed, x)
    Array(True, dtype=bool)
  rJ   )rE   rQ   s         r$   rL   rL      s!    H <	a}	D	D	DDr&   c                D    ~~t           j                            |           S )a  Compute the determinant of a matrix

  JAX implementation of :func:`scipy.linalg.det`.

  Args:
    a: input array, of shape ``(..., N, N)``
    overwrite_a: unused by JAX
    check_finite: unused by JAX

  Returns
    Determinant of shape ``a.shape[:-2]``

  See Also:
    :func:`jax.numpy.linalg.det`: NumPy-style determinant API

  Examples:
    Determinant of a small 2D array:

    >>> x = jnp.array([[1., 2.],
    ...                [3., 4.]])
    >>> jax.scipy.linalg.det(x)
    Array(-2., dtype=float32)

    Batch-wise determinant of multiple 2D arrays:

    >>> x = jnp.array([[[1., 2.],
    ...                 [3., 4.]],
    ...                [[8., 5.],
    ...                 [7., 9.]]])
    >>> jax.scipy.linalg.det(x)
    Array([-2., 37.], dtype=float32)
  )r   r   detr   r'   r(   s      r$   rX   rX   @  s    B <			r&   ArrayLike | Noneeigvals_onlyeigvalsNonetypeintc                    d S rB   rC   r   r/   r   r[   r\   r^   s         r$   _eighrb   e  s    .1cr&   tuple[Array, Array]c                    d S rB   rC   ra   s         r$   rb   rb   i  s    <?Cr&   Array | tuple[Array, Array]c                    d S rB   rC   ra   s         r$   rb   rb   m  s    DGCr&   )r   r[   r\   r^   c                    |t          d          |dk    rt          d          |t          d          t          t          j        |                     \  } t	          j        | |          \  }}|r|S ||fS )Nz+Only the b=None case of eigh is implemented   z,Only the type=1 case of eigh is implemented.z2Only the eigvals=None case of eigh is implemented.r   )NotImplementedErrorr   r   r   r   eigh)r   r/   r   r[   r\   r^   vws           r$   rb   rb   q  s     ]
K
L
LL	QYY
L
M
MM
<> > > ck!nn--"!	%	(	(	($!Q Ha4Kr&   rh   turboc
                    d S rB   rC   
r   r/   r   r[   r'   r9   rm   r\   r^   r(   s
             r$   rj   rj     s     LO3r&   )r'   r9   rm   r\   r^   r(   c                   d S rB   rC   ro   s
             r$   rj   rj     
     >ASr&   c
                    d S rB   rC   ro   s
             r$   rj   rj     rq   r&   c
                    d S rB   rC   ro   s
             r$   rj   rj     s     TWSVr&   c
                2    ~~~~	t          | |||||          S )u  Compute eigenvalues and eigenvectors for a Hermitian matrix

  JAX implementation of :func:`scipy.linalg.eigh`.

  Args:
    a: Hermitian input array of shape ``(..., N, N)``
    b: optional Hermitian input of shape ``(..., N, N)``. If specified, compute
      the generalized eigenvalue problem.
    lower: if True (default) access only the lower portion of the input matrix.
      Otherwise access only the upper portion.
    eigvals_only: If True, compute only the eigenvalues. If False (default) compute
      both eigenvalues and eigenvectors.
    type: if ``b`` is specified, ``type`` gives the type of generalized eigenvalue
      problem to be computed. Denoting ``(λ, v)`` as an eigenvalue, eigenvector pair:

      - ``type = 1`` solves ``a @ v = λ * b @ v`` (default)
      - ``type = 2`` solves ``a @ b @ v = λ * v``
      - ``type = 3`` solves ``b @ a @ v = λ * v``

    eigvals: a ``(low, high)`` tuple specifying which eigenvalues to compute.
    overwrite_a: unused by JAX.
    overwrite_b: unused by JAX.
    turbo: unused by JAX.
    check_finite: unused by JAX.

  Returns:
    A tuple of arrays ``(eigvals, eigvecs)`` if ``eigvals_only`` is False, otherwise
    an array ``eigvals``.

    - ``eigvals``: array of shape ``(..., N)`` containing the eigenvalues.
    - ``eigvecs``: array of shape ``(..., N, N)`` containing the eigenvectors.

  See also:
    - :func:`jax.numpy.linalg.eigh`: NumPy-style eigh API.
    - :func:`jax.lax.linalg.eigh`: XLA-style eigh API.
    - :func:`jax.numpy.linalg.eig`: non-hermitian eigenvalue problem.
    - :func:`jax.scipy.linalg.eigh_tridiagonal`: tri-diagonal eigenvalue problem.

  Examples:
    Compute the standard eigenvalue decomposition of a simple 2x2 matrix:

    >>> a = jnp.array([[2., 1.],
    ...                [1., 2.]])
    >>> eigvals, eigvecs = jax.scipy.linalg.eigh(a)
    >>> eigvals
    Array([1., 3.], dtype=float32)
    >>> eigvecs
    Array([[-0.70710677,  0.70710677],
           [ 0.70710677,  0.70710677]], dtype=float32)

    Eigenvectors are orthonormal:

    >>> jnp.allclose(eigvecs.T @ eigvecs, jnp.eye(2), atol=1E-5)
    Array(True, dtype=bool)

    Solution satisfies the eigenvalue problem:

    >>> jnp.allclose(a @ eigvecs, eigvecs @ jnp.diag(eigvals))
    Array(True, dtype=bool)
  )rb   ro   s
             r$   rj   rj     s&    @ ;|	q!UL'4	8	88r&   outputrv   c                    |dk    r,|                      t          j        | j                            } t	          j        |           S )Ncomplex)astyper   to_complex_dtypedtyper   schurr   rv   s     r$   _schurr~     s<    y	(1122A		!		r&   realc                P    |dvrt          d|d          t          | |          S )a  Compute the Schur decomposition

  JAX implementation of :func:`scipy.linalg.schur`.

  The Schur form `T` of a matrix `A` satisfies:

  .. math::

     A = Z T Z^H

  where `Z` is unitary, and `T` is upper-triangular for the complex-valued Schur
  decomposition (i.e. ``output="complex"``) and is quasi-upper-triangular for the
  real-valued Schur decomposition (i.e. ``output="real"``). In the quasi-triangular
  case, the diagonal may include 2x2 blocks associated with complex-valued
  eigenvalue pairs of `A`.

  Args:
    a: input array of shape ``(..., N, N)``
    output: Specify whether to compute the ``"real"`` (default) or ``"complex"``
      Schur decomposition.

  Returns:
    A tuple of arrays ``(T, Z)``

    - ``T`` is a shape ``(..., N, N)`` array containing the upper-triangular
      Schur form of the input.
    - ``Z`` is a shape ``(..., N, N)`` array containing the unitary Schur
      transformation matrix.

  See also:
    - :func:`jax.scipy.linalg.rsf2csf`: convert real Schur form to complex Schur form.
    - :func:`jax.lax.linalg.schur`: XLA-style API for Schur decomposition.

  Examples:
    A Schur decomposition of a 3x3 matrix:

    >>> a = jnp.array([[1., 2., 3.],
    ...                [1., 4., 2.],
    ...                [3., 2., 1.]])
    >>> T, Z = jax.scipy.linalg.schur(a)

    The Schur form ``T`` is quasi-upper-triangular in general, but is truly
    upper-triangular in this case because the input matrix is symmetric:

    >>> T  # doctest: +SKIP
    Array([[-2.0000005 ,  0.5066295 , -0.43360388],
           [ 0.        ,  1.5505103 ,  0.74519426],
           [ 0.        ,  0.        ,  6.449491  ]], dtype=float32)

    The transformation matrix ``Z`` is unitary:

    >>> jnp.allclose(Z.T @ Z, jnp.eye(3), atol=1E-5)
    Array(True, dtype=bool)

    The input can be reconstructed from the outputs:

    >>> jnp.allclose(Z @ T @ Z.T, a)
    Array(True, dtype=bool)
  )r   rx   z?Expected 'output' to be either 'real' or 'complex', got output=.)
ValueErrorr~   r}   s     r$   r|   r|     sD    x &&&
KKKKM M M	6		r&   c                D    ~~t           j                            |           S )a  Return the inverse of a square matrix

  JAX implementation of :func:`scipy.linalg.inv`.

  Args:
    a: array of shape ``(..., N, N)`` specifying square array(s) to be inverted.
    overwrite_a: unused in JAX
    check_finite: unused in JAX

  Returns:
    Array of shape ``(..., N, N)`` containing the inverse of the input.

  Notes:
    In most cases, explicitly computing the inverse of a matrix is ill-advised. For
    example, to compute ``x = inv(A) @ b``, it is more performant and numerically
    precise to use a direct solve, such as :func:`jax.scipy.linalg.solve`.

  See Also:
    - :func:`jax.numpy.linalg.inv`: NumPy-style API for matrix inverse
    - :func:`jax.scipy.linalg.solve`: direct linear solver

  Examples:
    Compute the inverse of a 3x3 matrix

    >>> a = jnp.array([[1., 2., 3.],
    ...                [2., 4., 2.],
    ...                [3., 2., 1.]])
    >>> a_inv = jax.scipy.linalg.inv(a)
    >>> a_inv  # doctest: +SKIP
    Array([[ 0.        , -0.25      ,  0.5       ],
           [-0.25      ,  0.5       , -0.25000003],
           [ 0.5       , -0.25      ,  0.        ]], dtype=float32)

    Check that multiplying with the inverse gives the identity:

    >>> jnp.allclose(a @ a_inv, jnp.eye(3), atol=1E-5)
    Array(True, dtype=bool)

    Multiply the inverse by a vector ``b``, to find a solution to ``a @ x = b``

    >>> b = jnp.array([1., 4., 2.])
    >>> a_inv @ b
    Array([ 0.  ,  1.25, -0.5 ], dtype=float32)

    Note, however, that explicitly computing the inverse in such a case can lead
    to poor performance and loss of precision as the size of the problem grows.
    Instead, you should use a direct solver like :func:`jax.scipy.linalg.solve`:

    >>> jax.scipy.linalg.solve(a, b)
     Array([ 0.  ,  1.25, -0.5 ], dtype=float32)
  )r   r   invrY   s      r$   r   r   '  s    h <			r&   )r'   r(   c                    ~~t          t          j        |                     \  } t          j        |           \  }}}||fS )a  Factorization for LU-based linear solves

  JAX implementation of :func:`scipy.linalg.lu_factor`.

  This function returns a result suitable for use with :func:`jax.scipy.linalg.lu_solve`.
  For direct LU decompositions, prefer :func:`jax.scipy.linalg.lu`.

  Args:
    a: input array of shape ``(..., M, N)``.
    overwrite_a: unused by JAX
    check_finite: unused by JAX

  Returns:
    A tuple ``(lu, piv)``

    - ``lu`` is an array of shape ``(..., M, N)``, containing ``L`` in its
      lower triangle and ``U`` in its upper.
    - ``piv`` is an array of shape ``(..., K)`` with ``K = min(M, N)``,
      which encodes the pivots.

  See Also:
    - :func:`jax.scipy.linalg.lu`
    - :func:`jax.scipy.linalg.lu_solve`

  Examples:
    Solving a small linear system via LU factorization:

    >>> a = jnp.array([[2., 1.],
    ...                [1., 2.]])

    Compute the lu factorization via :func:`~jax.scipy.linalg.lu_factor`,
    and use it to solve a linear equation via :func:`~jax.scipy.linalg.lu_solve`.

    >>> b = jnp.array([3., 4.])
    >>> lufac = jax.scipy.linalg.lu_factor(a)
    >>> y = jax.scipy.linalg.lu_solve(lufac, b)
    >>> y
    Array([0.6666666, 1.6666667], dtype=float32)

    Check that the result is consistent:

    >>> jnp.allclose(a @ y, b)
    Array(True, dtype=bool)
  )r   r   r   r   lu)r   r'   r(   r   pivots_s         r$   	lu_factorr   _  s@    \ <ck!nn--"!-""-"fa	Vr&   )transr9   r(   
lu_and_pivtuple[Array, ArrayLike]r   c                    ~~| \  }}|j         dd         \  }}t          j        ||          }	t          j        ||	||          S )a  Solve a linear system using an LU factorization

  JAX implementation of :func:`scipy.linalg.lu_solve`. Uses the output
  of :func:`jax.scipy.linalg.lu_factor`.

  Args:
    lu_and_piv: ``(lu, piv)``, output of :func:`~jax.scipy.linalg.lu_factor`.
      ``lu`` is an array of shape ``(..., M, N)``, containing ``L`` in its lower
      triangle and ``U`` in its upper. ``piv`` is an array of shape ``(..., K)``,
      with ``K = min(M, N)``, which encodes the pivots.
    b: right-hand-side of linear system. Must have shape ``(..., M)``
    trans: type of system to solve. Options are:

      - ``0``: :math:`A x = b`
      - ``1``: :math:`A^Tx = b`
      - ``2``: :math:`A^Hx = b`

    overwrite_b: unused by JAX
    check_finite: unused by JAX

  Returns:
    Array of shape ``(..., N)`` representing the solution of the linear system.

  See Also:
    - :func:`jax.scipy.linalg.lu`
    - :func:`jax.scipy.linalg.lu_factor`

  Examples:
    Solving a small linear system via LU factorization:

    >>> a = jnp.array([[2., 1.],
    ...                [1., 2.]])

    Compute the lu factorization via :func:`~jax.scipy.linalg.lu_factor`,
    and use it to solve a linear equation via :func:`~jax.scipy.linalg.lu_solve`.

    >>> b = jnp.array([3., 4.])
    >>> lufac = jax.scipy.linalg.lu_factor(a)
    >>> y = jax.scipy.linalg.lu_solve(lufac, b)
    >>> y
    Array([0.6666666, 1.6666667], dtype=float32)

    Check that the result is consistent:

    >>> jnp.allclose(a @ y, b)
    Array(True, dtype=bool)
  N)shaper   lu_pivots_to_permutationlu_solve)
r   r/   r   r9   r(   r   r   mr   perms
             r$   r   r     sO    d <*"f	"##$!Q		,VQ	7	7$		Rq%	0	00r&   	permute_lc                    d S rB   rC   r   r   s     r$   _lur     s    HKr&   c                    d S rB   rC   r   s     r$   r   r     s    PSPSr&   0tuple[Array, Array] | tuple[Array, Array, Array]c                    d S rB   rC   r   s     r$   r   r     s    \_\_r&   rh   )static_argnumsc           	        t          t          j        |                     \  } t          j        |           \  }}}t          j        |           }t          j        |           \  }}t          j        t          j	        |d d d f         t          j
        ||j                  d d d f         k    |                    }t          ||          }	t          j        |d          d d d |	f         t          j        ||	|          z   }
t          j        |          d |	d d f         }|r(t          j        ||
t
          j        j                  |fS ||
|fS )Nr{   	precision)r   r   r   r   r   r   r{   r   r   arrayarangemintrileyetriumatmul	PrecisionHIGHEST)r   r   r   r   permutationr{   r   npkr#   us               r$   r   r     s9   ck!nn--"!!}Q''"a
)A,,%	1$!Q	hsyT111W-A[EV1W1W1WXYXYXY[_X_1``hmnnnoo!	!Qii!	hr2qqq"1"u1E : : ::!	hrll2A2qqq5! :acm&;<<<a??a7Nr&   c                    d S rB   rC   r   r   r'   r(   s       r$   r   r     s    ADr&   c                    d S rB   rC   r   s       r$   r   r     s    :=#r&   c                    d S rB   rC   r   s       r$   r   r     s    WZWZr&   )r   r'   r(   c                &    ~~t          | |          S )ac  Compute the LU decomposition

  JAX implementation of :func:`scipy.linalg.lu`.

  The LU decomposition of a matrix `A` is:

  .. math::

     A = P L U

  where `P` is a permutation matrix, `L` is lower-triangular and `U` is upper-triangular.

  Args:
    a: array of shape ``(..., M, N)`` to decompose.
    permute_l: if True, then permute ``L`` and return ``(P @ L, U)`` (default: False)
    overwrite_a: not used by JAX
    check_finite: not used by JAX

  Returns:
    A tuple of arrays ``(P @ L, U)`` if ``permute_l`` is True, else ``(P, L, U)``:

    - ``P`` is a permutation matrix of shape ``(..., M, M)``
    - ``L`` is a lower-triangular matrix of shape ``(... M, K)``
    - ``U`` is an upper-triangular matrix of shape ``(..., K, N)``

    with ``K = min(M, N)``

  See also:
    - :func:`jax.numpy.linalg.lu`: NumPy-style API for LU decomposition.
    - :func:`jax.lax.linalg.lu`: XLA-style API for LU decomposition.
    - :func:`jax.scipy.linalg.lu_solve`: LU-based linear solver.

  Examples:
    An LU decomposition of a 3x3 matrix:

    >>> a = jnp.array([[1., 2., 3.],
    ...                [5., 4., 2.],
    ...                [3., 2., 1.]])
    >>> P, L, U = jax.scipy.linalg.lu(a)

    ``P`` is a permutation matrix: i.e. each row and column has a single ``1``:

    >>> P
    Array([[0., 1., 0.],
           [1., 0., 0.],
           [0., 0., 1.]], dtype=float32)

    ``L`` and ``U`` are lower-triangular and upper-triangular matrices:

    >>> with jnp.printoptions(precision=3):
    ...   print(L)
    ...   print(U)
    [[ 1.     0.     0.   ]
     [ 0.2    1.     0.   ]
     [ 0.6   -0.333  1.   ]]
    [[5.    4.    2.   ]
     [0.    1.2   2.6  ]
     [0.    0.    0.667]]

    The original matrix can be reconstructed by multiplying the three together:

    >>> a_reconstructed = P @ L @ U
    >>> jnp.allclose(a, a_reconstructed)
    Array(True, dtype=bool)
  )r   r   s       r$   r   r     s    H <	Q			r&   modeLiteral['r']pivotingtuple[Array]c                    d S rB   rC   r   r   r   s      r$   _qrr   7  s    KN3r&   Literal['full', 'economic']c                    d S rB   rC   r   s      r$   r   r   :  s    adadr&   "tuple[Array] | tuple[Array, Array]c                    d S rB   rC   r   s      r$   r   r   =  s    X[X[r&   )r   r   c                    |rt          d          |dv rd}n|dk    rd}nt          d| d          t          t          j        |                     \  } t          j        | |          \  }}|d	k    r|fS ||fS )
Nz0The pivoting=True case of qr is not implemented.)fullrTeconomicFz#Unsupported QR decomposition mode ''r=   r   )ri   r   r   r   r   r   qr)r   r   r   r=   qr   s         r$   r   r   @  s     <
:< < <	]MMzMM
B4BBB
C
CCck!nn--"!	q	6	6	6$!Q	S[[4K	
A+r&   r   lworkr   c                    d S rB   rC   r   r'   r   r   r   r(   s         r$   r   r   R  s    RURUr&   c                    d S rB   rC   r   s         r$   r   r   V      KN3r&   )r   r(   c                   d S rB   rC   r   s         r$   r   r   Z  r   r&   c                    d S rB   rC   r   s         r$   r   r   ^  s    adadr&   c                *    ~~~t          | ||          S )ay  Compute the QR decomposition of an array

  JAX implementation of :func:`scipy.linalg.qr`.

  The QR decomposition of a matrix `A` is given by

  .. math::

     A = QR

  Where `Q` is a unitary matrix (i.e. :math:`Q^HQ=I`) and `R` is an upper-triangular
  matrix.

  Args:
    a: array of shape (..., M, N)
    mode: Computational mode. Supported values are:

      - ``"full"`` (default): return `Q` of shape ``(M, M)`` and `R` of shape ``(M, N)``.
      - ``"r"``: return only `R`
      - ``"economic"``: return `Q` of shape ``(M, K)`` and `R` of shape ``(K, N)``,
        where K = min(M, N).

    pivoting: Not implemented in JAX.
    overwrite_a: unused in JAX
    lwork: unused in JAX
    check_finite: unused in JAX

  Returns:
    A tuple ``(Q, R)`` (if ``mode`` is not ``"r"``) otherwise an array ``R``,
    where:

    - ``Q`` is an orthogonal matrix of shape ``(..., M, M)`` (if ``mode`` is ``"full"``)
      or ``(..., M, K)`` (if ``mode`` is ``"economic"``).
    - ``R`` is an upper-triangular matrix of shape ``(..., M, N)`` (if ``mode`` is
      ``"r"`` or ``"full"``) or ``(..., K, N)`` (if ``mode`` is ``"economic"``)

    with ``K = min(M, N)``.

  See also:
    - :func:`jax.numpy.linalg.qr`: NumPy-style QR decomposition API
    - :func:`jax.lax.linalg.qr`: XLA-style QR decomposition API

  Examples:
    Compute the QR decomposition of a matrix:

    >>> a = jnp.array([[1., 2., 3., 4.],
    ...                [5., 4., 2., 1.],
    ...                [6., 3., 1., 5.]])
    >>> Q, R = jax.scipy.linalg.qr(a)
    >>> Q  # doctest: +SKIP
    Array([[-0.12700021, -0.7581426 , -0.6396022 ],
           [-0.63500065, -0.43322435,  0.63960224],
           [-0.7620008 ,  0.48737738, -0.42640156]], dtype=float32)
    >>> R  # doctest: +SKIP
    Array([[-7.8740077, -5.080005 , -2.4130025, -4.953006 ],
           [ 0.       , -1.7870499, -2.6534991, -1.028908 ],
           [ 0.       ,  0.       , -1.0660033, -4.050814 ]], dtype=float32)

    Check that ``Q`` is orthonormal:

    >>> jnp.allclose(Q.T @ Q, jnp.eye(3), atol=1E-5)
    Array(True, dtype=bool)

    Reconstruct the input:

    >>> jnp.allclose(Q @ R, a)
    Array(True, dtype=bool)
  )r   r   s         r$   r   r   c  s    L 5,	Qh		r&   )assume_ar   r   c           	     ,    |dk    r t           j                             |          S t          t          j                   t          j        |                    \   }t          j         |           t          t          j	                   |          t          t          j         fdfdd          } j        |j        dz   k    r ||          S  t          ||j        dz
  t           j        |j                  dz
            |          S )Nposr   c                .    t          j        |           S rB   )r   _matvec_multiply)r<   r   s    r$   <lambda>z_solve.<locals>.<lambda>  s    
+Aq11 r&   c                $    t          |          S rB   )r;   )r   r<   factorss     r$   r   z_solve.<locals>.<lambda>  s    7A.. r&   T)solve	symmetricrh   )r   r   r   r   r   r   r4   r-   r   stop_gradientr   custom_linear_solvendimr	   max)r   r/   r   r   custom_solver   s   `    @r$   _solver     s   :Aq!!!	AA	?	?$!Q A&&& s(++5999'	1111....	  ,
 Vqvz<?? C4afqj#afaf*=*=*ABB1EEEr&   gendebugc                h    ~~~~g d}||vrt          d| d|          t          | |||          S )a  Solve a linear system of equations

  JAX implementation of :func:`scipy.linalg.solve`.

  This solves a (batched) linear system of equations ``a @ x = b`` for ``x``
  given ``a`` and ``b``.

  Args:
    a: array of shape ``(..., N, N)``.
    b: array of shape ``(..., N)`` or ``(..., N, M)``
    lower: Referenced only if ``assume_a != 'gen'``. If True, only use the lower
      triangle of the input, If False (default), only use the upper triangle.
    assume_a: specify what properties of ``a`` can be assumed. Options are:

      - ``"gen"``: generic matrix (default)
      - ``"sym"``: symmetric matrix
      - ``"her"``: hermitian matrix
      - ``"pos"``: positive-definite matrix

    overwrite_a: unused by JAX
    overwrite_b: unused by JAX
    debug: unused by JAX
    check_finite: unused by JAX

  Returns:
    An array of the same shape as ``b`` containing the solution to the linear system.

  See also:
    - :func:`jax.scipy.linalg.lu_solve`: Solve via LU factorization.
    - :func:`jax.scipy.linalg.cho_solve`: Solve via Cholesky factorization.
    - :func:`jax.scipy.linalg.solve_triangular`: Solve a triangular system.
    - :func:`jax.numpy.linalg.solve`: NumPy-style API for solving linear systems.
    - :func:`jax.lax.custom_linear_solve`: matrix-free linear solver.

  Examples:
    A simple 3x3 linear system:

    >>> A = jnp.array([[1., 2., 3.],
    ...                [2., 4., 2.],
    ...                [3., 2., 1.]])
    >>> b = jnp.array([14., 16., 10.])
    >>> x = jax.scipy.linalg.solve(A, b)
    >>> x
    Array([1., 2., 3.], dtype=float32)

    Confirming that the result solves the system:

    >>> jnp.allclose(A @ x, b)
    Array(True, dtype=bool)
  )r   symherr   zExpected assume_a to be one of z; got )r   r   )	r   r/   r   r'   r9   r   r(   r   valid_assume_as	            r$   r   r     sW    j ;|///.^##
Y~YYXYY
Z
ZZ	1h	&	&&r&   )r   r   unit_diagonal	int | strr   c           	        |dk    s|dk    rd\  }}n6|dk    s|dk    rd\  }}n$|dk    s|dk    rd	\  }}nt          d
|           t          t          j        |           t          j        |                    \  } }t          j        |           t          j        |          dz   k    }|r|d         }t          j        | |d||||          }|r|d         S |S )Nr   N)FFrh   T)TF   C)TTzInvalid 'trans' value ).NT)r1   r   r2   r3   r   ).r   )r   r   r   r   r   r   r5   )	r   r/   r   r   r   r2   r3   b_is_vectorouts	            r$   _solve_triangularr      s
    aZZ5C<<+KzzUc\\*KzzUc\\)K
5e55
6
66	AA	?	?$!Q sx{{Q.+ 	)A#AqD0;0;2?	A 	A 	A#  v;Jr&   c                .    ~~~t          | ||||          S )aE  Solve a triangular linear system of equations

  JAX implementation of :func:`scipy.linalg.solve_triangular`.

  This solves a (batched) linear system of equations ``a @ x = b`` for ``x``
  given a triangular matrix ``a`` and a vector or matrix ``b``.

  Args:
    a: array of shape ``(..., N, N)``. Only part of the array will be accessed,
      depending on the ``lower`` and ``unit_diagonal`` arguments.
    b: array of shape ``(..., N)`` or ``(..., N, M)``
    lower: If True, only use the lower triangle of the input, If False (default),
      only use the upper triangle.
    unit_diagonal: If True, ignore diagonal elements of ``a`` and assume they are
      ``1`` (default: False).
    trans: specify what properties of ``a`` can be assumed. Options are:

      - ``0`` or ``'N'``: solve :math:`Ax=b`
      - ``1`` or ``'T'``: solve :math:`A^Tx=b`
      - ``2`` or ``'C'``: solve :math:`A^Hx=b`

    overwrite_b: unused by JAX
    debug: unused by JAX
    check_finite: unused by JAX

  Returns:
    An array of the same shape as ``b`` containing the solution to the linear system.

  See also:
    :func:`jax.scipy.linalg.solve`: Solve a general linear system.

  Examples:
    A simple 3x3 triangular linear system:

    >>> A = jnp.array([[1., 2., 3.],
    ...                [0., 3., 2.],
    ...                [0., 0., 5.]])
    >>> b = jnp.array([10., 8., 5.])
    >>> x = jax.scipy.linalg.solve_triangular(A, b)
    >>> x
    Array([3., 2., 1.], dtype=float32)

    Confirming that the result solves the system:

    >>> jnp.allclose(A @ x, b)
    Array(True, dtype=bool)

    Computing the transposed problem:

    >>> x = jax.scipy.linalg.solve_triangular(A, b, trans='T')
    >>> x
    Array([10. , -4. , -3.4], dtype=float32)

    Confirming that the result solves the system:

    >>> jnp.allclose(A.T @ x, b)
    Array(True, dtype=bool)
  )r   )r   r/   r   r   r   r9   r   r(   s           r$   solve_triangularr     s"    z 5,	1a}	=	==r&   upper_triangularmax_squarings   Ar   r   c                  t          |           \  } | j        dk     s| j        d         | j        d         k    rt          d| j        d          | j        dk    r4 t	          j        t          t                    d          |           S t          t	          j	        |                     \  }}d	 }fd
}t          j        k    ||| ||f          }|S )a)  Compute the matrix exponential

  JAX implementation of :func:`scipy.linalg.expm`.

  Args:
    A: array of shape ``(..., N, N)``
    upper_triangular: if True, then assume that ``A`` is upper-triangular. Default=False.
    max_squarings: The number of squarings in the scaling-and-squaring approximation method
     (default: 16).

  Returns:
    An array of shape ``(..., N, N)`` containing the matrix exponent of ``A``.

  Notes:
    This uses the scaling-and-squaring approximation method, with computational complexity
    controlled by the optional ``max_squarings`` argument. Theoretically, the number of
    required squarings is ``max(0, ceil(log2(norm(A))) - c)`` where ``norm(A)`` is the L1
    norm and ``c=2.42`` for float64/complex128, or ``c=1.97`` for float32/complex64.

  See Also:
    :func:`jax.scipy.linalg.expm_frechet`

  Examples:

    ``expm`` is the matrix exponential, and has similar properties to the more
    familiar scalar exponential. For scalars ``a`` and ``b``, :math:`e^{a + b}
    = e^a e^b`. However, for matrices, this property only holds when ``A`` and
    ``B`` commute (``AB = BA``). In this case, ``expm(A+B) = expm(A) @ expm(B)``

    >>> A = jnp.array([[2, 0],
    ...                [0, 1]])
    >>> B = jnp.array([[3, 0],
    ...                [0, 4]])
    >>> jnp.allclose(jax.scipy.linalg.expm(A+B),
    ...              jax.scipy.linalg.expm(A) @ jax.scipy.linalg.expm(B),
    ...              rtol=0.0001)
    Array(True, dtype=bool)

    If a matrix ``X`` is invertible, then
    ``expm(X @ A @ inv(X)) = X @ expm(A) @ inv(X)``

    >>> X = jnp.array([[3, 1],
    ...                [2, 5]])
    >>> X_inv = jax.scipy.linalg.inv(X)
    >>> jnp.allclose(jax.scipy.linalg.expm(X @ A @ X_inv),
    ...              X @ jax.scipy.linalg.expm(A) @ X_inv)
    Array(True, dtype=bool)
  r   r   r   z8Expected A to be a (batched) square matrix, got A.shape=r   r   z(n,n)->(n,n))	signaturec                H    | ^}}t          j        |t           j                  S rB   )r   	full_likenan)argsr   r   s      r$   _nanzexpm.<locals>._nan  s    EA=CG$$$r&   c                X    | \  }}}t          ||          }t          |          }|S rB   )
_solve_P_Q	_squaring)r   r   PQRr   n_squaringsr   s        r$   _computezexpm.<locals>._compute  s6    GAq!1a)**A![-00AHr&   )r   r   r   r   r   	vectorizer   expm	_calc_P_Qr   r   cond)	r   r   r   r  r  r   r  r  r  s	    ``     @r$   r  r  ]  s   d a  "!VaZZ172;!'"+--
SSSS
T
TTVaZZ 3=d%5]SSS      !# # #  A//!Q% % %       
h{]*D(Q1IFF!	
(r&   c           	     ^   | j         dk    s| j        d         | j        d         k    rt          d          t          j                            | d          }| j        dk    s| j        dk    rd}t          j        dt          j        t          j	        ||z                                }| d|
                    | j                  z  z  } t          j        g d|j        	          }t          j        ||          }t          j        |t          t           t"          t$          t&          g|           \  }}n| j        d
k    s| j        dk    rd}t          j        dt          j        t          j	        ||z                                }| d|
                    | j                  z  z  } t          j        ddg|j        	          }t          j        ||          }t          j        |t          t           t"          g|           \  }}nt)          d| j         d          ||z   }| |z   }	||	|fS )Nr   r   rh   z expected A to be a square matrixfloat64
complex128gC|@)g ,?g|zی@?gQi?gd @r   float32	complex64gj%eg@g#"ՀA?gNj?zA.dtype=z is not supported.)r   r   r   r   r   normr{   maximumfloorlog2ry   r   digitizer   switch_pade3_pade5_pade7_pade9_pade13	TypeError)
r   A_L1maxnormr  condsidxUVr  r  s
             r$   r  r    s   Vq[[AGAJ!'!*,,
7
8
88	1		$ W	QW447Q	#(4'>*B*B C CDD;1""17++++19 F F F J( ( (5 
dE	"	"3
*S66667CQ
G
G41aaw)qw+55G+a38D7N+C+C!D!DEEK	A##AG,,,,AI-/EF J( ( (E
,tU
#
#C:cFFF3Q77DAqq
:qw:::
;
;;!e!b1f!	
A{	r&   r  r  c                f    |rt          ||           S t          j                            ||           S rB   )r   r   r   r   )r  r  r   s      r$   r   r     s2     "Aq!!!:Aq!!!r&   Bc                N    t          j        | |t          j        j                  S )Nr   )r   dotr   r   r   )r   r"  s     r$   _precise_dotr%    s    	A!6	7	7	77r&   r   r  r  c                    d d fd}t          j        || t          j        |j                            \  }}|S )Nc                "    t          | |           S rB   )r%  r<   s    r$   _squaring_precisez$_squaring.<locals>._squaring_precise  s    1r&   c                    | S rB   rC   r(  s    r$   	_identityz_squaring.<locals>._identity  s    Hr&   c                >    t          j        |k     |           d fS rB   )r   r	  )r.   ir+  r)  r  s     r$   _scan_fz_squaring.<locals>._scan_f  s#    8AO%6	1EEtKKr&   r   )r   scanr   r   r{   )r  r  r   r.  resr   r+  r)  s    `    @@r$   r   r     s{        L L L L L L L8GQ
=@Q R R RSS&#q	*r&   c                    d}| j         \  }}t          j        ||| j                  }t	          | |           }t	          | |d         |z  |d         |z  z             }|d         |z  |d         |z  z   }||fS )N)g      ^@g      N@g      (@      ?r      rh   r   r   r   r   r   r{   r%  )r   r/   Mr   identA2r  r   s           r$   r  r    s    !	
$!Q
'!Qag
&
&
&%Aq"1qtBw1e+--!qT"WqtEz!!	
A+r&   c                B   d}| j         \  }}t          j        ||| j                  }t	          | |           }t	          ||          }t	          | |d         |z  |d         |z  z   |d         |z  z             }|d         |z  |d         |z  z   |d         |z  z   }||fS )	N)g     @g     @g     @@g     @z@g      >@r2  r      r3  rh      r   r   r4  )	r   r/   r5  r   r6  r7  A4r  r   s	            r$   r  r    s    ,!	
$!Q
'!Qag
&
&
&%Aq"B"1ad2g!R'!A$u*455!qT"WqtBw1e+!	
A+r&   c                   d}| j         \  }}t          j        ||| j                  }t	          | |           }t	          ||          }t	          ||          }t	          | |d         |z  |d         |z  z   |d         |z  z   |d         |z  z             }|d         |z  |d         |z  z   |d	         |z  z   |d
         |z  z   }	||	fS )N)g    ~pAg    ~`Ag    @t>Ag    @Ag     @g     @g      L@r2  r      r9  r3  rh      r:  r   r   r4  
r   r/   r5  r   r6  r7  r;  A6r  r   s
             r$   r  r    s    F!	
$!Q
'!Qag
&
&
&%Aq"B"B"1ad2g!R'!A$r'1AaDJ>??!d2g!R!A$r'!AaDJ.!	
1*r&   c                   d}| j         \  }}t          j        ||| j                  }t	          | |           }t	          ||          }t	          ||          }t	          ||          }t	          | |d         |z  |d         |z  z   |d         |z  z   |d         |z  z   |d         |z  z             }	|d         |z  |d	         |z  z   |d
         |z  z   |d         |z  z   |d         |z  z   }
|	|
fS )N)
g   ynBg   yn Bg    Ag   @
Ag    2|Ag    ~@Ag     @g     @g     V@r2  r   	   r=  r9  r3  rh      r>  r:  r   r   r4  )r   r/   r5  r   r6  r7  r;  r@  A8r  r   s              r$   r  r    s    *!	
$!Q
'!Qag
&
&
&%Aq"B"B"B"1ad2g!R'!A$r'1AaDG;ad5jHII!d2g!R!A$r'!AaDG+ad5j8!	
1*r&   c           	     Z   d}| j         \  }}t          j        ||| j                  }t	          | |           }t	          ||          }t	          ||          }t	          | t	          ||d         |z  |d         |z  z   |d         |z  z             |d         |z  z   |d         |z  z   |d         |z  z   |d	         |z  z             }t	          ||d
         |z  |d         |z  z   |d         |z  z             |d         |z  z   |d         |z  z   |d         |z  z   |d         |z  z   }	||	fS )N)g D`lCg D`\Cg `=Hb;Cg 	eCg JXBg  "5Bg  /cBg   \L8Bg   pķAg    syAg    S-Ag     @g     f@r2  r         rB  r=  r9  r3  rh      
   rC  r>  r:  r   r   r4  r?  s
             r$   r  r  
  sN   H! 
$!Q
'!Qag
&
&
&%Aq"B"B"1l2quRx!B%(':QqT"W'DEE!RORSTURVWYRYY\]^_\`ac\ccfghifjkpfppqq!2quRx!B%(*QqT"W455!R?!A$r'IAaDQSGSVWXYVZ[`V``!	
1*r&   )methodcompute_expmErJ  
str | NonerK  c                   d S rB   rC   r   rL  rJ  rK  s       r$   expm_frechetrP    s    MPSr&   )rJ  c                   d S rB   rC   rO  s       r$   rP  rP    s    9<r&   c                   d S rB   rC   rO  s       r$   rP  rP     s    LOCr&   c                  ~t          j        |           }t          j        |          }|j        dk     s|j        d         |j        d         k    rt	          d|j                   |j        dk     s|j        d         |j        d         k    rt	          d|j                   |j        |j        k    rt	          d|j         d|j                   t          t          d	d
          }t          ||f|f          \  }}|r||fS |S )ai  Compute the Frechet derivative of the matrix exponential.

  JAX implementation of :func:`scipy.linalg.expm_frechet`

  Args:
    A: array of shape ``(..., N, N)``
    E: array of shape ``(..., N, N)``; specifies the direction of the derivative.
    compute_expm: if True (default) then compute and return ``expm(A)``.
    method: ignored by JAX

  Returns:
    A tuple ``(expm_A, expm_frechet_AE)`` if ``compute_expm`` is True, else
    the array ``expm_frechet_AE``. Both returned arrays have shape ``(..., N, N)``.

  See also:
    :func:`jax.scipy.linalg.expm`

  Examples:
    We can use this API to compute the matrix exponential of ``A``, as well as its
    derivative in the direction ``E``:

    >>> key1, key2 = jax.random.split(jax.random.key(3372))
    >>> A = jax.random.normal(key1, (3, 3))
    >>> E = jax.random.normal(key2, (3, 3))
    >>> expmA, expm_frechet_AE = jax.scipy.linalg.expm_frechet(A, E)

    This can be equivalently computed using JAX's automatic differentiation methods;
    here we'll compute the derivative of :func:`~jax.scipy.linalg.expm` in the
    direction of ``E`` using :func:`jax.jvp`, and find the same results:

    >>> expmA2, expm_frechet_AE2 = jax.jvp(jax.scipy.linalg.expm, (A,), (E,))
    >>> jnp.allclose(expmA, expmA2)
    Array(True, dtype=bool)
    >>> jnp.allclose(expm_frechet_AE, expm_frechet_AE2)
    Array(True, dtype=bool)
  r   r   rh   z8expected A to be a (batched) square matrix, got A.shape=r   z8expected E to be a (batched) square matrix, got E.shape=z3expected A and E to be the same shape, got A.shape=z	 E.shape=Fr   r   )r   r   r   r   r   r   r  r
   )	r   rL  rJ  rK  A_arrE_arr	bound_funexpm_Aexpm_frechet_AEs	            r$   rP  rP  %  s-   N 
+a..%
+a..%
Z!^^u{2%+a.88
]PUP[]]
^
^^
Z!^^u{2%+b/99
]PUP[]]
^
^^
[EK
 D %D D6;kD D E E EdU"EEE)	E8eX>>&/ ?""r&   arrsc            	        t          |           dk    rt          j        d          f} t          t	          |            } d t          |           D             }|r5t          d                    | |d                  |d                             d | D             }|d         }t          j	        |          }|dd         D ]}|j
        \  }}t          j        ||                    d          d|j
        d	         ddff          }t          j        ||                    d          dd|dff          }t          j        ||gd
          }|S )a  Create a block diagonal matrix from input arrays.

  JAX implementation of :func:`scipy.linalg.block_diag`.

  Args:
    *arrs: arrays of at most two dimensions

  Returns:
    2D block-diagonal array constructed by placing the input arrays
    along the diagonal.

  Examples:
    >>> A = jnp.ones((1, 1))
    >>> B = jnp.ones((2, 2))
    >>> C = jnp.ones((3, 3))
    >>> jax.scipy.linalg.block_diag(A, B, C)
    Array([[1., 0., 0., 0., 0., 0.],
           [0., 1., 1., 0., 0., 0.],
           [0., 1., 1., 0., 0., 0.],
           [0., 0., 0., 1., 1., 1.],
           [0., 0., 0., 1., 1., 1.],
           [0., 0., 0., 1., 1., 1.]], dtype=float32)
  r   )rh   r   c                H    g | ]\  }}t          j        |          d k    | S )r   )r   r   ).0r-  r   s      r$   
<listcomp>zblock_diag.<locals>.<listcomp>z  s)    AAAda!qr&   z_Arguments to jax.scipy.linalg.block_diag must have at most 2 dimensions, got {} at argument {}.c                6    g | ]}t          j        |          S rC   )r   
atleast_2d)r\  r   s     r$   r]  zblock_diag.<locals>.<listcomp>  s"    444!CN1%%444r&   rh   N)r   r   r   r   )	dimension)lenr   zerostupler   	enumerater   formatr   r{   r   padr^   concatenate)rY  
bad_shapesconverted_arrsaccr{   r   r   r.   s           r$   
block_diagrk  ^  sU   2 	YY!^^Yv D	~t$	%	%$AAiooAAA* B
 AfT*Q-0*Q-@@B B B 54t444.q#
)C..%!"" 1 1a7DAq5::a==9sy}a.C"DEEA
'#uzz!}}y1a)&<
=
=C
/3(a
0
0
0CC	*r&   )r[   selectselect_range)r[   rl  rm  tolderl  rm  tuple[float, float] | Nonern  float | Nonec               Z	   ! |st          d          d t          j        |           t          j        |          }t          j        t          j        t          j        t          j        f}j        |j        k    rt          dj         d|j                   j        |vs	|j        |vrt          dj         d|j                   j	        d         }|dk    rt          j
                  S t          j        j        t          j                  rRt          j
                  t          j
        |t          j        |          z            t          j                  }	n(t          j        |          }	t          j        |          t          j        |	dd         |	dd	         |	dd         z   |	d	d         gd
          }
t          j        |
z             }t          j        |
z
            }t          j        t          j        |          t          j        |                    }t+          j        j                  }t+          j        g j                  }t+          j        ||j        z  ||j        z   |j        z            }|t          j        dt          j                            z   t          j        |j        |	d         z            |j        |z  |t          j        |          |j        dz   |dk    r!t          j        |t          j                  !n|dk    rc|t=          d          |d         |d         k    rt=          d          t          j        |d         |d         dz   t          j                  !n$|dk    rt          d          t=          d          d}t          j        |j                  |z  |j        z  |z  }||z
  d|z   z  z
  }||z   | z  z   }t          j	        !          }t          j         ||          }t          j         ||          }d||z   z  }t          j          |           t          j         |          fd} !fd}tC          j"        ||d|||f          \  }}}}|S )a  Solve the eigenvalue problem for a symmetric real tridiagonal matrix

  JAX implementation of :func:`scipy.linalg.eigh_tridiagonal`.

  Args:
    d: real-valued array of shape ``(N,)`` specifying the diagonal elements.
    e: real-valued array of shape ``(N - 1,)`` specifying the off-diagonal elements.
    eigvals_only: If True, return only the eigenvalues (default: False). Computation
      of eigenvectors is not yet implemented, so ``eigvals_only`` must be set to True.
    select: specify which eigenvalues to calculate. Supported values are:

      - ``'a'``: all eigenvalues
      - ``'i'``: eigenvalues with indices ``select_range[0] <= i <= select_range[1]``

      JAX does not currently implement ``select = 'v'``.
    select_range: range of values used when ``select='i'``.
    tol: absolute tolerance to use when solving for the eigenvalues.

  Returns:
    An array of eigenvalues with shape ``(N,)``.

  See also:
    :func:`jax.scipy.linalg.eigh`: general Hermitian eigenvalue solver

  Examples:
    >>> d = jnp.array([1., 2., 3., 4.])
    >>> e = jnp.array([1., 1., 1.])
    >>> eigvals = jax.scipy.linalg.eigh_tridiagonal(d, e, eigvals_only=True)
    >>> eigvals
    Array([0.2547188, 1.8227171, 3.1772828, 4.745281 ], dtype=float32)

    For comparison, we can construct the full matrix and compute the same result
    using :func:`~jax.scipy.linalg.eigh`:

    >>> A = jnp.diag(d) + jnp.diag(e, 1) + jnp.diag(e, -1)
    >>> A
    Array([[1., 1., 0., 0.],
           [1., 2., 1., 0.],
           [0., 1., 3., 1.],
           [0., 0., 1., 4.]], dtype=float32)
    >>> eigvals_full = jax.scipy.linalg.eigh(A, eigvals_only=True)
    >>> jnp.allclose(eigvals, eigvals_full)
    Array(True, dtype=bool)
  z.Calculation of eigenvectors is not implementedc                     j         d         t          j        j         t          j                  t          j        j         t          j                   fd} fd |            \  }}d}d}	dz
  |z  }
|
fd} ||	||f          \  }	}}|fd}t          j        |||	||f          \  }}}|S )	z)Implements the Sturm sequence recurrence.r   r   c                     d         z
  } t          j        | dk               }t          j        d         k    |           } | |fS Nr   r   where)r   countalphaalpha0_perturbationonesr<   rb  s     r$   sturm_step0z5eigh_tridiagonal.<locals>._sturm.<locals>.sturm_step0  sL    
(Q,aiAtU++e
)E!HM#6
:
:aXor&   c                    |          | dz
           |z  z
  z
  }t          j        |k    |dz   |          }t          j        |k    t          j        |           |          }||fS )Nrh   )r   rx  minimum)r-  r   ry  rz  beta_sqpivminr<   s      r$   
sturm_stepz4eigh_tridiagonal.<locals>._sturm.<locals>.sturm_step  sl    
(WQU^a'
'!
+aiVUQY66e
)AKQ!8!8!
<
<aXor&   r   rh   c                j    | \  }}}t                    D ]} ||z   ||          \  }}|z   ||fS rB   )range)r   startr   ry  jr  
unroll_cnts        r$   unrolled_stepsz8eigh_tridiagonal.<locals>._sturm.<locals>.unrolled_steps  sT    oeQZ   3 3!:eaiE2255ZE))r&   c                :    | \  }}}t          j        |          S rB   )r   less)iqcr-  r   ry  r   s       r$   r	  z.eigh_tridiagonal.<locals>._sturm.<locals>.cond  s    kaEXa^^r&   )r   r   rb  int32r|  r   
while_loop)rz  r  r  r{  r<   r}  r   ry  	blocksizer-  peelr  r	  r   r   r|  r  r  rb  s   `````         @@@@@r$   _sturmz eigh_tridiagonal.<locals>._sturm  sM   AAIagSY///E8AG39---D                {}}HAu I	AEYDJ* * * * * * !.!Q//KAq% J     .~1e}EEKAq%Lr&   z;diagonal and off-diagonal values must have same dtype, got z and zbOnly float32 and float64 inputs are supported as inputs to jax.scipy.linalg.eigh_tridiagonal, got r   rh   Nr   axisr   r   r-  z/for select='i', select_range must be specified.z&Got empty index range in select_range.rk   z4eigh_tridiagonal(..., select='v') is not implementedz-'select must have a value in {'a', 'i', 'v'}.g @r   )r         ?c           
         | \  }}}}t          j        t          j        |          t          j        t          j        ||z
                                S rB   )r   logical_andr  amax)r   r-  r   r   upperabs_tolmax_its        r$   r	  zeigh_tridiagonal.<locals>.cond@  sQ    Aua?F#(55=11224 4 4r&   c                    | \  }}}} 	
|          }t          j        |k    ||          }t          j        |k    ||          }d||z   z  }|dz   |||fS )Nr  rh   rw  )r   r-  r   midr  countsr  rz  r{  r  r  target_countss         r$   bodyzeigh_tridiagonal.<locals>.bodyF  sz    Auc5VE7F,?EEFIf-sE::EIf},c599E

Cq5%e##r&   )#ri   r   r   r  r  r  r  r{   r  r   r   
issubdtypecomplexfloatingr!   sqrtabssquarerg  r  aminr  npfinfor|  r   epstinynmantr   r  r   r   broadcast_tor   r  )"ro  rp  r[   rl  rm  rn  betasupported_dtypesr   beta_absoff_diag_abs_row_sumlambda_est_maxlambda_est_mint_normr  onesafeminfudge
norm_slackr   r  target_shaper  r	  r  r   r  r  rz  r{  r  r  r  r  s"                             @@@@@@@@r$   eigh_tridiagonalr    s   ` 
 P
N
O
OO. . .` +a..%	Q$k3;s~N
[DJ
 : ;: :-1Z: : ; ; ;
[(((DJ>N,N,N
 6{6 6)-6 6 7 7 7 k!n!!VV8E??^EK!455 HUOOEhtchtnn,--Gx  HHwt}}HjG |Xcrc]Xabb\18BCC=AK K K8E$8899.8E$8899.;sw~..0G0GHH& (5;

%
%+&&&#JsUYuyEJ(FGG'S[CHW$5$5666&
59x{#:;;I'_k#w''G ;?& s]]Jq	222MM}}HIIIAa((?@@@J|AQ!0C39UUUMM}}
 , - - - D
E
EE
 %yEK((5059<vE*
:
%E	F(:
:%
:
%
6% =)),

5
5
5
5%

5
5
5
5%uu}#FL11&()<lKK4 4 4 4 4 4$ $ $ $ $ $ $ $ $ $ dQsE,BCC,!QQ	*r&   )siderJ  r  rightr   )rJ  r  max_iterationsr  r  r  
int | Nonec               t   t          j        |           }|j        dk    rt          d          |dvrt          d          |j        \  }}|dk    r||k    r$|dk    rt          j        |d|          \  }}	}
}
n:||k     rn|d	k    rh|j                                        }t          j        |d|          \  }}	}
}
|	j                                        }	|j                                        }nt          d
|j         d|          |dk    rt          j
        |d          \  }}}|                    |j                  }||z  }|dk    r*|j                                        |dddf         z  |z  }	n=||dddf         z  |j                                        z  }	nt          d| d          ||	fS )aF  Computes the polar decomposition.

  Given the :math:`m \times n` matrix :math:`a`, returns the factors of the polar
  decomposition :math:`u` (also :math:`m \times n`) and :math:`p` such that
  :math:`a = up` (if side is ``"right"``; :math:`p` is :math:`n \times n`) or
  :math:`a = pu` (if side is ``"left"``; :math:`p` is :math:`m \times m`),
  where :math:`p` is positive semidefinite.  If :math:`a` is nonsingular,
  :math:`p` is positive definite and the
  decomposition is unique. :math:`u` has orthonormal columns unless
  :math:`n > m`, in which case it has orthonormal rows.

  Writing the SVD of :math:`a` as
  :math:`a = u_\mathit{svd} \cdot s_\mathit{svd} \cdot v^h_\mathit{svd}`, we
  have :math:`u = u_\mathit{svd} \cdot v^h_\mathit{svd}`. Thus the unitary
  factor :math:`u` can be constructed as the application of the sign function to
  the singular values of :math:`a`; or, if :math:`a` is Hermitian, the
  eigenvalues.

  Several methods exist to compute the polar decomposition. Currently two
  are supported:

  * ``method="svd"``:

    Computes the SVD of :math:`a` and then forms
    :math:`u = u_\mathit{svd} \cdot v^h_\mathit{svd}`.

  * ``method="qdwh"``:

    Applies the `QDWH`_ (QR-based Dynamically Weighted Halley) algorithm.

  Args:
    a: The :math:`m \times n` input matrix.
    side: Determines whether a right or left polar decomposition is computed.
      If ``side`` is ``"right"`` then :math:`a = up`. If ``side`` is ``"left"``
      then :math:`a = pu`. The default is ``"right"``.
    method: Determines the algorithm used, as described above.
    precision: :class:`~jax.lax.Precision` object specifying the matmul precision.
    eps: The final result will satisfy
      :math:`\left|x_k - x_{k-1}\right| < \left|x_k\right| (4\epsilon)^{\frac{1}{3}}`,
      where :math:`x_k` are the QDWH iterates. Ignored if ``method`` is not
      ``"qdwh"``.
    max_iterations: Iterations will terminate after this many steps even if the
      above is unsatisfied.  Ignored if ``method`` is not ``"qdwh"``.

  Returns:
    A ``(unitary, posdef)`` tuple, where ``unitary`` is the unitary factor
    (:math:`m \times n`), and ``posdef`` is the positive-semidefinite factor.
    ``posdef`` is either :math:`n \times n` or :math:`m \times m` depending on
    whether ``side`` is ``"right"`` or ``"left"``, respectively.

  Examples:

    Polar decomposition of a 3x3 matrix:

    >>> a = jnp.array([[1., 2., 3.],
    ...                [5., 4., 2.],
    ...                [3., 2., 1.]])
    >>> U, P = jax.scipy.linalg.polar(a)

    U is a Unitary Matrix:

    >>> jnp.round(U.T @ U)
    Array([[ 1., -0., -0.],
           [-0.,  1.,  0.],
           [-0.,  0.,  1.]], dtype=float32)

    P is positive-semidefinite Matrix:

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...     print(P)
    [[4.79 3.25 1.23]
     [3.25 3.06 2.01]
     [1.23 2.01 2.91]]

    The original matrix can be reconstructed by multiplying the U and P:

    >>> a_reconstructed = U @ P
    >>> jnp.allclose(a, a_reconstructed)
    Array(True, dtype=bool)

  .. _QDWH: https://epubs.siam.org/doi/abs/10.1137/090774999
  r   z"The input `a` must be a 2-D array.)r  leftz5The argument `side` must be either 'right' or 'left'.r   r  F)is_hermitianr  r  zdmethod='qdwh' only supports mxn matrices where m < n where side='right' and m >= n side='left', got z with side=rL   r   Nz#Unknown polar decomposition method r   )r   r   r   r   r   r   r   r!   ri   r   rL   ry   r{   )r   r  rJ  r  r  arrr   r   unitaryposdefr   u_svds_svdvh_svds                 r$   polarr  Q  s   l 	A#X]]
9
:
::	"""
L
M
MM	$!QvAvv$'//"i%SIIIgvq!!	
Q46>>EJJLLc"i%SIIIgvq!x}}f	  gg !M47I!M !MEI!M !M N N N %>#UCCCE5&LL%%EfnGw%aaa.0F:ff dAAAg&57<<>>:ff
D6DDD
E
EE	&r&   r   c                     t          j        t          j                             j        }t          j                  } fdfd}t	          j        d|||          }|S )u   
  Implements Björck, Å., & Hammarling, S. (1983).
      "A Schur method for the square root of a matrix". Linear algebra and
      its applications", 52, 127-140.
  c                (   |\  dz
  | z
  t          j        dz   fdd          }t          j        f         |k    df         |z
                    z   z            }j        f                             |          fS )Nrh   c                4    || f         | f         z  z   S rB   rC   )r   valr  r-  r  s     r$   r   z-_sqrtm_triu.<locals>.i_loop.<locals>.<lambda>  s!    sQq!tWqAw5F/F r&           )r   	fori_loopr   rx  atset)	r#   datasvaluer  r-  r  r   diags	       @@@r$   i_loopz_sqrtm_triu.<locals>.i_loop  s    DAq	A	Aa!eQ F F F F F FLLAIa1glCAw{tAwa'89; ;Ead1a4jnnU####r&   c                @    t          j        d| | |f          \  }}|S rv  )r   r  )r  r  r   r  s      r$   j_loopz_sqrtm_triu.<locals>.j_loop  s%    =Av1v..DAqHr&   r   )r   r  r  sizer   r  )r   r   r  r  r  r  s   `   @@r$   _sqrtm_triur    s     
#(1++		$
i!	htnn!$ $ $ $ $ $     
mAq&!$$!	
(r&   c                
   t          | d          \  }}t          |          }t          j        t          j        ||t          j        j                  t          j        |j                  t          j        j                  S )Nrx   ru   r   )	r|   r  r   r   r   r   r   r!   r   )r   r   Zsqrt_Ts       r$   _sqrtmr    sl    	q	#	#	#$!Qq>>&	CJq&CM4IJJJHQSMMS]-B
D 
D 
D Dr&   r  c                J    |dk    rt          d          t          |           S )u  Compute the matrix square root

  JAX implementation of :func:`scipy.linalg.sqrtm`.

  Args:
    A: array of shape ``(N, N)``
    blocksize: Not supported in JAX; JAX always uses ``blocksize=1``.

  Returns:
    An array of shape ``(N, N)`` containing the matrix square root of ``A``

  See Also:
    :func:`jax.scipy.linalg.expm`

  Examples:
    >>> a = jnp.array([[1., 2., 3.],
    ...                [2., 4., 2.],
    ...                [3., 2., 1.]])
    >>> sqrt_a = jax.scipy.linalg.sqrtm(a)
    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(sqrt_a)
    [[0.92+0.71j 0.54+0.j   0.92-0.71j]
     [0.54+0.j   1.85+0.j   0.54-0.j  ]
     [0.92-0.71j 0.54-0.j   0.92+0.71j]]

    By definition, matrix multiplication of the matrix square root with itself should
    equal the input:

    >>> jnp.allclose(a, sqrt_a @ sqrt_a)
    Array(True, dtype=bool)

  Notes:
    This function implements the complex Schur method described in [1]_.  It does not use
    recursive blocking to speed up computations as a Sylvester Equation solver is not
    yet available in JAX.

  References:
    .. [1] Björck, Å., & Hammarling, S. (1983). "A Schur method for the square root of a matrix".
           Linear algebra and its applications, 52, 127-140.
  rh   z'Blocked version is not implemented yet.)ri   r  )r   r  s     r$   sqrtmr    s)    R ]] IJJJ	r&   )r(   r  c                   ~t          j        |           }t          j        |          }|j        dk    s|j        d         |j        d         k    rt	          d          |j        dk    s|j        d         |j        d         k    rt	          d          |j        d         |j        d         k    rt	          d|j         d|j                   t          ||          \  }}t          j        |j                  j        |j        d         dk    r||fS fdfd	}t          j
        d|||f          S )
a+  Convert real Schur form to complex Schur form.

  JAX implementation of :func:`scipy.linalg.rsf2csf`.

  Args:
    T: array of shape ``(..., N, N)`` containing the real Schur form of the input.
    Z: array of shape ``(..., N, N)`` containing the corresponding Schur transformation
      matrix.
    check_finite: unused by JAX

  Returns:
    A tuple of arrays ``(T, Z)`` of the same shape as the inputs, containing the
    Complex Schur form and the associated Schur transformation matrix.

  See Also:
    :func:`jax.scipy.linalg.schur`: Schur decomposition

  Examples:
    >>> A = jnp.array([[0., 3., 3.],
    ...                [0., 1., 2.],
    ...                [2., 0., 1.]])
    >>> Tr, Zr = jax.scipy.linalg.schur(A)
    >>> Tc, Zc = jax.scipy.linalg.rsf2csf(Tr, Zr)

    Both the real and complex form can be used to reconstruct the input matrix
    to float32 precision:

    >>> jnp.allclose(Zr @ Tr @ Zr.T, A, atol=1E-5)
    Array(True, dtype=bool)
    >>> jnp.allclose(Zc @ Tc @ Zc.conj().T, A, atol=1E-5)
    Array(True, dtype=bool)

    The real-valued Schur form is only quasi-upper-triangular, as we can see in this case:

    >>> with jax.numpy.printoptions(precision=2, suppress=True):
    ...   print(Tr)
    [[ 3.76 -2.17  1.38]
     [ 0.   -0.88 -0.35]
     [ 0.    2.37 -0.88]]

    By contrast, the complex form is truly upper-triangular:

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(Tc)
    [[ 3.76+0.j    1.29-0.78j  2.02-0.5j ]
     [ 0.  +0.j   -0.88+0.91j -2.02+0.j  ]
     [ 0.  +0.j    0.  +0.j   -0.88-0.91j]]
  r   r   rh   zInput 'T' must be square.zInput 'Z' must be square.z"Input array shapes must match: Z: z vs. T: c           	        t           j                            t          j        || dz
  | dz
  fd                    || | f         z
  }t           j                            t          j        |d         || | dz
  f         g                                        |j                  }|d         |z  }|| | dz
  f         |z  }t          j        |	                                |g| |gg|j                  }t          j
        || dz
  dd          }t          j                  | dz
  k    }	|t          j        |	|d          z  }
t          j        |	 ||
          }t          j        ||| dz
  d          }t          j
        || dz
  dd          }t          j                  d d t           j        f         | dz   k     }t          j        ||d          |	                                j        z  }t          j        | ||          }t          j        ||| dz
  d          }t          j
        || dz
  dd          }t          j        |||	                                j        z  | dz
  d          }||fS )Nrh   )r   r   r   r   r   r  )r   r   r\   r   dynamic_slicer  r   ry   r{   r!   dynamic_slice_in_dimr   rx  dynamic_update_slice_in_dimnewaxisr   )r   r   r  mur   r.   r  GT_rowscol_maskG_dot_T_zeroed_cols
T_rows_newT_colsrow_maskT_zeroed_rows_dot_GH
T_cols_newZ_colsr   s                    r$   _update_T_Zzrsf2csf.<locals>._update_T_Za  s@   			C-a!A#qsVDD	E	E!Q$	OB
	2a5!AqsF)"45566==agFFA
1	A	!QqS&	AA	AFFHHa=A2q'*!':::A %a1aa888Fz!}}!#Hci&!<<<H9f.ABBJ':qsCCCA %a1aa888Fz!}}QQQ^,qs2H9Xvq99AFFHHJFH9f.BCCJ':qsCCCA %a1aa888F'6AFFHHJ+>!!LLLAa4Kr&   c           
     f   | z
  }|\  }}t          j        t          j        |||dz
  f                   t          j        ||dz
  |dz
  f                   t          j        |||f                   z   z  k    d |||          \  }}|j        ||dz
  f                             d          }||fS )Nrh   c                
    ||fS rB   rC   )r   r   r  s      r$   r   z0rsf2csf.<locals>._rsf2scf_iter.<locals>.<lambda>  s
    q!f r&   r  )r   r	  r   r  r  r  )r-  TZr   r   r  r   r  r  s        r$   _rsf2scf_iterzrsf2csf.<locals>._rsf2scf_iter{  s    	!ADAq8	ga1Q3i3!A#qs( 4 4swqAw7G7G GHHA	 DAq
 	
Q!VAa4Kr&   )r   r   r   r   r   r   r  r{   r  r   r  )	r   r  r(   T_arrZ_arrr  r   r  r  s	         @@@r$   rsf2csfr    s\   d 
+a..%
+a..%
Z1__A%+a.88
0
1
11
Z1__A%+a.88
0
1
11
[^u{1~%%
\%+\\u{\\
]
]]'u55,%	%+"#k!n!!VV%<    4	 	 	 	 	 	 	 
q!]UEN	;	;;r&   calc_qc                   d S rB   rC   r   r  r'   r(   s       r$   
hessenbergr    s    47Cr&   c                   d S rB   rC   r  s       r$   r  r    s    BE#r&   )r  r(   r'   )r  r'   r(   c          	     |   ~~t          j        |           d         }|dk    r>|r(t          j        |           t          j        |           fS t          j        |           S t          j        |           \  }}t          j        |d          }|rt          j        |dddddf         |          }|j        dd         }	t          j        t          j        |	dz   |j	                  t          j
        |	d|dz
  fz   |j	                  gt          j
        |	|dz
  dfz   |j	                  |gg          }||fS |S )	a  Compute the Hessenberg form of the matrix

  JAX implementation of :func:`scipy.linalg.hessenberg`.

  The Hessenberg form `H` of a matrix `A` satisfies:

  .. math::

     A = Q H Q^H

  where `Q` is unitary and `H` is zero below the first subdiagonal.

  Args:
    a : array of shape ``(..., N, N)``
    calc_q: if True, calculate the ``Q`` matrix (default: False)
    overwrite_a: unused by JAX
    check_finite: unused by JAX

  Returns:
    A tuple of arrays ``(H, Q)`` if ``calc_q`` is True, else an array ``H``

    - ``H`` has shape ``(..., N, N)`` and is the Hessenberg form of ``a``
    - ``Q`` has shape ``(..., N, N)`` and is the associated unitary matrix

  Examples:
    Computing the Hessenberg form of a 4x4 matrix

    >>> a = jnp.array([[1., 2., 3., 4.],
    ...                [1., 4., 2., 3.],
    ...                [3., 2., 1., 4.],
    ...                [2., 3., 2., 2.]])
    >>> H, Q = jax.scipy.linalg.hessenberg(a, calc_q=True)
    >>> with jnp.printoptions(suppress=True, precision=3):
    ...   print(H)
    [[ 1.    -5.078  1.167  1.361]
     [-3.742  5.786 -3.613 -1.825]
     [ 0.    -2.992  2.493 -0.577]
     [ 0.     0.    -0.043 -1.279]]

    Notice the zeros in the subdiagonal positions. The original matrix
    can be reconstructed using the ``Q`` vectors:

    >>> a_reconstructed = Q @ H @ Q.conj().T
    >>> jnp.allclose(a_reconstructed, a)
    Array(True, dtype=bool)
  r   r   .rh   Nr   )rh   rh   r   )r   r   
zeros_liker   r  r   householder_productblockr|  r{   rb  )
r   r  r'   r(   r   a_outtaushr   
batch_dimss
             r$   r  r    sL   b <	ill2!!VV ^Aq 1 111^A%a((+%	hub! &uS!""crc\':DAAASbS!J	CHZ&0DDDIjAq1u:5U[IIIKIjAE1:5U[III1MO 	P 	PA a4KHr&   r   c                   |7t          d|            t          j        t          j        |                     }nt          d| |           t          j        |                                           }t          j        |                                          }|j        \  }|j        \  }|dk    s|dk    r5t          j        ||ft          j        |j        |j                            S ||z   dz
  }t          j	        |ddd         |dd         f          }t          j        |                    d|df          |fddd	t          j        j        
          d         }t          j        |d          S )ax  Construct a Toeplitz matrix

  JAX implementation of :func:`scipy.linalg.toeplitz`.

  A Toeplitz matrix has equal diagonals: :math:`A_{ij} = k_{i - j}`
  for :math:`0 \le i < n` and :math:`0 \le j < n`. This function
  specifies the diagonals via the first column ``c`` and the first row
  ``r``, such that for row `i` and column `j`:

  .. math::

     A_{ij} = \begin{cases}
      c_{i - j} & i \ge j \\
      r_{j - i} & i < j
     \end{cases}

  Notice this implies that :math:`r_0` is ignored.

  Args:
    c: array specifying the first column. Will be flattened
      if not 1-dimensional.
    r: (optional) array specifying the first row. If not specified, defaults
      to ``conj(c)``. Will be flattened if not 1-dimensional.

  Returns:
    toeplitz matrix of shape ``(c.size, r.size)``.

  Examples:
    Specifying ``c`` only:

    >>> c = jnp.array([1, 2, 3])
    >>> jax.scipy.linalg.toeplitz(c)
    Array([[1, 2, 3],
           [2, 1, 2],
           [3, 2, 1]], dtype=int32)

    Specifying ``c`` and ``r``:

    >>> r = jnp.array([-1, -2, -3])
    >>> jax.scipy.linalg.toeplitz(c, r)  # Note r[0] is ignored
    Array([[ 1, -2, -3],
           [ 2,  1, -2],
           [ 3,  2,  1]], dtype=int32)

    If specifying only complex-valued ``c``, ``r`` defaults to ``c.conj()``,
    resulting in a Hermitian matrix if ``c[0].imag == 0``:

    >>> c = jnp.array([1, 2+1j, 1+2j])
    >>> M = jax.scipy.linalg.toeplitz(c)
    >>> M
    Array([[1.+0.j, 2.-1.j, 1.-2.j],
           [2.+1.j, 1.+0.j, 2.-1.j],
           [1.+2.j, 2.+1.j, 1.+0.j]], dtype=complex64)
    >>> print("M is Hermitian:", jnp.all(M == M.conj().T))
    M is Hermitian: True
  Ntoeplitzr   r   rh   r   r   VALID)NTCIOTr  )dimension_numbersr   r  )r   r   	conjugater   flattenr   emptypromote_typesr{   rg  r   conv_general_dilated_patchesreshaper   r   flip)	r.   r   c_arrr_arrncolsnrowsnelemselemspatchess	            r$   r  r    sh   r YJ"""ck!nn%%AAJ1%%%
+a..
 
 
"
"%
+a..
 
 
"
"%;&%;&%
aZZ5A::9eU^,U[%+FFH H H H 5=1&
/52;abb	2
3
3%,mmQN##hg1F%' ' ' ()*' 
'	"	"	""r&   )r   r   c                f    t          j        t          j        | dfd          }d||j        z   dz   z  S )a  Create a Hilbert matrix of order n.

  JAX implementation of :func:`scipy.linalg.hilbert`.

  The Hilbert matrix is defined by:

  .. math::

     H_{ij} = \frac{1}{i + j + 1}

  for :math:`1 \le i \le n` and :math:`1 \le j \le n`.

  Args:
    n: the size of the matrix to create.

  Returns:
    A Hilbert matrix of shape ``(n, n)``

  Examples:
    >>> jax.scipy.linalg.hilbert(2)
    Array([[1.        , 0.5       ],
           [0.5       , 0.33333334]], dtype=float32)
    >>> jax.scipy.linalg.hilbert(3)
    Array([[1.        , 0.5       , 0.33333334],
           [0.5       , 0.33333334, 0.25      ],
           [0.33333334, 0.25      , 0.2       ]], dtype=float32)
  rh   r   )r   broadcasted_iotar   r  r   )r   r   s     r$   hilbertr  (  s2    : 
3;A22!	
AGaKr&   )r   r   r   r   r   r   )FFT)
r   r   r   r   r'   r   r(   r   r   r   )
r   r   r   r   r'   r   r(   r   r   r+   )r.   r   r/   r   r   r   r   r   )FT)
r7   r8   r/   r   r9   r   r(   r   r   r   )r<   r   r=   r   r>   r?   r   r@   )r<   r   r=   r   r>   rF   r   r   )r<   r   r=   r   r>   r   r   rH   )r   r   r=   r   r>   r   r   rH   )TTFTrM   )r   r   r=   r   r>   r?   r'   r   r(   r   rN   rO   r   r@   )FTrM   )r   r   r=   r   r>   rF   r'   r   r(   r   rN   rO   r   r   )T)r   r   r=   r   r>   r   r'   r   r(   r   rN   rO   r   rH   )r   r   r'   r   r(   r   r   r   )r   r   r/   rZ   r   r   r[   r?   r\   r]   r^   r_   r   r   )r   r   r/   rZ   r   r   r[   rF   r\   r]   r^   r_   r   rc   )r   r   r/   rZ   r   r   r[   r   r\   r]   r^   r_   r   re   )	NTFFFTNrh   T)r   r   r/   rZ   r   r   r[   rF   r'   r   r9   r   rm   r   r\   r]   r^   r_   r(   r   r   rc   )NT)r   r   r/   rZ   r   r   r[   r?   r'   r   r9   r   rm   r   r\   r]   r^   r_   r(   r   r   r   )FFTNrh   T)r   r   r/   rZ   r   r   r[   r   r'   r   r9   r   rm   r   r\   r]   r^   r_   r(   r   r   re   )r   r   rv   rO   r   rc   )r   )r   r   rv   rO   r   rc   )r   r   r'   r   r(   r   r   rc   )r   FT)r   r   r/   r   r   r_   r9   r   r(   r   r   r   )r   r   r   r?   r   rc   )r   r   r   rF   r   r@   )r   r   r   r   r   r   )
r   r   r   rF   r'   r   r(   r   r   r@   )
r   r   r   r?   r'   r   r(   r   r   rc   )
r   r   r   r   r'   r   r(   r   r   r   )r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   rc   )r   r   r   rO   r   r   r   r   )FNr   FT)r   r   r'   r   r   r   r   r   r   r   r(   r   r   rc   )r   r   r'   r   r   r   r   r   r   r   r(   r   r   r   )FN)r   r   r'   r   r   r   r   rO   r   r   r(   r   r   r   )
r   r   r/   r   r   rO   r   r   r   r   )FFFFTr   )r   r   r/   r   r   r   r'   r   r9   r   r   r   r(   r   r   rO   r   r   )r   r   r/   r   r   r   r   r   r   r   r   r   )r   FFFNT)r   r   r/   r   r   r   r   r   r   r   r9   r   r   r   r(   r   r   r   )r   r   r   r   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   )r   r   r   rc   )
r   r   rL  r   rJ  rM  rK  r?   r   rc   )
r   r   rL  r   rJ  rM  rK  rF   r   r   )
r   r   rL  r   rJ  rM  rK  r   r   re   )rY  r   r   r   )ro  r   rp  r   r[   r   rl  rO   rm  rq  rn  rr  r   r   )r  )r   r   r  rO   rJ  rO   r  rr  r  r  r   rc   )r   r   r   r   )r   r   r   r   )r   r   r  r_   r   r   )r   r   r  r   r(   r   r   rc   )
r   r   r  rF   r'   r   r(   r   r   r   )
r   r   r  r?   r'   r   r(   r   r   rc   )
r   r   r  r   r'   r   r(   r   r   re   rB   )r.   r   r   rZ   r   r   )r   r_   r   r   )P
__future__r   	functoolsr   numpyr  textwraptypingr   r   r   jax	jax.numpyr   r   r	   r
   r   jax._srcr   jax._src.laxr   r   r   jax._src.numpy.utilr   r   r   r   jax._src.typingr   r   dedent_no_chkfinite_doc_no_overwrite_and_chkfinite_docr%   r    r-   r6   r;   rE   rL   rX   rb   rj   r~   r|   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r%  r   r  r  r  r  r  rP  rk  r  default_matmul_precisionr  r  r  r  r  r  r  r  rC   r&   r$   <module>r)     s   # " " " " "            ) ) ) ) ) ) ) ) ) ) 



                             - - - - - -                  - , , , , , , , $HO %    #46s"s j)))( ( ( *)( EJ"&9 9 9 9 9x GL$(-+ -+ -+ -+ -+^ 	j)))   *) ?C,! ,! ,! ,! ,!\ 
 l l l 
 l	 X X X 
 X	 k k k 
 k=>>>O O O ?>O 
NR8<$I I I I 
I 
8<$4 4 4 4 
4 
4!$4 4 4 4 4 
4 
EI8<$Q Q Q Q 
Q
 FJ8<$EE EE EE EE EEP" " " " "J 
2 2 2 
2 
@ @ @ 
@ 
H H H 
H 	JKKK   LK$ 
AECHHL-1O O O O 
O
 
A:?"$TA A A A A 
A
 
:?HL-1A A A A 
A
 
AE9>HL-1W W W W 
W
 BF9>HL-1A9 A9 A9 A9 A9F 	k***   +*
? ? ? ? ?D5 5 5 5 5p 	=>>>0 0 0 0 ?>0f 	FGGGMN=A51 51 51 51 HG51n 
 K K K 
 K	 S S S 
 S	 _ _ _ 
 _T"""   #" 
LQ E E E E 
E 
CH > > > > 
> 
BG [ [ [ [ 
[ 	JKKKBG D D D D LKDL 
 N N N 
 N	 d d d 
 d	 [ [ [ 
 [2333   43" 
gm48V V V V 
V 
48O O O O 
O 
ODO O O O O 
O 
OU48e e e e 
e PV48G  G  G  G  G T 	3444F F F 54F. 5:NS5:9' 9' 9' 9' 9'v 	ABBB   CB6 V[FK=A>> >> >> >> >>B 	CDDD38r H H H H H EDHT    <" " " " "8 8 8 8 	Q          	 	 	 	       
EI/3Q Q Q Q Q 
Q 
EI = = = = = 
= 
EI&*P P P P P 
P 	8999EI&*5 5 5 5 5 :95p ( ( ( (V 	HIIIIN#&SW)-D D D D D JIDL 	0111i((vfZ^'+v v v v v )( 21vr    2 D D D D+ + + + +\ 	/000i< i< i< i< 10i<V 
LQ$(8 8 8 8 8 
8 
KP$(F F F F F 
F 	GHHH/4%$(A A A A A IHAHO# O# O# O# O#d 	f%%%   &%  r&   