
    (ph                        S r SSKrSSKrSSKJrJrJrJrJrJ	r	J
r
JrJrJrJrJrJrJrJrJrJrJr  SSKJrJr  SSKJr  SSKJr  SSKJr  / SQr\R>                  " \R@                  S	S
9r \" \5      r!\" \5      r"\" \5      r#S r$S r%\ " \%5      S 5       r&\ " \%5      S 5       r'\\" S	5      SS\(S4SS.S jj5       5       r)\ " 5       " \)5      r*S#S jr+\ " \+5      S$S j5       r,\ " \+5      S$S j5       r-\\" S	5      SS\(4SS.S jj5       5       r.\ " 5       " \.5      r/S#S jr0\ " \05      S$S j5       r1\ " \05      S$S j5       r2S%S jr3\ " \35      S&S j5       r4  S'S jr5\ " \55      S(S j5       r6\" S	5      S$S j5       r7\" S	5      S)S j5       r8S#S jr9\ " \95      S$S  j5       r:\" S	5      S)S! j5       r;\ " \95      S$S" j5       r<g)*z,Basic functions for manipulating 2d arrays

    N)
asanyarrayarangezerosgreater_equalmultiplyonesasarraywhereint8int16int32int64intpemptypromote_typesdiagonalnonzeroindices)set_array_function_like_doc
set_module)	overrides)iinfo)broadcast_to)diagdiagflateyefliplrflipudtritriutrilvanderhistogram2dmask_indicestril_indicestril_indices_fromtriu_indicestriu_indices_fromnumpy)modulec                 "   U[         R                  ::  a  U [         R                  :  a  [        $ U[        R                  ::  a  U [        R                  :  a  [
        $ U[        R                  ::  a  U [        R                  :  a  [        $ [        $ )z"get small int that fits the range )	i1maxminr   i2r   i4r   r   )lowhighs     H/var/www/html/venv/lib/python3.13/site-packages/numpy/lib/twodim_base.py_min_intr4   !   sU    rvv~#-rvv~#-rvv~#-L    c                     U 4$ N ms    r3   _flip_dispatcherr;   ,   	    4Kr5   c                 f    [        U 5      n U R                  S:  a  [        S5      eU SS2SSS24   $ )a  
Reverse the order of elements along axis 1 (left/right).

For a 2-D array, this flips the entries in each row in the left/right
direction. Columns are preserved, but appear in a different order than
before.

Parameters
----------
m : array_like
    Input array, must be at least 2-D.

Returns
-------
f : ndarray
    A view of `m` with the columns reversed.  Since a view
    is returned, this operation is :math:`\mathcal O(1)`.

See Also
--------
flipud : Flip array in the up/down direction.
flip : Flip array in one or more dimensions.
rot90 : Rotate array counterclockwise.

Notes
-----
Equivalent to ``m[:,::-1]`` or ``np.flip(m, axis=1)``.
Requires the array to be at least 2-D.

Examples
--------
>>> A = np.diag([1.,2.,3.])
>>> A
array([[1.,  0.,  0.],
       [0.,  2.,  0.],
       [0.,  0.,  3.]])
>>> np.fliplr(A)
array([[0.,  0.,  1.],
       [0.,  2.,  0.],
       [3.,  0.,  0.]])

>>> A = np.random.randn(2,3,5)
>>> np.all(np.fliplr(A) == A[:,::-1,...])
True

   zInput must be >= 2-d.Nr   ndim
ValueErrorr9   s    r3   r   r   0   s7    ` 	1Avvz011Q"W:r5   c                 b    [        U 5      n U R                  S:  a  [        S5      eU SSS2S4   $ )a  
Reverse the order of elements along axis 0 (up/down).

For a 2-D array, this flips the entries in each column in the up/down
direction. Rows are preserved, but appear in a different order than before.

Parameters
----------
m : array_like
    Input array.

Returns
-------
out : array_like
    A view of `m` with the rows reversed.  Since a view is
    returned, this operation is :math:`\mathcal O(1)`.

See Also
--------
fliplr : Flip array in the left/right direction.
flip : Flip array in one or more dimensions.
rot90 : Rotate array counterclockwise.

Notes
-----
Equivalent to ``m[::-1, ...]`` or ``np.flip(m, axis=0)``.
Requires the array to be at least 1-D.

Examples
--------
>>> A = np.diag([1.0, 2, 3])
>>> A
array([[1.,  0.,  0.],
       [0.,  2.,  0.],
       [0.,  0.,  3.]])
>>> np.flipud(A)
array([[0.,  0.,  3.],
       [0.,  2.,  0.],
       [1.,  0.,  0.]])

>>> A = np.random.randn(2,3,5)
>>> np.all(np.flipud(A) == A[::-1,...])
True

>>> np.flipud([1,2])
array([2, 1])

   zInput must be >= 1-d.Nr?   .r@   r9   s    r3   r   r   f   s7    d 	1Avvz011TrT3Y<r5   C)likec          	          Ub  [        XPXX4S9$ Uc  U n[        X4X4S9nX!:  a  U$ [        R                  " U5      n[        R                  " U5      nUS:  a  UnOU* U-  nSUSX-
   R                  USUS-   2'   U$ )ah  
Return a 2-D array with ones on the diagonal and zeros elsewhere.

Parameters
----------
N : int
  Number of rows in the output.
M : int, optional
  Number of columns in the output. If None, defaults to `N`.
k : int, optional
  Index of the diagonal: 0 (the default) refers to the main diagonal,
  a positive value refers to an upper diagonal, and a negative value
  to a lower diagonal.
dtype : data-type, optional
  Data-type of the returned array.
order : {'C', 'F'}, optional
    Whether the output should be stored in row-major (C-style) or
    column-major (Fortran-style) order in memory.

    .. versionadded:: 1.14.0
${ARRAY_FUNCTION_LIKE}

    .. versionadded:: 1.20.0

Returns
-------
I : ndarray of shape (N,M)
  An array where all elements are equal to zero, except for the `k`-th
  diagonal, whose values are equal to one.

See Also
--------
identity : (almost) equivalent function
diag : diagonal 2-D array from a 1-D array specified by the user.

Examples
--------
>>> np.eye(2, dtype=int)
array([[1, 0],
       [0, 1]])
>>> np.eye(3, k=1)
array([[0.,  1.,  0.],
       [0.,  0.,  1.],
       [0.,  0.,  0.]])

N)Mkdtypeorder)rJ   rK   r   rD   )_eye_with_liker   operatorindexflat)NrH   rI   rJ   rK   rF   r:   is           r3   r   r      s    b duJJyqfE/Av 	qAqAAvR1HAdqsGLLAaCHr5   c                     U 4$ r7   r8   )vrI   s     r3   _diag_dispatcherrT      r<   r5   c                 <   [        U 5      n U R                  n[        U5      S:X  aR  US   [        U5      -   n[	        X34U R
                  5      nUS:  a  UnOU* U-  nXSX1-
   R                  USUS-   2'   U$ [        U5      S:X  a  [        X5      $ [        S5      e)a  
Extract a diagonal or construct a diagonal array.

See the more detailed documentation for ``numpy.diagonal`` if you use this
function to extract a diagonal and wish to write to the resulting array;
whether it returns a copy or a view depends on what version of numpy you
are using.

Parameters
----------
v : array_like
    If `v` is a 2-D array, return a copy of its `k`-th diagonal.
    If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th
    diagonal.
k : int, optional
    Diagonal in question. The default is 0. Use `k>0` for diagonals
    above the main diagonal, and `k<0` for diagonals below the main
    diagonal.

Returns
-------
out : ndarray
    The extracted diagonal or constructed diagonal array.

See Also
--------
diagonal : Return specified diagonals.
diagflat : Create a 2-D array with the flattened input as a diagonal.
trace : Sum along diagonals.
triu : Upper triangle of an array.
tril : Lower triangle of an array.

Examples
--------
>>> x = np.arange(9).reshape((3,3))
>>> x
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

>>> np.diag(x)
array([0, 4, 8])
>>> np.diag(x, k=1)
array([1, 5])
>>> np.diag(x, k=-1)
array([3, 7])

>>> np.diag(np.diag(x))
array([[0, 0, 0],
       [0, 4, 0],
       [0, 0, 8]])

rD   r   Nr>   zInput must be 1- or 2-d.)	r   shapelenabsr   rJ   rO   r   rB   )rS   rI   snresrQ   s         r3   r   r      s    n 	1A	A
1v{aDQKQFAGG$6AqA!"DQS	qv!A#v
	Q1~344r5   c                     U R                   n[        U 5      R                  5       n [	        U 5      nU[        U5      -   n[        XD4U R                  5      nUS:  a  [        SXA-
  [        S9nXa-   Xd-  -   nO[        SXA-   [        S9nXfU-
  U-  -   nXR                  U'   U(       d  U$ U" U5      $ ! [         a    Sn Nf = f)a  
Create a two-dimensional array with the flattened input as a diagonal.

Parameters
----------
v : array_like
    Input data, which is flattened and set as the `k`-th
    diagonal of the output.
k : int, optional
    Diagonal to set; 0, the default, corresponds to the "main" diagonal,
    a positive (negative) `k` giving the number of the diagonal above
    (below) the main.

Returns
-------
out : ndarray
    The 2-D output array.

See Also
--------
diag : MATLAB work-alike for 1-D and 2-D arrays.
diagonal : Return specified diagonals.
trace : Sum along diagonals.

Examples
--------
>>> np.diagflat([[1,2], [3,4]])
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0],
       [0, 0, 0, 4]])

>>> np.diagflat([1,2], 1)
array([[0, 1, 0],
       [0, 0, 2],
       [0, 0, 0]])

Nr   rJ   )__array_wrap__AttributeErrorr	   ravelrW   rX   r   rJ   r   r   rO   )rS   rI   wraprY   rZ   r[   rQ   fis           r3   r   r   2  s    P 	
AAA	CF
A

 C	Q1ac&SW1ac&!QwYHHRL
9  s   B2 2C Cc                    Ub  [        X@XUS9$ Uc  U n[        R                  " [        U [	        SU 5      S9[        U* X-
  [	        U* X-
  5      S95      nUR                  USS9nU$ )a  
An array with ones at and below the given diagonal and zeros elsewhere.

Parameters
----------
N : int
    Number of rows in the array.
M : int, optional
    Number of columns in the array.
    By default, `M` is taken equal to `N`.
k : int, optional
    The sub-diagonal at and below which the array is filled.
    `k` = 0 is the main diagonal, while `k` < 0 is below it,
    and `k` > 0 is above.  The default is 0.
dtype : dtype, optional
    Data type of the returned array.  The default is float.
${ARRAY_FUNCTION_LIKE}

    .. versionadded:: 1.20.0

Returns
-------
tri : ndarray of shape (N, M)
    Array with its lower triangle filled with ones and zero elsewhere;
    in other words ``T[i,j] == 1`` for ``j <= i + k``, 0 otherwise.

Examples
--------
>>> np.tri(3, 5, 2, dtype=int)
array([[1, 1, 1, 0, 0],
       [1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1]])

>>> np.tri(3, 5, -1)
array([[0.,  0.,  0.,  0.,  0.],
       [1.,  0.,  0.,  0.,  0.],
       [1.,  1.,  0.,  0.,  0.]])

)rH   rI   rJ   r   r]   F)copy)_tri_with_liker   outerr   r4   astype)rP   rH   rI   rJ   rF   r:   s         r3   r   r   n  sx    T du==yF1HQN;"A2qs(A2qu2EF	HA 	
U#AHr5   c                     U 4$ r7   r8   )r:   rI   s     r3   _trilu_dispatcherri     r<   r5   c                     [        U 5      n [        U R                  SS U[        S.6n[	        X [        SU R                  5      5      $ )a  
Lower triangle of an array.

Return a copy of an array with elements above the `k`-th diagonal zeroed.
For arrays with ``ndim`` exceeding 2, `tril` will apply to the final two
axes.

Parameters
----------
m : array_like, shape (..., M, N)
    Input array.
k : int, optional
    Diagonal above which to zero elements.  `k = 0` (the default) is the
    main diagonal, `k < 0` is below it and `k > 0` is above.

Returns
-------
tril : ndarray, shape (..., M, N)
    Lower triangle of `m`, of same shape and data-type as `m`.

See Also
--------
triu : same thing, only for the upper triangle

Examples
--------
>>> np.tril([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
array([[ 0,  0,  0],
       [ 4,  0,  0],
       [ 7,  8,  0],
       [10, 11, 12]])

>>> np.tril(np.arange(3*4*5).reshape(3, 4, 5))
array([[[ 0,  0,  0,  0,  0],
        [ 5,  6,  0,  0,  0],
        [10, 11, 12,  0,  0],
        [15, 16, 17, 18,  0]],
       [[20,  0,  0,  0,  0],
        [25, 26,  0,  0,  0],
        [30, 31, 32,  0,  0],
        [35, 36, 37, 38,  0]],
       [[40,  0,  0,  0,  0],
        [45, 46,  0,  0,  0],
        [50, 51, 52,  0,  0],
        [55, 56, 57, 58,  0]]])

NrI   rJ   rD   r   r   rV   boolr
   r   rJ   r:   rI   masks      r3   r!   r!     s>    b 	1A.D%177+,,r5   c                     [        U 5      n [        U R                  SS US-
  [        S.6n[	        U[        SU R                  5      U 5      $ )an  
Upper triangle of an array.

Return a copy of an array with the elements below the `k`-th diagonal
zeroed. For arrays with ``ndim`` exceeding 2, `triu` will apply to the
final two axes.

Please refer to the documentation for `tril` for further details.

See Also
--------
tril : lower triangle of an array

Examples
--------
>>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 0,  8,  9],
       [ 0,  0, 12]])

>>> np.triu(np.arange(3*4*5).reshape(3, 4, 5))
array([[[ 0,  1,  2,  3,  4],
        [ 0,  6,  7,  8,  9],
        [ 0,  0, 12, 13, 14],
        [ 0,  0,  0, 18, 19]],
       [[20, 21, 22, 23, 24],
        [ 0, 26, 27, 28, 29],
        [ 0,  0, 32, 33, 34],
        [ 0,  0,  0, 38, 39]],
       [[40, 41, 42, 43, 44],
        [ 0, 46, 47, 48, 49],
        [ 0,  0, 52, 53, 54],
        [ 0,  0,  0, 58, 59]]])

rk   NrD   rl   rm   ro   s      r3   r    r      sD    L 	1A!40DuQ(!,,r5   c                     U 4$ r7   r8   )xrP   
increasings      r3   _vander_dispatcherru     r<   r5   c                    [        U 5      n U R                  S:w  a  [        S5      eUc  [        U 5      n[	        [        U 5      U4[        U R                  [        5      S9nU(       d  USS2SSS24   OUnUS:  a	  SUSS2S4'   US:  a:  U SS2S4   USS2SS24'   [        R                  " USS2SS24   USS2SS24   SS9  U$ )a  
Generate a Vandermonde matrix.

The columns of the output matrix are powers of the input vector. The
order of the powers is determined by the `increasing` boolean argument.
Specifically, when `increasing` is False, the `i`-th output column is
the input vector raised element-wise to the power of ``N - i - 1``. Such
a matrix with a geometric progression in each row is named for Alexandre-
Theophile Vandermonde.

Parameters
----------
x : array_like
    1-D input array.
N : int, optional
    Number of columns in the output.  If `N` is not specified, a square
    array is returned (``N = len(x)``).
increasing : bool, optional
    Order of the powers of the columns.  If True, the powers increase
    from left to right, if False (the default) they are reversed.

    .. versionadded:: 1.9.0

Returns
-------
out : ndarray
    Vandermonde matrix.  If `increasing` is False, the first column is
    ``x^(N-1)``, the second ``x^(N-2)`` and so forth. If `increasing` is
    True, the columns are ``x^0, x^1, ..., x^(N-1)``.

See Also
--------
polynomial.polynomial.polyvander

Examples
--------
>>> x = np.array([1, 2, 3, 5])
>>> N = 3
>>> np.vander(x, N)
array([[ 1,  1,  1],
       [ 4,  2,  1],
       [ 9,  3,  1],
       [25,  5,  1]])

>>> np.column_stack([x**(N-1-i) for i in range(N)])
array([[ 1,  1,  1],
       [ 4,  2,  1],
       [ 9,  3,  1],
       [25,  5,  1]])

>>> x = np.array([1, 2, 3, 5])
>>> np.vander(x)
array([[  1,   1,   1,   1],
       [  8,   4,   2,   1],
       [ 27,   9,   3,   1],
       [125,  25,   5,   1]])
>>> np.vander(x, increasing=True)
array([[  1,   1,   1,   1],
       [  1,   2,   4,   8],
       [  1,   3,   9,  27],
       [  1,   5,  25, 125]])

The determinant of a square Vandermonde matrix is the product
of the differences between the values of the input vector:

>>> np.linalg.det(np.vander(x))
48.000000000000043 # may vary
>>> (5-3)*(5-2)*(5-1)*(3-2)*(3-1)*(2-1)
48

rD   z.x must be a one-dimensional array or sequence.Nr]   r?   r   )outaxis)
r	   rA   rB   rW   r   r   rJ   intr   
accumulate)rs   rP   rt   rS   tmps        r3   r"   r"     s    R 	
Avv{IJJyFs1vqkqww!<=A&!AttG*AC1uAqD	1uq$wZAqrE
C12JC12JQ?Hr5   c              #      #    U v   Uv    [        U5      nUS:X  a  U S h  vN   OUv   Uv   g ! [         a    Sn N(f = f N 7f)NrD   r>   )rW   	TypeError)rs   ybinsrangedensityweightsrP   s          r3   _histogram2d_dispatcherr   q  sR     
G
GI 	Av

M   	s-   	A1 AAAA AA  Ac                     SSK Jn  [        U 5      [        U5      :w  a  [        S5      e [        U5      nUS:w  a  US:w  a  [        U5      =pX/nU" X/X#XE5      u  pXS   US   4$ ! [         a    Sn N@f = f)a/  
Compute the bi-dimensional histogram of two data samples.

Parameters
----------
x : array_like, shape (N,)
    An array containing the x coordinates of the points to be
    histogrammed.
y : array_like, shape (N,)
    An array containing the y coordinates of the points to be
    histogrammed.
bins : int or array_like or [int, int] or [array, array], optional
    The bin specification:

      * If int, the number of bins for the two dimensions (nx=ny=bins).
      * If array_like, the bin edges for the two dimensions
        (x_edges=y_edges=bins).
      * If [int, int], the number of bins in each dimension
        (nx, ny = bins).
      * If [array, array], the bin edges in each dimension
        (x_edges, y_edges = bins).
      * A combination [int, array] or [array, int], where int
        is the number of bins and array is the bin edges.

range : array_like, shape(2,2), optional
    The leftmost and rightmost edges of the bins along each dimension
    (if not specified explicitly in the `bins` parameters):
    ``[[xmin, xmax], [ymin, ymax]]``. All values outside of this range
    will be considered outliers and not tallied in the histogram.
density : bool, optional
    If False, the default, returns the number of samples in each bin.
    If True, returns the probability *density* function at the bin,
    ``bin_count / sample_count / bin_area``.
weights : array_like, shape(N,), optional
    An array of values ``w_i`` weighing each sample ``(x_i, y_i)``.
    Weights are normalized to 1 if `density` is True. If `density` is
    False, the values of the returned histogram are equal to the sum of
    the weights belonging to the samples falling into each bin.

Returns
-------
H : ndarray, shape(nx, ny)
    The bi-dimensional histogram of samples `x` and `y`. Values in `x`
    are histogrammed along the first dimension and values in `y` are
    histogrammed along the second dimension.
xedges : ndarray, shape(nx+1,)
    The bin edges along the first dimension.
yedges : ndarray, shape(ny+1,)
    The bin edges along the second dimension.

See Also
--------
histogram : 1D histogram
histogramdd : Multidimensional histogram

Notes
-----
When `density` is True, then the returned histogram is the sample
density, defined such that the sum over bins of the product
``bin_value * bin_area`` is 1.

Please note that the histogram does not follow the Cartesian convention
where `x` values are on the abscissa and `y` values on the ordinate
axis.  Rather, `x` is histogrammed along the first dimension of the
array (vertical), and `y` along the second dimension of the array
(horizontal).  This ensures compatibility with `histogramdd`.

Examples
--------
>>> from matplotlib.image import NonUniformImage
>>> import matplotlib.pyplot as plt

Construct a 2-D histogram with variable bin width. First define the bin
edges:

>>> xedges = [0, 1, 3, 5]
>>> yedges = [0, 2, 3, 4, 6]

Next we create a histogram H with random bin content:

>>> x = np.random.normal(2, 1, 100)
>>> y = np.random.normal(1, 1, 100)
>>> H, xedges, yedges = np.histogram2d(x, y, bins=(xedges, yedges))
>>> # Histogram does not follow Cartesian convention (see Notes),
>>> # therefore transpose H for visualization purposes.
>>> H = H.T

:func:`imshow <matplotlib.pyplot.imshow>` can only display square bins:

>>> fig = plt.figure(figsize=(7, 3))
>>> ax = fig.add_subplot(131, title='imshow: square bins')
>>> plt.imshow(H, interpolation='nearest', origin='lower',
...         extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]])
<matplotlib.image.AxesImage object at 0x...>

:func:`pcolormesh <matplotlib.pyplot.pcolormesh>` can display actual edges:

>>> ax = fig.add_subplot(132, title='pcolormesh: actual edges',
...         aspect='equal')
>>> X, Y = np.meshgrid(xedges, yedges)
>>> ax.pcolormesh(X, Y, H)
<matplotlib.collections.QuadMesh object at 0x...>

:class:`NonUniformImage <matplotlib.image.NonUniformImage>` can be used to
display actual bin edges with interpolation:

>>> ax = fig.add_subplot(133, title='NonUniformImage: interpolated',
...         aspect='equal', xlim=xedges[[0, -1]], ylim=yedges[[0, -1]])
>>> im = NonUniformImage(ax, interpolation='bilinear')
>>> xcenters = (xedges[:-1] + xedges[1:]) / 2
>>> ycenters = (yedges[:-1] + yedges[1:]) / 2
>>> im.set_data(xcenters, ycenters, H)
>>> ax.add_image(im)
>>> plt.show()

It is also possible to construct a 2-D histogram without specifying bin
edges:

>>> # Generate non-symmetric test data
>>> n = 10000
>>> x = np.linspace(1, 100, n)
>>> y = 2*np.log(x) + np.random.rand(n) - 0.5
>>> # Compute 2d histogram. Note the order of x/y and xedges/yedges
>>> H, yedges, xedges = np.histogram2d(y, x, bins=20)

Now we can plot the histogram using
:func:`pcolormesh <matplotlib.pyplot.pcolormesh>`, and a
:func:`hexbin <matplotlib.pyplot.hexbin>` for comparison.

>>> # Plot histogram using pcolormesh
>>> fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True)
>>> ax1.pcolormesh(xedges, yedges, H, cmap='rainbow')
>>> ax1.plot(x, 2*np.log(x), 'k-')
>>> ax1.set_xlim(x.min(), x.max())
>>> ax1.set_ylim(y.min(), y.max())
>>> ax1.set_xlabel('x')
>>> ax1.set_ylabel('y')
>>> ax1.set_title('histogram2d')
>>> ax1.grid()

>>> # Create hexbin plot for comparison
>>> ax2.hexbin(x, y, gridsize=20, cmap='rainbow')
>>> ax2.plot(x, 2*np.log(x), 'k-')
>>> ax2.set_title('hexbin')
>>> ax2.set_xlim(x.min(), x.max())
>>> ax2.set_xlabel('x')
>>> ax2.grid()

>>> plt.show()
r   )histogramddz"x and y must have the same length.rD   r>   )r)   r   rW   rB   r}   r	   )rs   r~   r   r   r   r   r   rP   xedgesyedgeshistedgess               r3   r#   r#     s    p "
1vQ=>>I 	Av!q&!$-'qfd7DKDq58##  s   A( (A76A7c                 P    [        X 4[        5      nU" X25      n[        US:g  5      $ )a  
Return the indices to access (n, n) arrays, given a masking function.

Assume `mask_func` is a function that, for a square array a of size
``(n, n)`` with a possible offset argument `k`, when called as
``mask_func(a, k)`` returns a new array with zeros in certain locations
(functions like `triu` or `tril` do precisely this). Then this function
returns the indices where the non-zero values would be located.

Parameters
----------
n : int
    The returned indices will be valid to access arrays of shape (n, n).
mask_func : callable
    A function whose call signature is similar to that of `triu`, `tril`.
    That is, ``mask_func(x, k)`` returns a boolean array, shaped like `x`.
    `k` is an optional argument to the function.
k : scalar
    An optional argument which is passed through to `mask_func`. Functions
    like `triu`, `tril` take a second argument that is interpreted as an
    offset.

Returns
-------
indices : tuple of arrays.
    The `n` arrays of indices corresponding to the locations where
    ``mask_func(np.ones((n, n)), k)`` is True.

See Also
--------
triu, tril, triu_indices, tril_indices

Notes
-----
.. versionadded:: 1.4.0

Examples
--------
These are the indices that would allow you to access the upper triangular
part of any 3x3 array:

>>> iu = np.mask_indices(3, np.triu)

For example, if `a` is a 3x3 array:

>>> a = np.arange(9).reshape(3, 3)
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> a[iu]
array([0, 1, 2, 4, 5, 8])

An offset can be passed also to the masking function.  This gets us the
indices starting on the first diagonal right of the main one:

>>> iu1 = np.mask_indices(3, np.triu, 1)

with which we now extract only three elements:

>>> a[iu1]
array([1, 2, 5])

r   )r   ry   r   )rZ   	mask_funcrI   r:   as        r3   r$   r$   ,  s*    D 	aVSA!A16?r5   c                 p   ^ [        XU[        S9m[        U4S j[        TR                  SS9 5       5      $ )a  
Return the indices for the lower-triangle of an (n, m) array.

Parameters
----------
n : int
    The row dimension of the arrays for which the returned
    indices will be valid.
k : int, optional
    Diagonal offset (see `tril` for details).
m : int, optional
    .. versionadded:: 1.9.0

    The column dimension of the arrays for which the returned
    arrays will be valid.
    By default `m` is taken equal to `n`.


Returns
-------
inds : tuple of arrays
    The indices for the triangle. The returned tuple contains two arrays,
    each with the indices along one dimension of the array.

See also
--------
triu_indices : similar function, for upper-triangular.
mask_indices : generic function accepting an arbitrary mask function.
tril, triu

Notes
-----
.. versionadded:: 1.4.0

Examples
--------
Compute two different sets of indices to access 4x4 arrays, one for the
lower triangular part starting at the main diagonal, and one starting two
diagonals further right:

>>> il1 = np.tril_indices(4)
>>> il2 = np.tril_indices(4, 2)

Here is how they can be used with a sample array:

>>> a = np.arange(16).reshape(4, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

Both for indexing:

>>> a[il1]
array([ 0,  4,  5, ..., 13, 14, 15])

And for assigning values:

>>> a[il1] = -1
>>> a
array([[-1,  1,  2,  3],
       [-1, -1,  6,  7],
       [-1, -1, -1, 11],
       [-1, -1, -1, -1]])

These cover almost the whole array (two diagonals right of the main one):

>>> a[il2] = -10
>>> a
array([[-10, -10, -10,   3],
       [-10, -10, -10, -10],
       [-10, -10, -10, -10],
       [-10, -10, -10, -10]])

rl   c              3   V   >#    U  H  n[        UTR                  5      T   v   M      g 7fr7   r   rV   .0indstri_s     r3   	<genexpr>tril_indices.<locals>.<genexpr>  (      ?=T dDJJ/5=   &)Tsparser   rn   tupler   rV   rZ   rI   r:   r   s      @r3   r%   r%   s  s9    \ qq%D ?$TZZ=? ? ?r5   c                     U 4$ r7   r8   arrrI   s     r3   _trilu_indices_form_dispatcherr     s	    6Mr5   c                     U R                   S:w  a  [        S5      e[        U R                  S   XR                  S   S9$ )a  
Return the indices for the lower-triangle of arr.

See `tril_indices` for full details.

Parameters
----------
arr : array_like
    The indices will be valid for square arrays whose dimensions are
    the same as arr.
k : int, optional
    Diagonal offset (see `tril` for details).

Examples
--------

Create a 4 by 4 array.

>>> a = np.arange(16).reshape(4, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

Pass the array to get the indices of the lower triangular elements.

>>> trili = np.tril_indices_from(a)
>>> trili
(array([0, 1, 1, 2, 2, 2, 3, 3, 3, 3]), array([0, 0, 1, 0, 1, 2, 0, 1, 2, 3]))

>>> a[trili]
array([ 0,  4,  5,  8,  9, 10, 12, 13, 14, 15])

This is syntactic sugar for tril_indices().

>>> np.tril_indices(a.shape[0])
(array([0, 1, 1, 2, 2, 2, 3, 3, 3, 3]), array([0, 0, 1, 0, 1, 2, 0, 1, 2, 3]))

Use the `k` parameter to return the indices for the lower triangular array
up to the k-th diagonal.

>>> trili1 = np.tril_indices_from(a, k=1)
>>> a[trili1]
array([ 0,  1,  4,  5,  6,  8,  9, 10, 11, 12, 13, 14, 15])

See Also
--------
tril_indices, tril, triu_indices_from

Notes
-----
.. versionadded:: 1.4.0

r>   input array must be 2-drk   r?   rI   r:   )rA   rB   r%   rV   r   s     r3   r&   r&     s9    r xx1}233		"iim<<r5   c                 x   ^ [        XUS-
  [        S9) m[        U4S j[        TR                  SS9 5       5      $ )a  
Return the indices for the upper-triangle of an (n, m) array.

Parameters
----------
n : int
    The size of the arrays for which the returned indices will
    be valid.
k : int, optional
    Diagonal offset (see `triu` for details).
m : int, optional
    .. versionadded:: 1.9.0

    The column dimension of the arrays for which the returned
    arrays will be valid.
    By default `m` is taken equal to `n`.


Returns
-------
inds : tuple, shape(2) of ndarrays, shape(`n`)
    The indices for the triangle. The returned tuple contains two arrays,
    each with the indices along one dimension of the array.  Can be used
    to slice a ndarray of shape(`n`, `n`).

See also
--------
tril_indices : similar function, for lower-triangular.
mask_indices : generic function accepting an arbitrary mask function.
triu, tril

Notes
-----
.. versionadded:: 1.4.0

Examples
--------
Compute two different sets of indices to access 4x4 arrays, one for the
upper triangular part starting at the main diagonal, and one starting two
diagonals further right:

>>> iu1 = np.triu_indices(4)
>>> iu2 = np.triu_indices(4, 2)

Here is how they can be used with a sample array:

>>> a = np.arange(16).reshape(4, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

Both for indexing:

>>> a[iu1]
array([ 0,  1,  2, ..., 10, 11, 15])

And for assigning values:

>>> a[iu1] = -1
>>> a
array([[-1, -1, -1, -1],
       [ 4, -1, -1, -1],
       [ 8,  9, -1, -1],
       [12, 13, 14, -1]])

These cover only a small part of the whole array (two diagonals right
of the main one):

>>> a[iu2] = -10
>>> a
array([[ -1,  -1, -10, -10],
       [  4,  -1,  -1, -10],
       [  8,   9,  -1,  -1],
       [ 12,  13,  14,  -1]])

rD   rl   c              3   V   >#    U  H  n[        UTR                  5      T   v   M      g 7fr7   r   r   s     r3   r   triu_indices.<locals>.<genexpr>[  r   r   Tr   r   r   s      @r3   r'   r'   	  s@    ` AT**D ?$TZZ=? ? ?r5   c                     U R                   S:w  a  [        S5      e[        U R                  S   XR                  S   S9$ )a  
Return the indices for the upper-triangle of arr.

See `triu_indices` for full details.

Parameters
----------
arr : ndarray, shape(N, N)
    The indices will be valid for square arrays.
k : int, optional
    Diagonal offset (see `triu` for details).

Returns
-------
triu_indices_from : tuple, shape(2) of ndarray, shape(N)
    Indices for the upper-triangle of `arr`.

Examples
--------

Create a 4 by 4 array.

>>> a = np.arange(16).reshape(4, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

Pass the array to get the indices of the upper triangular elements.

>>> triui = np.triu_indices_from(a)
>>> triui
(array([0, 0, 0, 0, 1, 1, 1, 2, 2, 3]), array([0, 1, 2, 3, 1, 2, 3, 2, 3, 3]))

>>> a[triui]
array([ 0,  1,  2,  3,  5,  6,  7, 10, 11, 15])

This is syntactic sugar for triu_indices().

>>> np.triu_indices(a.shape[0])
(array([0, 0, 0, 0, 1, 1, 1, 2, 2, 3]), array([0, 1, 2, 3, 1, 2, 3, 2, 3, 3]))

Use the `k` parameter to return the indices for the upper triangular array
from the k-th diagonal.

>>> triuim1 = np.triu_indices_from(a, k=1)
>>> a[triuim1]
array([ 1,  2,  3,  6,  7, 11])


See Also
--------
triu_indices, triu, tril_indices_from

Notes
-----
.. versionadded:: 1.4.0

r>   r   rk   r?   r   )rA   rB   r'   rV   r   s     r3   r(   r(   _  s9    | xx1}233		"iim<<r5   r7   )r   )NN)NF)NNNN)
   NNN)r   N)=__doc__	functoolsrM   numpy.core.numericr   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   numpy.core.overridesr   r   
numpy.corer   r   numpy.lib.stride_tricksr   __all__partialarray_function_dispatchr,   r/   r0   r4   r;   r   r   floatr   rL   rT   r   r   r   re   ri   r!   r    ru   r"   r   r#   r$   r%   r   r&   r'   r(   r8   r5   r3   <module>r      s        
 I    0@ $++%%g7  4[
5\
5\ )*2 +2j )*4 +4n GQe3 @ @  @F )*3/ )*D5 +D5N )*8 +8v GQe 4T 4  4n )*3/ *+3- ,3-l *+(- ,(-V
 +,W -Wt BF$($ 01e$ 2e$P GC CL GP? P?f 78:= 9:=z GR? R?j 78?= 9?=r5   