
    Vpfdl                    n   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mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ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)m*Z*m+Z+m,Z, d dl-m.Z.m/Z/ edBd            Z0edCd            Z1dddDdZ2 eed          	 	 dEdFd)            Z3edGd+            Z4 eed,g          d-d.dHd/            Z5edId2            Z6 eed3          dJdKd8            Z7 eed3          dLdMd9            Z8dd:dNd<Z9dd:dOd@Z:edIdA            Z;dS )P    )annotations)partialN)jit)lax)dtypes)core)arangeargminarrayasarray
atleast_1dconcatenateconvolvediagdotfinfofullonesouterroll
trim_zerostrim_zeros_tolvanderzeros)maximumtrue_dividesqrt)alllinalg)check_arraylikepromote_dtypespromote_dtypes_inexact_where)Array	ArrayLikepr%   returnc                T   | j         dk     r(t          g t          j        | j                            S t          t          | j         dz
  f| j                  d          }|j        dd d f                             | dd           | d         z            }t          j
        |          S )N   dtyper      )sizer   r   to_complex_dtyper,   r   r   atsetr    eigvals)r'   As     Y/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/_src/numpy/polynomial.py_roots_no_zerosr6   &   s     VaZZ6217;;<<<<
4!qw'',,!d1aaa4jnnaeVad]##!			    num_leading_zerosArray | intc                b   t          t          |           |k    d|           } t          t          | |                     }t	          j        |dk    |          d         }t          t          |j                  |j        |z
  k     |t          t          j
        t          j
                            S )N      ?r   r.   )r$   lenr6   r   r   sort_key_valr	   r/   complexnpnan)r'   r8   rootss      r5   _roots_with_zerosrB   0   s     SVV((#q11!
$q#4"455
6
6%

5A:u
-
-a
0%	uz""UZ2C%CCUGTVTZ\^\bLcLc	d	ddr7   T)strip_zerosr&   rC   boolc               
   t          d|            t          t          |           d                   }~ |j        dk    rt	          d          |j        dk     r(t          g t          j        |j	                            S t          t          |dk              t          |          t          |dk                        }|r2t          j        t           |d          }t#          ||d                   S t%          ||          S )	a  Returns the roots of a polynomial given the coefficients ``p``.

  JAX implementations of :func:`numpy.roots`.

  Args:
    p: Array of polynomial coefficients having rank-1.
    strip_zeros : bool, default=True. If True, then leading zeros in the
      coefficients will be stripped, similar to :func:`numpy.roots`. If set to
      False, leading zeros will not be stripped, and undefined roots will be
      represented by NaN values in the function output. ``strip_zeros`` must be
      set to ``False`` for the function to be compatible with :func:`jax.jit` and
      other JAX transformations.

  Returns:
    An array containing the roots of the polynomial.

  Note:
    Unlike ``np.roots`` of this function, the ``jnp.roots`` returns the roots
    in a complex array regardless of the values of the roots.

  See Also:
    - :func:`jax.numpy.poly`: Finds the polynomial coefficients of the given
      sequence of roots.
    - :func:`jax.numpy.polyfit`: Least squares polynomial fit to data.
    - :func:`jax.numpy.polyval`: Evaluate a polynomial at specific values.

  Examples:
    >>> coeffs = jnp.array([0, 1, 2])

    The default behavior matches numpy and strips leading zeros:

    >>> jnp.roots(coeffs)
    Array([-2.+0.j], dtype=complex64)

    With ``strip_zeros=False``, extra roots are set to NaN:

    >>> jnp.roots(coeffs, strip_zeros=False)
    Array([-2. +0.j, nan+nanj], dtype=complex64)
  rA   r   r.   zInput must be a rank-1 array.r*   r+   zThe error occurred in the jnp.roots() function. To use this within a JIT-compiled context, pass strip_zeros=False, but be aware that leading zeros will result in some returned roots being set to NaN.N)r!   r   r#   ndim
ValueErrorr/   r   r   r0   r,   r$   r   r<   r
   r   concrete_or_errorintr6   rB   )r'   rC   p_arrr8   s       r5   rA   rA   <   s    P '1
+A..q1
2
2%
Z1__
4
5
55
Z!^^625;??@@@@S!__c%jj&!:L:LMM 7.s4E=> > 5!2!3!34555U$5666r7   )degrcondr   cov)static_argnamesFxyrK   rI   rL   float | Noner   wArrayLike | NonerM   Array | tuple[Array, ...]c                n   |t          d| |           nt          d| ||           t          j        t          |d          }|dz   }t	          |           t	          |          }	}~ ~|dk     rt          d          |j        dk    rt          d          |j        dk    rt          d          |	j        dk     s|	j        d	k    rt          d
          |j	        d         |	j	        d         k    rt          d          |)t          |          t          |j                  j        z  }t          j        t          |d          }t          ||          }
|	}|t!          |          \  }t	          |          }|j        dk    rt          d          |j	        d         |	j	        d         k    rt          d          |
|ddt"          j        f         z  }
|j        d	k    r||ddt"          j        f         z  }n||z  }t'          |
|
z                      d                    }|
|t"          j        ddf         z  }
t+          j        |
||          \  }}}}|j        |z  j        }|r||||t	          |          fS |rt+          j        t3          |
j        |
                    }|t5          ||          z  }|dk    rd}n?t          |          |k    rt          d          |t          |          |z
  z  }|d         }|	j        dk    r|||z  fS ||ddddt"          j        f         |z  fS |S )a  Least squares polynomial fit to data.

  Jax implementation of :func:`numpy.polyfit`.

  Given a set of data points ``(x, y)`` and degree of polynomial ``deg``, the
  function finds a polynomial equation of the form:

  .. math::

	   y = p(x) = p[0] x^{deg} + p[1] x^{deg - 1} + ... + p[deg]

  Args:
    x: Array of data points of shape ``(M,)``.
    y: Array of data points of shape ``(M,)`` or ``(M, K)``.
    deg: Degree of the polynomials. It must be specified statically.
    rcond: Relative condition number of the fit. Default value is ``len(x) * eps``.
       It must be specified statically.
    full: Switch that controls the return value. Default is ``False`` which
      restricts the return value to the array of polynomail coefficients ``p``.
      If ``True``, the function returns a tuple ``(p, resids, rank, s, rcond)``.
      It must be specified statically.
    w: Array of weights of shape ``(M,)``. If None, all data points are considered
      to have equal weight. If not None, the weight :math:`w_i` is applied to the
      unsquared residual of :math:`y_i - \widehat{y}_i` at :math:`x_i`, where
      :math:`\widehat{y}_i` is the fitted value of :math:`y_i`. Default is None.
    cov: Boolean or string. If ``True``, returns the covariance matrix scaled
      by ``resids/(M-deg-1)`` along with ploynomial coefficients. If
      ``cov='unscaled'``, returns the unscaaled version of covariance matrix.
      Default is ``False``. ``cov`` is ignored if ``full=True``. It must be
      specified statically.

  Returns:
    - An array polynomial coefficients ``p`` if ``full=False`` and ``cov=False``.

    - A tuple of arrays ``(p, resids, rank, s, rcond)`` if ``full=True``. Where

      - ``p`` is an array of shape ``(M,)`` or ``(M, K)`` containing the polynomial
        coefficients.
      - ``resids`` is the sum of squared residual of shape () or (K,).
      - ``rank`` is the rank of the matrix ``x``.
      - ``s`` is the singular values of the matrix ``x``.
      - ``rcond`` as the array.
    - A tuple of arrays ``(p, C)`` if ``full=False`` and ``cov=True``. Where

      - ``p`` is an array of shape ``(M,)`` or ``(M, K)`` containing the polynomial
        coefficients.
      - ``C`` is the covariance matrix of polynomial coefficients of shape
        ``(deg + 1, deg + 1)`` or ``(deg + 1, deg + 1, 1)``.

  Note:
    Unlike :func:`numpy.polyfit` implementation of polyfit, :func:`jax.numpy.polyfit`
    will not warn on rank reduction, which indicates an ill conditioned matrix.

  See Also:
    - :func:`jax.numpy.poly`: Finds the polynomial coefficients of the given
      sequence of roots.
    - :func:`jax.numpy.polyval`: Evaluate a polynomial at specific values.
    - :func:`jax.numpy.roots`: Computes the roots of a polynomial for given
      coefficients.

  Examples:
    >>> x = jnp.array([3., 6., 9., 4.])
    >>> y = jnp.array([[0, 1, 2],
    ...                [2, 5, 7],
    ...                [8, 4, 9],
    ...                [1, 6, 3]])
    >>> p = jnp.polyfit(x, y, 2)
    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(p)
    [[ 0.2  -0.35 -0.14]
     [-1.17  4.47  2.96]
     [ 1.95 -8.21 -5.93]]

    If ``full=True``, returns a tuple of arrays as follows:

    >>> p, resids, rank, s, rcond = jnp.polyfit(x, y, 2, full=True)
    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print("Polynomial Coefficients:", "\n", p, "\n",
    ...         "Residuals:", resids, "\n",
    ...         "Rank:", rank, "\n",
    ...         "s:", s, "\n",
    ...         "rcond:", rcond)
    Polynomial Coefficients:
    [[ 0.2  -0.35 -0.14]
    [-1.17  4.47  2.96]
    [ 1.95 -8.21 -5.93]]
    Residuals: [0.37 5.94 0.61]
    Rank: 3
    s: [1.67 0.47 0.04]
    rcond: 4.7683716e-07

    If ``cov=True`` and ``full=False``, returns a tuple of arrays having
    polynomial coefficients and covariance matrix.

    >>> p, C = jnp.polyfit(x, y, 2, cov=True)
    >>> p.shape, C.shape
    ((3, 3), (3, 3, 1))
  Npolyfitzdeg must be intr.   r   zexpected deg >= 0zexpected 1D vector for xzexpected non-empty vector for xr*   zexpected 1D or 2D array for yz$expected x and y to have same lengthzrcond must be floatz expected a 1-d array for weightsz(expected w and y to have the same length)axisunscaledzJthe number of data points must exceed order to scale the covariance matrix)r!   r   rH   rI   r   rG   rF   	TypeErrorr/   shaper<   r   r,   epsfloatr   r#   r?   newaxisr   sumr    lstsqTinvr   r   )rO   rP   rK   rL   r   rR   rM   orderx_arry_arrlhsrhsw_arrscalecresidsranksVbasefacs                       r5   rV   rV   w   sJ   L YIq!$$$$Iq!Q'''sC):;;#
'%WQZZ%1WW
(
)
))
Z1__
.
/
//
Z1__
5
6
66
Z!^^uzA~~
3
4
44
[^u{1~%%
:
;
;; ]JJu{++//E

 /D
E
E%ue## ]		"	"BAAJJEzQ8999{1~Q''@AAA5BJC
x1}}	U111bj=!!cc	Ulc C}}!}$$
%
%%rz!!!|	#|Ce44!VT1s5ym!	 fdAwu~~--
 Js35#''E	U5%   E
jcc	Uu		 = > > 	>c%jj5()cFczQ^aaaBJ&'#---Hr7   seq_of_zerosc           	     B   t          d|            t          |           \  } t          |           }~ |j        }t	          |          dk    r4|d         |d         k    r"|d         dk    rddlm}  |j        |          }|j        dk    rt          d          |j
        }t	          |          dk    rt          d|          S t          d	|          }t          t	          |                    D ],}t          |t          d||          g|          d
          }-|S )a  Returns the coefficients of a polynomial for the given sequence of roots.

  JAX implementation of :func:`numpy.poly`.

  Args:
    seq_of_zeros: A scalar or an array of roots of the polynomial of shape ``(M,)``
      or ``(M, M)``.

  Returns:
    An array containing the coefficients of the polynomial. The dtype of the
    output is always promoted to inexact.

  Note:

    :func:`jax.numpy.poly` differs from :func:`numpy.poly`:

    - When the input is a scalar, ``np.poly`` raises a ``TypeError``, whereas
      ``jnp.poly`` treats scalars the same as length-1 arrays.
    - For complex-valued or square-shaped inputs, ``jnp.poly`` always returns
      complex coefficients, whereas ``np.poly`` may return real or complex
      depending on their values.

  See also:
    - :func:`jax.numpy.polyfit`: Least squares polynomial fit.
    - :func:`jax.numpy.polyval`: Evaluate a polynomial at specific values.
    - :func:`jax.numpy.roots`: Computes the roots of a polynomial for given
      coefficients.

  Example:

    Scalar inputs:

    >>> jnp.poly(1)
    Array([ 1., -1.], dtype=float32)

    Input array with integer values:

    >>> x = jnp.array([1, 2, 3])
    >>> jnp.poly(x)
    Array([ 1., -6., 11., -6.], dtype=float32)

    Input array with complex conjugates:

    >>> x = jnp.array([2, 1+2j, 1-2j])
    >>> jnp.poly(x)
    Array([  1.+0.j,  -4.+0.j,   9.+0.j, -10.+0.j], dtype=complex64)

    Input array as square matrix with real valued inputs:

    >>> x = jnp.array([[2, 1, 5],
    ...                [3, 4, 7],
    ...                [1, 3, 5]])
    >>> jnp.round(jnp.poly(x))
    Array([  1.+0.j, -11.-0.j,   9.+0.j, -15.+0.j], dtype=complex64)
  polyr*   r   r.   r   z.input must be 1d or non-empty square 2d array. r+   r.   r   mode)r!   r#   r   rZ   r<   jax._src.numpyr    r3   rF   rG   r,   r   ranger   r   )ro   seq_of_zeros_arrshr    dtaks          r5   rq   rq   "  sC   r &,'''(66-,--"WW\\ber!unnA!%%%%%%%v~&677a
E
F
FF"	a"
4r!%&&'' M MaE1/2232>>>VLLLAA	
(r7   unroll   r}   c                  t          d| |           t          | |          \  }~ ~t          j        |j        dd         j                  }t          j        d|j                  }t          j        fd|||          \  }}|S )a  Evaluates the polynomial at specific values.

  JAX implementations of :func:`numpy.polyval`.

  For the 1D-polynomial coefficients ``p`` of length ``M``, the function returns
  the value:

  .. math::

    p_0 x^{M - 1} + p_1 x^{M - 2} + ... + p_{M - 1}

  Args:
    p: An array of polynomial coefficients of shape ``(M,)``.
    x: A number or an array of numbers.
    unroll: A number used to control the number of unrolled steps with
      ``lax.scan``. It must be specified statically.

  Returns:
    An array of same shape as ``x``.

  Note:

    The ``unroll`` parameter is JAX specific. It does not affect correctness but
    can have a major impact on performance for evaluating high-order polynomials.
    The parameter controls the number of unrolled steps with ``lax.scan`` inside
    the ``jnp.polyval`` implementation. Consider setting ``unroll=128`` (or even
    higher) to improve runtime performance on accelerators, at the cost of
    increased compilation time.

  See also:
    - :func:`jax.numpy.polyfit`: Least squares polynomial fit.
    - :func:`jax.numpy.poly`: Finds the coefficients of a polynomial with given
      roots.
    - :func:`jax.numpy.roots`: Computes the roots of a polynomial for given
      coefficients.

  Example:
    >>> p = jnp.array([2, 5, 1])
    >>> jnp.polyval(p, 3)
    Array(34., dtype=float32)

    If ``x`` is a 2D array, ``polyval`` returns 2D-array with same shape as
    that of ``x``:

    >>> x = jnp.array([[2, 1, 5],
    ...                [3, 4, 7],
    ...                [1, 3, 5]])
    >>> jnp.polyval(p, x)
    Array([[ 19.,   8.,  76.],
           [ 34.,  53., 134.],
           [  8.,  34.,  76.]], dtype=float32)
  polyvalr.   Nr   )rZ   r,   c                    | z  |z   d fS )Nrr   )rP   r'   rc   s     r5   <lambda>zpolyval.<locals>.<lambda>  s    E	At4 r7   r   )r!   r#   r   broadcast_shapesrZ   	full_liker,   scan)r'   rO   r}   rJ   rZ   rP   _rc   s          @r5   r   r   t  s    l )Q"""'1--,%

u{122
<
<%	mE1E===!	4444av	N	N	N$!Q	
(r7   a1a2c                >   t          d| |           t          | |          \  }}~ ~|j        d         |j        d         k    r.|j        |j        d          d                             |          S |j        |j        d          d                             |          S )a  Returns the sum of the two polynomials.

  JAX implementation of :func:`numpy.polyadd`.

  Args:
    a1: Array of polynomial coefficients.
    a2: Array of polynomial coefficients.

  Returns:
    An array containing the coefficients of the sum of input polynomials.

  Note:
    :func:`jax.numpy.polyadd` only accepts arrays as input unlike
    :func:`numpy.polyadd` which accepts scalar inputs as well.

  See also:
    - :func:`jax.numpy.polysub`: Computes the difference of two polynomials.
    - :func:`jax.numpy.polymul`: Computes the product of two polynomials.
    - :func:`jax.numpy.polydiv`: Computes the quotient and remainder of polynomial
      division.

  Example:
    >>> x1 = jnp.array([2, 3])
    >>> x2 = jnp.array([5, 4, 1])
    >>> jnp.polyadd(x1, x2)
    Array([5, 6, 4], dtype=int32)

    >>> x3 = jnp.array([[2, 3, 1]])
    >>> x4 = jnp.array([[5, 7, 3],
    ...                 [8, 2, 6]])
    >>> jnp.polyadd(x3, x4)
    Array([[ 5,  7,  3],
           [10,  5,  7]], dtype=int32)

    >>> x5 = jnp.array([1, 3, 5])
    >>> x6 = jnp.array([[5, 7, 9],
    ...                 [8, 6, 4]])
    >>> jnp.polyadd(x5, x6)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    ValueError: Cannot broadcast to shape with fewer dimensions: arr_shape=(2, 3) shape=(2,)
    >>> x7 = jnp.array([2])
    >>> jnp.polyadd(x6, x7)
    Array([[ 5,  7,  9],
           [10,  8,  6]], dtype=int32)
  polyaddr   N)r!   r"   rZ   r1   add)r   r   a1_arra2_arrs       r5   r   r     s    ` )R$$$!"b)).&&"\!_Q''9fl1o%&&'++F3339fl1o%&&'++F333r7   )mr.   r   r|   int | ArrayLike | Nonec                   t          j        t          j        |d          }|dn|}t	          d| |           t          | |          \  }}~ ~|dk     rt          d          t          |          }t          |          dk    rt          |f|d                   }|j
        |fk    rt          d          |dk    r|S t          t          |          |z   |j                  t          j                 t          ||j                  ddt          j        f         z
  }t          d|                              d          ddd	         }t#          t%          ||f          |          S )
a  Returns the coefficients of the integration of specified order of a polynomial.

  JAX implementation of :func:`numpy.polyint`.

  Args:
    p: An array of polynomial coefficients.
    m: Order of integration. Default is 1. It must be specified statically.
    k: Scalar or array of ``m`` integration constant (s).

  Returns:
    An array of coefficients of integrated polynomial.

  See also:
    - :func:`jax.numpy.polyder`: Computes the coefficients of the derivative of
      a polynomial.
    - :func:`jax.numpy.polyval`: Evaluates a polynomial at specific values.

  Examples:

    The first order integration of the polynomial :math:`12 x^2 + 12 x + 6` is
    :math:`4 x^3 + 6 x^2 + 6 x`.

    >>> p = jnp.array([12, 12, 6])
    >>> jnp.polyint(p)
    Array([4., 6., 6., 0.], dtype=float32)

    Since the constant ``k`` is not provided, the result included ``0`` at the end.
    If the constant ``k`` is provided:

    >>> jnp.polyint(p, k=4)
    Array([4., 6., 6., 4.], dtype=float32)

    and the second order integration is :math:`x^4 + 2 x^3 + 3 x`:

    >>> jnp.polyint(p, m=2)
    Array([1., 2., 3., 0., 0.], dtype=float32)

    When ``m>=2``, the constants ``k`` should be provided as an array having
    ``m`` elements. The second order integration of the polynomial
    :math:`12 x^2 + 12 x + 6` with the constants ``k=[4, 5]`` is
    :math:`x^4 + 2 x^3 + 3 x^2 + 4 x + 5`:

    >>> jnp.polyint(p, m=2, k=jnp.array([4, 5]))
    Array([1., 2., 3., 4., 5.], dtype=float32)
  z'm' argument of jnp.polyintNr   polyintz0Order of integral must be positive (see polyder)r.   z6k must be a scalar or a rank-1 array of length 1 or m.r+   r-   )r   rH   operatorindexr!   r#   rG   r   r<   r   rZ   r	   r,   r?   r]   r   prodr   r   )r'   r   r|   rJ   k_arrgridcoeffs          r5   r   r     sW   ^ X^Q0MNN!9aa!!)Q"""'1--,%UU
G
H
HH
U

%ZZ1__!uQx  E
[QD
M
N
NN!VVL3u::>555bjAQek***111bj=9:DAt!!!$$TTrT*E{E5>22E:::r7   c                   t          d|            t          j        t          j        |d          }t          |           \  }~ |dk     rt          d          |dk    r|S t          |t          |          |j	                  t          j                 t          ||j	                  ddt          j        f         z
                      d          }|d|          |ddd         z  S )aI  Returns the coefficients of the derivative of specified order of a polynomial.

  JAX implementation of :func:`numpy.polyder`.

  Args:
    p: Array of polynomials coefficients.
    m: Order of differentiation (positive integer). Default is 1. It must be
      specified statically.

  Returns:
    An array of polynomial coefficients representing the derivative.

  Note:
    :func:`jax.numpy.polyder` differs from :func:`numpy.polyder` when an integer
    array is given. NumPy returns the result with dtype ``int`` whereas JAX
    returns the result with dtype ``float``.

  See also:
    - :func:`jax.numpy.polyint`: Computes the integral of polynomial.
    - :func:`jax.numpy.polyval`: Evaluates a polynomial at specific values.

  Examples:

    The first order derivative of the polynomial :math:`2 x^3 - 5 x^2 + 3 x - 1`
    is :math:`6 x^2 - 10 x +3`:

    >>> p = jnp.array([2, -5, 3, -1])
    >>> jnp.polyder(p)
    Array([  6., -10.,   3.], dtype=float32)

    and its second order derivative is :math:`12 x - 10`:

    >>> jnp.polyder(p, m=2)
    Array([ 12., -10.], dtype=float32)
  polyderz'm' argument of jnp.polyderr   z$Order of derivative must be positiver+   Nr-   )r!   r   rH   r   r   r#   rG   r	   r<   r,   r?   r]   r   )r'   r   rJ   r   s       r5   r   r   0  s    J )Q
X^Q0MNN!!!$$&%UU
;
<
<<!VVL!SZZu{333BJ?1EK(((BJ789=a 	sseDDbDk	!!r7   )trim_leading_zerosr   c                  t          d| |           t          | |          \  }}~ ~|rHt          |          dk    st          |          dk    r"t          |d          t          |d          }}t          |          dk    rt	          dg|j                  }t          |          dk    rt	          dg|j                  }t          ||d          S )	a]  Returns the product of two polynomials.

  JAX implementation of :func:`numpy.polymul`.

  Args:
    a1: 1D array of polynomial coefficients.
    a2: 1D array of polynomial coefficients.
    trim_leading_zeros: Default is ``False``. If ``True`` removes the leading
      zeros in the return value to match the result of numpy. But prevents the
      function from being able to be used in compiled code. Due to differences
      in accumulation of floating point arithmetic errors, the cutoff for values
      to be considered zero may lead to inconsistent results between NumPy and
      JAX, and even between different JAX backends. The result may lead to
      inconsistent output shapes when ``trim_leading_zeros=True``.

  Returns:
    An array of the coefficients of the product of the two polynomials. The dtype
    of the output is always promoted to inexact.

  Note:
    :func:`jax.numpy.polymul` only accepts arrays as input unlike
    :func:`numpy.polymul` which accepts scalar inputs as well.

  See also:
    - :func:`jax.numpy.polyadd`: Computes the sum of two polynomials.
    - :func:`jax.numpy.polysub`: Computes the difference of two polynomials.
    - :func:`jax.numpy.polydiv`: Computes the quotient and remainder of polynomial
      division.

  Example:
    >>> x1 = np.array([2, 1, 0])
    >>> x2 = np.array([0, 5, 0, 3])
    >>> np.polymul(x1, x2)
    array([10,  5,  6,  3,  0])
    >>> jnp.polymul(x1, x2)
    Array([ 0., 10.,  5.,  6.,  3.,  0.], dtype=float32)

    If ``trim_leading_zeros=True``, the result matches with ``np.polymul``'s.

    >>> jnp.polymul(x1, x2, trim_leading_zeros=True)
    Array([10.,  5.,  6.,  3.,  0.], dtype=float32)

    For input arrays of dtype ``complex``:

    >>> x3 = np.array([2., 1+2j, 1-2j])
    >>> x4 = np.array([0, 5, 0, 3])
    >>> np.polymul(x3, x4)
    array([10. +0.j,  5.+10.j, 11.-10.j,  3. +6.j,  3. -6.j])
    >>> jnp.polymul(x3, x4)
    Array([ 0. +0.j, 10. +0.j,  5.+10.j, 11.-10.j,  3. +6.j,  3. -6.j],      dtype=complex64)
    >>> jnp.polymul(x3, x4, trim_leading_zeros=True)
    Array([10. +0.j,  5.+10.j, 11.-10.j,  3. +6.j,  3. -6.j], dtype=complex64)
  polymulr.   f)trimr   r+   r   rt   )r!   r#   r<   r   r   r,   r   )r   r   r   r   r   s        r5   r   r   b  s    l )R$$$)"b11.&&" PS[[1__FaS111:f33O3O3OFF[[AaS---F[[AaS---F	&&v	.	.	..r7   uvtuple[Array, Array]c               X   t          d| |           t          | |          \  }}~ ~t          |          dz
  }t          |          dz
  }d|d         z  }t          t	          ||z
  dz   d          |j                  }t          d||z
  dz             D ]Y}	|||	         z  }
|j        |	                             |
          }|j        |	|	|z   dz            	                    |
 |z            }Z|r6t          |t          t          |j                  j                  d          }||fS )a  Returns the quotient and remainder of polynomial division.

  JAX implementation of :func:`numpy.polydiv`.

  Args:
    u: Array of dividend polynomial coefficients.
    v: Array of divisor polynomial coefficients.
    trim_leading_zeros: Default is ``False``. If ``True`` removes the leading
      zeros in the return value to match the result of numpy. But prevents the
      function from being able to be used in compiled code. Due to differences
      in accumulation of floating point arithmetic errors, the cutoff for values
      to be considered zero may lead to inconsistent results between NumPy and
      JAX, and even between different JAX backends. The result may lead to
      inconsistent output shapes when ``trim_leading_zeros=True``.

  Returns:
    A tuple of quotient and remainder arrays. The dtype of the output is always
    promoted to inexact.

  Note:
    :func:`jax.numpy.polydiv` only accepts arrays as input unlike
    :func:`numpy.polydiv` which accepts scalar inputs as well.

  See also:
    - :func:`jax.numpy.polyadd`: Computes the sum of two polynomials.
    - :func:`jax.numpy.polysub`: Computes the difference of two polynomials.
    - :func:`jax.numpy.polymul`: Computes the product of two polynomials.

  Example:
    >>> x1 = jnp.array([5, 7, 9])
    >>> x2 = jnp.array([4, 1])
    >>> np.polydiv(x1, x2)
    (array([1.25  , 1.4375]), array([7.5625]))
    >>> jnp.polydiv(x1, x2)
    (Array([1.25  , 1.4375], dtype=float32), Array([0.    , 0.    , 7.5625], dtype=float32))

    If ``trim_leading_zeros=True``, the result matches with ``np.polydiv``'s.

    >>> jnp.polydiv(x1, x2, trim_leading_zeros=True)
    (Array([1.25  , 1.4375], dtype=float32), Array([7.5625], dtype=float32))
  polydivr.   r;   r   r+   r   )tolr   )r!   r#   r<   r   maxr,   rw   r1   r2   r   r   r   r   r[   )r   r   r   u_arrv_arrr   nrh   qr|   ds              r5   r   r     s+   T )Q"""'1--,%	%jj1n!	%jj1n!
uQx-%3q1uqy!$$ek:::!AaCE?? , ,aaA	QAAHQqs1uW!!1"U(++EE N5d5+=+=+A&B&BMMME	
E/r7   c                l    t          d| |           t          | |          \  } }t          | |           S )a  Returns the difference of two polynomials.

  JAX implementation of :func:`numpy.polysub`.

  Args:
    a1: Array of minuend polynomial coefficients.
    a2: Array of subtrahend polynomial coefficients.

  Returns:
    An array containing the coefficients of the difference of two polynomials.

  Note:
    :func:`jax.numpy.polysub` only accepts arrays as input unlike
    :func:`numpy.polysub` which accepts scalar inputs as well.

  See also:
    - :func:`jax.numpy.polyadd`: Computes the sum of two polynomials.
    - :func:`jax.numpy.polymul`: Computes the product of two polynomials.
    - :func:`jax.numpy.polydiv`: Computes the quotient and remainder of polynomial
      division.

  Example:
    >>> x1 = jnp.array([2, 3])
    >>> x2 = jnp.array([5, 4, 1])
    >>> jnp.polysub(x1, x2)
    Array([-5, -2,  2], dtype=int32)

    >>> x3 = jnp.array([[2, 3, 1]])
    >>> x4 = jnp.array([[5, 7, 3],
    ...                 [8, 2, 6]])
    >>> jnp.polysub(x3, x4)
    Array([[-5, -7, -3],
           [-6,  1, -5]], dtype=int32)

    >>> x5 = jnp.array([1, 3, 5])
    >>> x6 = jnp.array([[5, 7, 9],
    ...                 [8, 6, 4]])
    >>> jnp.polysub(x5, x6)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    ValueError: Cannot broadcast to shape with fewer dimensions: arr_shape=(2, 3) shape=(2,)
    >>> x7 = jnp.array([2])
    >>> jnp.polysub(x6, x7)
    Array([[5, 7, 9],
           [6, 4, 2]], dtype=int32)
  polysub)r!   r"   r   )r   r   s     r5   r   r     s<    ` )R$$$"b!!&"b	bS		r7   )r'   r%   r(   r%   )r'   r%   r8   r9   r(   r%   )r'   r&   rC   rD   r(   r%   )NFNF)rO   r&   rP   r&   rK   rI   rL   rQ   r   rD   rR   rS   rM   rD   r(   rT   )ro   r&   r(   r%   )r'   r&   rO   r&   r}   rI   r(   r%   )r   r&   r   r&   r(   r%   )r.   N)r'   r&   r   rI   r|   r   r(   r%   rs   )r'   r&   r   rI   r(   r%   )r   r&   r   r&   r   rD   r(   r%   )r   r&   r   r&   r   rD   r(   r   )<
__future__r   	functoolsr   r   numpyr?   jaxr   r   jax._srcr   r   jax._src.numpy.lax_numpyr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   jax._src.numpy.ufuncsr   r   r   jax._src.numpy.reductionsr   rv   r    jax._src.numpy.utilr!   r"   r#   r$   jax._src.typingr%   r&   r6   rB   rA   rV   rq   r   r   r   r   r   r   r   rr   r7   r5   <module>r      s   # " " " " "                                   # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # = < < < < < < < < < ) ) ) ) ) ) ! ! ! ! ! !E E E E E E E E E E E E , , , , , , , ,     e e e e 04 87 87 87 87 87 87v 	=>>>HLHMg g g g ?>gT N N N Nb 	xj)))9; ; ; ; ; ; *);| 54 54 54 54p 	f%%%@; @; @; @; &%@;F 	f%%%." ." ." ." &%."b IN ?/ ?/ ?/ ?/ ?/ ?/D GL 8 8 8 8 8 8v 1 1 1 1 1 1r7   