
    \ci
                     T   d Z dZg dZddlZddlZddlZddlZddlZddlZ	ddl
mZmZmZ ddlmZ ddlmZmZmZmZ dd	lmZ dd
lmZmZ ddlmZmZ ddlmZmZ ddl m!Z!m"Z" ddl#m$Z$m%Z% ddl&m'Z'm(Z( dddZ)d Z*d5dZ+d6dZ,dddeddZ-dddefdZ.d7dZ/d8de0dddZ1d9dZ2dde0dfdZ3d8d Z4d8d!Z5d" Z6d# Z7d:d$Z8d:d%Z9d:d&Z:ddd'd(Z;d;d)Z<d:d*Z= ed+          d,d-dddd.d/            Z>	 	 d<d0Z? ed+d12          	 	 d=d3            Z@ ed+d12          d>d4            ZAdS )?z2Functions to construct sparse matrices and arrays
zrestructuredtext en)spdiagseyeidentitykronkronsumhstackvstackbmatrandrandomdiags
block_diagdiags_arrayblock_array	eye_arrayrandom_arrayexpand_dimspermute_dimsswapaxes    N)check_random_staterng_integers_transition_to_rng)_NoValue   )upcastget_index_dtypeisscalarlike	isintlike)
csr_hstack)
bsr_matrix	bsr_array)
coo_matrix	coo_array)
csc_matrix	csc_array)
csr_matrix	csr_array)
dia_matrix	dia_array)issparsesparray)axisc                  t          |          st          d| d          |dk    r|n|| j        z   dz   }|dk     s|| j        k    rt          d| d| j         d          |                     d          }t	          j        |j        d                   }|j        d	|         |fz   |j        |d	         z   |_        |j        d	|         d
z   |j        |d	         z   |_        | j	        dk    r| j
        |_
        |S )a  
    Add trivial axes to an array. Shape gets a ``1`` inserted at position `axis`.

    Parameters
    ----------
    A : sparse array

    axis : int
        Position in the expanded axes where the new axis (or axes) is placed.
        For a dimension ``N`` array, a valid axis is an integer on the
        closed-interval ``[-N-1, N]``. Negative values work from the end of
        the shape. ``0`` prepends an axis, as does ``-N-1``. ``-1`` appends
        an axis, as does ``N``. The new axis has shape ``1`` and indices are
        created with the value ``0``.

    Returns
    -------
    out : sparse array
        A expanded copy output in COO format with the same dtype as `A`.

    Raises
    ------
    ValueError
        If provided a non-integer or out of range ``[-N-1, N]`` axis,
        where ``N`` is ``A.ndim``.

    Examples
    --------
    >>> from scipy.sparse import csr_array, expand_dims
    >>> A = csr_array([[1, 2], [2, 0]])
    >>> A.shape
    (2, 2)
    >>> expand_dims(A, axis=1).shape
    (2, 1, 2)

    zInvalid axis z. Must be an integer.r   r   z for N=z. Must be in [-N-1, N].TcopyNr   coo)r   
ValueErrorndimtocoonp
zeros_likecoordsshape_shapeformathas_canonical_format)Ar,   idxnewA	new_coords        g/var/www/html/mdtn/previsions/meteo_cartes/venv/lib/python3.11/site-packages/scipy/sparse/_construct.pyr   r       s   J T?? FDDDDEEE!))$$!2C
Qww#,,UUUafUUUVVV777Ddk!n--I+dsd#yl2T[5FFDK*TcT"T)DJstt,<<DKx5$%$:!K    c                 l   t          j        | j                  }	 |||g         |||g<   nj# t          $ r]}t	          |          }|                    d                              dd          d         }t          d| d| j                   d}~ww xY wt          |          }t          | |d	          S )
a  Interchange two axes of an array.

    Parameters
    ----------
    A : sparse array
    axis1 : int
        First axis.
    axis2 : int
        Second axis.

    Returns
    -------
    a_swapped : sparse array in COO format
        A copy of the input array with the two identified axes swapped.

    Raises
    ------
    ValueError
        If provided a non-integer or out of range ``[-N, N-1]`` axis,
        where ``N`` is ``A.ndim``.

    Examples
    --------
    >>> from scipy.sparse import coo_array, swapaxes
    >>> A = coo_array([[[1, 2, 3], [2, 0, 0]]])
    >>> A.shape
    (1, 2, 3)
    >>> swapaxes(A, 1, 2).shape
    (1, 3, 2)

    zindex z axis r   r   zInvalid axis: z ndim=NT)axesr/   )
r5   aranger3   
IndexErrorstrremoveprefixsplitr2   tupler   )r<   axis1axis2rC   errmsgs         r@   r   r   U   s    @ 9QVD?#UEN3eU^ ? ? ?#hhx((..x;;A>=#==QV==>>>? ;;D40000s   + 
BABBFc                 &     j         }|&t          t          |          ddd                   }n-t          |          |k    rt	          d| d j                    t          |t          t          f          s`t          j        t          j	        t          |                    t          j                  st          dt          |                     |f}g }|D ]_}t          |          st          d| d          |dk     r||z  }|dk     s||k    rt	          d	          |                    |           `t          |          t          t          |                    k    rt	          d
          |}|t          t          |                    k    r|s n                                 S                      |           t           fd|D                        _        t           fd|D                        _        d _         S )a  Permute the axes of the sparse array `A` to the order `axes`.

    Parameters
    ----------
    A : sparse array
    axes : tuple or list of ints, optional
        If specified, it must be a tuple or list which contains a permutation
        of ``[0, 1, ..., N-1]`` where ``N`` is ``A.ndim``. The ith
        axis of the returned array will correspond to the axis numbered ``axes[i]``
        of the input. If not specified, defaults to ``range(A.ndim)[::-1]``,
        which reverses the order of the axes.
    copy : bool, optional (default: False)
        Whether to return the permutation as a copy. If False, an in-place
        permutation is provided if possible depending on format.

    Returns
    -------
    out : sparse array in COO format
        A copy of `A` with permuted axes.

    Raises
    ------
    ValueError
        If provided a non-integer or out of range ``[-N, N-1]`` axis,
        where ``N`` is ``A.ndim``.

    Examples
    --------
    >>> from scipy.sparse import coo_array, permute_dims
    >>> A = coo_array([[[1, 2, 3], [2, 0, 0]]])
    >>> A.shape
    (1, 2, 3)
    >>> permute_dims(A, axes=(1, 2, 0)).shape
    (2, 3, 1)

    NzIncorrect number of axes: z instead of z+axis must be an integer/tuple of ints, not z axis must be an integer. (given )r   zaxis out of range for ndimzduplicate value in axisr.   c              3   2   K   | ]}j         |         V  d S Nr8   .0r=   r<   s     r@   	<genexpr>zpermute_dims.<locals>.<genexpr>   s)      22cQWS\222222rA   c              3   2   K   | ]}j         |         V  d S rR   r7   rT   s     r@   rV   zpermute_dims.<locals>.<genexpr>   s)      33sQXc]333333rA   F)r3   rI   rangelenr2   
isinstancelistr5   
issubdtypedtypetypeinteger	TypeErrorr   appendsetr/   r4   r9   r7   r;   )r<   rC   r/   r3   
canon_axesaxs   `     r@   r   r      s   J 6D|U4[[2&''	Td		PdPPPPQQQ dUDM**  }RXd4jj112:>> 	XV$t**VVWWWwJ  }} 	FDrDDDEEE66$JB66R4ZZ9:::"
:#c*oo....2333DtE$KK    *qq!&&((*	TA2222T22222AH3333d33333AH"AHrA   c                     ||t          | d                   x}}n||\  }}t          | |f||f                              |          S )a  
    Return a sparse matrix from diagonals.

    .. warning::

        This function returns a sparse matrix -- not a sparse array.
        You are encouraged to use `dia_array` to take advantage
        of the sparse array functionality. (See Notes below.)

    Parameters
    ----------
    data : array_like
        Matrix diagonals stored row-wise
    diags : sequence of int or an int
        Diagonals to set:

        * k = 0  the main diagonal
        * k > 0  the kth upper diagonal
        * k < 0  the kth lower diagonal
    m, n : int, tuple, optional
        Shape of the result. If `n` is None and `m` is a given tuple,
        the shape is this tuple. If omitted, the matrix is square and
        its shape is ``len(data[0])``.
    format : str, optional
        Format of the result. By default (format=None) an appropriate sparse
        matrix format is returned. This choice is subject to change.

    Returns
    -------
    new_matrix : sparse matrix
        `dia_matrix` format with values in ``data`` on diagonals from ``diags``.

    Notes
    -----
    This function can be replaced by an equivalent call to `dia_matrix`
    as::

        dia_matrix((data, diags), shape=(m, n)).asformat(format)

    See Also
    --------
    diags_array : more convenient form of this function
    diags : matrix version of diags_array
    dia_matrix : the sparse DIAgonal format.

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.sparse import spdiags
    >>> data = np.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])
    >>> diags = np.array([0, -1, 2])
    >>> spdiags(data, diags, 4, 4).toarray()
    array([[1, 0, 3, 0],
           [1, 2, 0, 4],
           [0, 2, 3, 0],
           [0, 0, 3, 4]])

    Nr   rS   )rZ   r(   asformat)datar   mnr:   s        r@   r   r      s[    v 	yQYDGAA	
1tUmAq6222;;FCCCrA   )offsetsr8   r:   r^   c               D   t          |          rMt          |           dk    st          | d                   rt          j        |           g} n6t	          d          t          t          t          j        |                     } t          j        |          }t          |           t          |          k    rt	          d          |<t          | d                   t          t          |d                             z   f}|t          j	        |  }n|t          u rt          j        t          j        |            }t          j	        |  }t          j        dk     rddi}d}n)dt          j                            t$                    fi}d	}||k    r"t'          j        d
| d| d|z   t*          fi | |\  t-          fd|D                       }t-          d|          }t          j        t          |          |f|          }	t1                    }
t3          |           D ]\  }}||         }t-          d|          }t1          |z   |z
  |
          }|dk     rt	          d| d| d          	 |dd|f         |	||||z   f<   h# t          $ rY}t          |          |k    r@t          |          dk    r-t	          d| dt          |           d| d d d          | d}~ww xY wt5          |	|ff                              |          S )a  
    Construct a sparse array from diagonals.

    Parameters
    ----------
    diagonals : sequence of array_like
        Sequence of arrays containing the array diagonals,
        corresponding to `offsets`.
    offsets : sequence of int or an int, optional
        Diagonals to set (repeated offsets are not allowed):
          - k = 0  the main diagonal (default)
          - k > 0  the kth upper diagonal
          - k < 0  the kth lower diagonal
    shape : tuple of int, optional
        Shape of the result. If omitted, a square array large enough
        to contain the diagonals is returned.
    format : {"dia", "csr", "csc", "lil", ...}, optional
        Matrix format of the result. By default (format=None) an
        appropriate sparse array format is returned. This choice is
        subject to change.
    dtype : dtype, optional
        Data type of the array.  If `dtype` is None, the output
        data type is determined by the data type of the input diagonals.

        Up until SciPy 1.19, the default behavior will be to return an array
        with an inexact (floating point) data type.  In particular, integer
        input will be converted to double precision floating point.  This
        behavior is deprecated, and in SciPy 1.19, the default behavior
        will be changed to return an array with the same data type as the
        input diagonals.  To adopt this behavior before version 1.19, use
        `dtype=None`.

    Returns
    -------
    new_array : dia_array
        `dia_array` holding the values in `diagonals` offset from the main diagonal
        as indicated in `offsets`.

    Notes
    -----
    Repeated diagonal offsets are disallowed.

    The result from ``diags_array`` is the sparse equivalent of::

        np.diag(diagonals[0], offsets[0])
        + ...
        + np.diag(diagonals[k], offsets[k])

    ``diags_array`` differs from `dia_array` in the way it handles off-diagonals.
    Specifically, `dia_array` assumes the data input includes padding
    (ignored values) at the start/end of the rows for positive/negative
    offset, while ``diags_array`` assumes the input data has no padding.
    Each value in the input `diagonals` is used.

    .. versionadded:: 1.11

    See Also
    --------
    dia_array : constructor for the sparse DIAgonal format.

    Examples
    --------
    >>> from scipy.sparse import diags_array
    >>> diagonals = [[1.0, 2.0, 3.0, 4.0], [1.0, 2.0, 3.0], [1.0, 2.0]]
    >>> diags_array(diagonals, offsets=[0, -1, 2]).toarray()
    array([[1., 0., 1., 0.],
           [1., 2., 0., 2.],
           [0., 2., 3., 0.],
           [0., 0., 3., 4.]])

    Broadcasting of scalars is supported (but shape needs to be
    specified):

    >>> diags_array([1.0, -2.0, 1.0], offsets=[-1, 0, 1], shape=(4, 4)).toarray()
    array([[-2.,  1.,  0.,  0.],
           [ 1., -2.,  1.,  0.],
           [ 0.,  1., -2.,  1.],
           [ 0.,  0.,  1., -2.]])


    If only one diagonal is wanted (as in `numpy.diag`), the following
    works as well:

    >>> diags_array([1.0, 2.0, 3.0], offsets=1).toarray()
    array([[ 0.,  1.,  0.,  0.],
           [ 0.,  0.,  2.,  0.],
           [ 0.,  0.,  0.,  3.],
           [ 0.,  0.,  0.,  0.]])

    r   z*Different number of diagonals and offsets.N)      
stacklevel   z
Note: In Python 3.11, this warning can be generated by a call of scipy.sparse.diags(), but the code indicated in the warning message will refer to an internal call of scipy.sparse.diags_array(). If that happens, check your code for the use of diags().skip_file_prefixes zInput has data type z", but the output has been cast to z.  In the future, the output data type will match the input. To avoid this warning, set the `dtype` parameter to `None` to have the output dtype match the input, or set it to the desired output data type.c                 ^    g | ])}t          |z   |z
            t          d |          z   *S r   )minmax)rU   offsetri   rj   s     r@   
<listcomp>zdiags_array.<locals>.<listcomp>  sH     $ $ $ VQZ((3q&>>9 $ $ $rA   r^   zOffset z (index z) out of bounds.r   zDiagonal length (index : z at offset z") does not agree with array size (z, z).rS   )r   rZ   r5   
atleast_1dr2   r\   mapabsintresult_typer   r^   common_typesysversion_infoospathdirname__file__warningswarnFutureWarningrv   zerosru   	enumerater)   rg   )	diagonalsrk   r8   r:   r^   future_dtypewarn_kwargs	extra_msgMdata_arrKjdiagonalrw   klengtheri   rj   s                    @@r@   r   r     s   x G 8y>>Q,y|"<"<y112IIIJJJR]I6677	mG$$G 9~~W%%EFFF }	!C
OO 4 44A }	*	(		 344~y1g%%'+K8II 0"'//(2K2K1MNKI\!!M,| , ,, , ,
  	 	 	 	 	 DAq $ $ $ $ $"$ $ $ 	% 	%AAq		AxWq)777HAq		A ++  86NNQZVQ//A::IvIIqIIIJJJ	&.s7F7{&;HQ!F(
]## 	 	 	8}}&&3x==A+=+= Ta T T3x== T T%T TIJT TNOT T T   	 h(A777@@HHHs   =J
K7AK22K7c                 l    t          | |||          }t          |                              |          S )a_  
    Construct a sparse matrix from diagonals.

    .. warning::

        This function returns a sparse matrix -- not a sparse array.
        You are encouraged to use `diags_array` to take advantage
        of the sparse array functionality.

    Parameters
    ----------
    diagonals : sequence of array_like
        Sequence of arrays containing the matrix diagonals,
        corresponding to `offsets`.
    offsets : sequence of int or an int, optional
        Diagonals to set (repeated offsets are not allowed):
          - k = 0  the main diagonal (default)
          - k > 0  the kth upper diagonal
          - k < 0  the kth lower diagonal
    shape : tuple of int, optional
        Shape of the result. If omitted, a square matrix large enough
        to contain the diagonals is returned.
    format : {"dia", "csr", "csc", "lil", ...}, optional
        Matrix format of the result. By default (format=None) an
        appropriate sparse matrix format is returned. This choice is
        subject to change.
    dtype : dtype, optional
        Data type of the matrix.  If `dtype` is None, the output
        data type is determined by the data type of the input diagonals.

        Up until SciPy 1.19, the default behavior will be to return a matrix
        with an inexact (floating point) data type.  In particular, integer
        input will be converted to double precision floating point.  This
        behavior is deprecated, and in SciPy 1.19, the default behavior
        will be changed to return a matrix with the same data type as the
        input diagonals.  To adopt this behavior before version 1.19, use
        `dtype=None`.

    Returns
    -------
    new_matrix : dia_matrix
        `dia_matrix` holding the values in `diagonals` offset from the main diagonal
        as indicated in `offsets`.

    Notes
    -----
    Repeated diagonal offsets are disallowed.

    The result from ``diags`` is the sparse equivalent of::

        np.diag(diagonals[0], offsets[0])
        + ...
        + np.diag(diagonals[k], offsets[k])

    ``diags`` differs from `dia_matrix` in the way it handles off-diagonals.
    Specifically, `dia_matrix` assumes the data input includes padding
    (ignored values) at the start/end of the rows for positive/negative
    offset, while ``diags`` assumes the input data has no padding.
    Each value in the input `diagonals` is used.

    .. versionadded:: 0.11

    See Also
    --------
    spdiags : construct matrix from diagonals
    diags_array : construct sparse array instead of sparse matrix

    Examples
    --------
    >>> from scipy.sparse import diags
    >>> diagonals = [[1.0, 2.0, 3.0, 4.0], [1.0, 2.0, 3.0], [1.0, 2.0]]
    >>> diags(diagonals, [0, -1, 2]).toarray()
    array([[1., 0., 1., 0.],
           [1., 2., 0., 2.],
           [0., 2., 3., 0.],
           [0., 0., 3., 4.]])

    Broadcasting of scalars is supported (but shape needs to be
    specified):

    >>> diags([1.0, -2.0, 1.0], [-1, 0, 1], shape=(4, 4)).toarray()
    array([[-2.,  1.,  0.,  0.],
           [ 1., -2.,  1.,  0.],
           [ 0.,  1., -2.,  1.],
           [ 0.,  0.,  1., -2.]])


    If only one diagonal is wanted (as in `numpy.diag`), the following
    works as well:

    >>> diags([1.0, 2.0, 3.0], 1).toarray()
    array([[ 0.,  1.,  0.,  0.],
           [ 0.,  0.,  2.,  0.],
           [ 0.,  0.,  0.,  3.],
           [ 0.,  0.,  0.,  0.]])

    rk   r8   r^   )r   r(   rg   )r   rk   r8   r:   r^   r<   s         r@   r   r     s5    D 	Iwe5IIIAa==!!&)))rA   dc                 (    t          | | ||          S )a[  Identity matrix in sparse format

    Returns an identity matrix with shape ``(n, n)`` using a given
    sparse format and dtype. This differs from `eye_array` in
    that it has a square shape with ones only on the main diagonal.
    It is thus the multiplicative identity. `eye_array` allows
    rectangular shapes and the diagonal can be offset from the main one.

    .. warning::

        This function returns a sparse matrix -- not a sparse array.
        You are encouraged to use `eye_array` to take advantage
        of the sparse array functionality.

    Parameters
    ----------
    n : int
        Shape of the identity matrix.
    dtype : dtype, optional
        Data type of the matrix
    format : str, optional
        Sparse format of the result, e.g., format="csr", etc.

    Returns
    -------
    new_matrix : sparse matrix
        A square sparse matrix with ones on the main diagonal and zeros elsewhere.

    See Also
    --------
    eye_array : Sparse array of chosen shape with ones on a specified diagonal.
    eye : Sparse matrix of chosen shape with ones on a specified diagonal.

    Examples
    --------
    >>> import scipy as sp
    >>> sp.sparse.identity(3).toarray()
    array([[ 1.,  0.,  0.],
           [ 0.,  1.,  0.],
           [ 0.,  0.,  1.]])
    >>> sp.sparse.identity(3, dtype='int8', format='dia')
    <DIAgonal sparse matrix of dtype 'int8'
        with 3 stored elements (1 diagonals) and shape (3, 3)>
    >>> sp.sparse.eye_array(3, dtype='int8', format='dia')
    <DIAgonal sparse array of dtype 'int8'
        with 3 stored elements (1 diagonals) and shape (3, 3)>

    )r^   r:   )r   )rj   r^   r:   s      r@   r   r   #  s    b q!50000rA   )r   r^   r:   c                (    t          | ||||          S )ao  Sparse array of chosen shape with ones on the kth diagonal and zeros elsewhere.

    Return a sparse array with ones on diagonal.
    Specifically a sparse array (m x n) where the kth diagonal
    is all ones and everything else is zeros.

    Parameters
    ----------
    m : int
        Number of rows requested.
    n : int, optional
        Number of columns. Default: `m`.
    k : int, optional
        Diagonal to place ones on. Default: 0 (main diagonal).
    dtype : dtype, optional
        Data type of the array
    format : str, optional (default: "dia")
        Sparse format of the result, e.g., format="csr", etc.

    Returns
    -------
    new_array : sparse array
        Sparse array of chosen shape with ones on the kth diagonal and zeros elsewhere.

    Examples
    --------
    >>> import numpy as np
    >>> import scipy as sp
    >>> sp.sparse.eye_array(3).toarray()
    array([[ 1.,  0.,  0.],
           [ 0.,  1.,  0.],
           [ 0.,  0.,  1.]])
    >>> sp.sparse.eye_array(3, dtype=np.int8)
    <DIAgonal sparse array of dtype 'int8'
        with 3 stored elements (1 diagonals) and shape (3, 3)>

    _eyeri   rj   r   r^   r:   s        r@   r   r   W  s    N 1a'''rA   Tc           
      J   |rt           }t          }t          }t          }	nt          }t
          }t          }t          }	|| }t          |           t          |          }} | |k    r|dk    r|dv rqt          |          }
t          j        |dz   |
          }t          j        ||
          }t          j        ||          }||d|         } ||||f||f          S |dk    rdt          |          }
t          j        ||
          }t          j        ||
          }t          j        ||          } ||||ff||f          S t          j        dt          dt          | |z   |                    f|          } |	||g| |f|                              |          S )Nr   )csrcscmaxvalr   ry   r1   r   )r'   r%   r#   r   r&   r$   r"   r   r~   r   r5   rD   onesrv   ru   rg   )ri   rj   r   r^   r:   
as_sparray
csr_sparse
csc_sparse
coo_sparsediags_sparse	idx_dtypeindptrindicesrh   clsrowcols                    r@   r   r     s    	


"


yq663q66qAAvv!q&&^##'q111IYqs)444Fi333G71E***D$Z88@C3gv.A777u__'q111I)AY///C)AY///C71E***D:tc3Z01a&9997As1c!a%mm,,-U;;;D<qc!QuEEENNvVVVrA   c                 *    t          | ||||d          S )aU  Sparse matrix of chosen shape with ones on the kth diagonal and zeros elsewhere.

    Returns a sparse matrix (m x n) where the kth diagonal
    is all ones and everything else is zeros.

    .. warning::

        This function returns a sparse matrix -- not a sparse array.
        You are encouraged to use `eye_array` to take advantage
        of the sparse array functionality.

    Parameters
    ----------
    m : int
        Number of rows in the matrix.
    n : int, optional
        Number of columns. Default: `m`.
    k : int, optional
        Diagonal to place ones on. Default: 0 (main diagonal).
    dtype : dtype, optional
        Data type of the matrix.
    format : str, optional
        Sparse format of the result, e.g., format="csr", etc.

    Returns
    -------
    new_matrix : sparse matrix
        Sparse matrix of chosen shape with ones on the kth diagonaland zeros elsewhere.

    See Also
    --------
    eye_array : Sparse array of chosen shape with ones on a specified diagonal.

    Examples
    --------
    >>> import numpy as np
    >>> import scipy as sp
    >>> sp.sparse.eye(3).toarray()
    array([[ 1.,  0.,  0.],
           [ 0.,  1.,  0.],
           [ 0.,  0.,  1.]])
    >>> sp.sparse.eye(3, dtype=np.int8)
    <DIAgonal sparse matrix of dtype 'int8'
        with 3 stored elements (1 diagonals) and shape (3, 3)>

    Fr   r   s        r@   r   r     s    ^ 1a...rA   c                 2   t          | t                    st          t                    rt          }t          }t          }nt
          }t          }t          } |          ||dk    rXj        dk    rLdj	        z  t          j        j                  k    r&t          | d          r| j        dk    r ||           } | j        dk    r || d          } | j        d         j        d         z  | j        d         j        d         z  f}| j	        dk    sj	        dk    r ||                              |          S                                 | j                            j                                      d	j        d         j        d                   }|z  } ||| j        | j        f|
          S n ||           } |t          u r9| j        d         j        d         z  | j        d         j        d         z  f}d}nk| j        j        z
  }|dk    r| j        nd| z  | j        z   }	|dk    rj        nd|z  j        z   }
t-          d t/          |	|
          D                       }| j	        dk    sj	        dk    r ||                              |          S | j                            j	                  }t1          | j        t5          |                    fd| j        D             }|dk     r@t7          j        |d                   gfdt;          | dz
            D             z   |z   }t/          |j         d         j                  D ]
\  }}||z  }fdt/          |j         d         j                  D             |j         d<   |                    d	j	                  j        z                                  } ||t-          |          f|
                              |          S )a)  Sparse representation of the Kronecker product of `A` and `B`

    Computes the Kronecker product, a composite sparse array
    made of blocks consisting of the second input array multiplied
    by each element of the first input array.

    Parameters
    ----------
    A : sparse or dense array
        first array of the product
    B : sparse or dense array
        second array of the product
    format : str, optional (default: 'bsr' or 'coo')
        format of the result (e.g. "csr")
        If None, choose 'bsr' for relatively dense 2D arrays and 'coo' for others

    Returns
    -------
    sparse matrix or array
        kronecker product in a sparse format. Returns a sparse matrix unless either
        `A` or `B` is a sparse array in which case returns a sparse array.

    Examples
    --------
    >>> import numpy as np
    >>> import scipy as sp
    >>> A = sp.sparse.csr_array(np.array([[0, 2], [5, 0]]))
    >>> B = sp.sparse.csr_array(np.array([[1, 2], [3, 4]]))
    >>> sp.sparse.kron(A, B).toarray()
    array([[ 0,  0,  2,  4],
           [ 0,  0,  6,  8],
           [ 5, 10,  0,  0],
           [15, 20,  0,  0]])

    >>> sp.sparse.kron(A, [[1, 2], [3, 4]]).toarray()
    array([[ 0,  0,  2,  4],
           [ 0,  0,  6,  8],
           [ 5, 10,  0,  0],
           [15, 20,  0,  0]])

    Nbsrrp   r3   Tr.   r   r   rO   rS   r0   c              3   &   K   | ]\  }}||z  V  d S rR    )rU   abs      r@   rV   zkron.<locals>.<genexpr>/  s*      EEtq!QUEEEEEErA   r   c                 l    g | ]0}t          j        |                               j                  1S )ry   )r5   asarrayrepeatnnz)rU   coBr   s     r@   rx   zkron.<locals>.<listcomp>8  s8    OOObj9---44QU;;OOOrA   c                 8    g | ]}                                 S r   r.   )rU   _new_cos     r@   rx   zkron.<locals>.<listcomp>;  s!    JJJqV[[]]JJJrA   c                 v    g | ]5\  }}|                     d j                  |z                                   6S )rO   )reshaper   ravel)rU   r   Bcor   s      r@   rx   zkron.<locals>.<listcomp>C  sT     H H H#B B..4;;== H H HrA   )r[   r+   r!   r'   r#   r    r&   r"   r3   r   mathprodr8   hasattrrg   toarrayrh   r   sizer   r   r   rI   zipr   r7   rv   r5   r6   rY   r   )r<   r   r:   
bsr_sparser   r   output_shaperh   	ndim_diffA_shapeB_shaper7   r   	B_shape_ir   r   s    `            @@r@   r   r     s   V !W  Aw!7!7  







1A 
6U??	!!%49QW#5#555q&!! 	QVq[[
1A6Q;;
14(((AGAJqwqz1171:agaj3HILuzzQUaZZ!z,//88@@@		A6==((00QWQZLLD!8D:tQY9NNNN  JqMM Z
QWQZ/agaj1HI		FQVO	&!^^!'')1Dqw1N&!^^!''	1AAG1KEEs7G/D/DEEEEEuzzQUaZZz,''00888 6==D\1B1BCCCIOOOOOahOOOF1}}vay))JJJJE9*q.4I4IJJJJVS VQVGHH-qw77  I
iH H H H'*616'((+;QX'F'FH H HFAF788 LLQU##af,3355D:tU6]]+<@@@II&QQQrA   c                     t          | t                    st          |t                    rt          }t          }nt          }t
          } ||           }  ||          }| j        dk    rt          d| j         d          |j        dk    rt          d|j         d          | j        d         | j        d         k    rt          d          |j        d         |j        d         k    rt          d          t          | j
        |j
                  } || j        d         |	          } ||j        d         |	          }t          || d
          }t          ||d
          }	||	z                       |          S )a  Kronecker sum of square sparse matrices `A` and `B`

    Kronecker sum of two sparse matrices is a sum of two Kronecker
    products ``kron(I_n,A) + kron(B,I_m)`` where `A` has shape ``(m, m)``
    and `B` has shape ``(n, n)`` and ``I_m`` and ``I_n`` are identity matrices
    of shape ``(m, m)`` and ``(n, n)``, respectively.

    Parameters
    ----------
    A : sparse matrix or array
        Square matrix
    B : sparse array or array
        Square matrix
    format : str
        format of the result (e.g. "csr")

    Returns
    -------
    sparse matrix or array
        kronecker sum in a sparse format. Returns a sparse matrix unless either
        `A` or `B` is a sparse array in which case returns a sparse array.

    Examples
    --------
    `kronsum` can be used to construct a finite difference discretization of the 2D
    Laplacian from a 1D discretization.

    >>> from scipy.sparse import diags_array, kronsum
    >>> from matplotlib import pyplot as plt
    >>> import numpy as np
    >>> ex = np.ones(10)
    >>> D_x = diags_array([ex, -ex[1:]], offsets=[0, -1])  # 1D first derivative
    >>> D_xx = D_x.T @ D_x  # 1D second derivative
    >>> L = kronsum(D_xx, D_xx)  # 2D Laplacian
    >>> plt.spy(L.toarray())
    >>> plt.show()

    rp   z#kronsum requires 2D inputs. `A` is zD.z#kronsum requires 2D inputs. `B` is r   r   zA is not squarezB is not squarery   r1   )r:   )r[   r+   r#   r   r"   r   r3   r2   r8   r   r^   r   rg   )
r<   r   r:   r   identity_sparser^   I_nI_mLRs
             r@   r   r   K  sy   P !W #Aw!7!7 #
#
"
1A
1Av{{IqvIIIJJJv{{IqvIIIJJJwqzQWQZ*+++wqzQWQZ*+++17AG$$E
/!'!*E
2
2
2C
/!'!*E
2
2
2CS!E"""AQE"""AEF###rA   c                    dk    rdnd}t          j        d | D                       }| d         j        |         }t          d | D             t	          |j        |                    }t          j        |j        |          }t          j        t          fd| D                       dz   |          } |d          }	d}
d}| D ]}|j        |         |k    rt          d|           |j	        ||||j	        j        z   <   ||j	        j        z  }t          |
|
|j                 z             }|j        d	d
         ||<   ||xx         |	z  cc<   |
|j                 z  }
|	|j        d
         z  }	|	|d
<   |r2dk    rt          |||f|
|f          S t          |||f||
f          S dk    rt          |||f|
|f          S t          |||f||
f          S )zh
    Stacking fast path for CSR/CSC matrices or arrays
    (i) vstack for CSR, (ii) hstack for CSC.
    r   r   c                     g | ]	}|j         
S r   rh   rU   r   s     r@   rx   z,_compressed_sparse_stack.<locals>.<listcomp>  s    222a16222rA   c                     g | ]	}|j         
S r   r   r   s     r@   rx   z,_compressed_sparse_stack.<locals>.<listcomp>  s    'A'A'AQ'A'A'ArA   )arraysr   ry   c              3   2   K   | ]}|j                  V  d S rR   _shape_as_2drU   r   r,   s     r@   rV   z+_compressed_sparse_stack.<locals>.<genexpr>  s*      ??1!..??????rA   z!incompatible dimensions for axis NrO   rS   )r5   concatenater   r   rv   r   emptysumr2   r   slicer   r&   r$   r'   r%   )blocksr,   return_spmatrix
other_axisrh   constant_dimr   r   r   last_indptrsum_dimsum_indicesr   idxss    `            r@   _compressed_sparse_stackr     so   
 aiiQJ>22622233D!9)*5L'A'A&'A'A'A'*49l'C'CE E EIhty	222GXc?????????!C9UUUF)A,,KGK 	$ 	$>*%55MMMNNN:;)K	667qy~%Wgt(<<==x}tt#1>$''qx|#F2J =199tWf5%,l$;= = = = tWf5%17$;= = = = qyy$0!(, 79 9 9 	9 $0!-w 79 9 9 	9rA   c                    t          |           }|dk    rt          d          |dk    r| d         S dk    rdndfd| D             }t          |          dk    rt          d d|           |\  }d | D             }t          j        d | D                       }t	          fd	| D                       }t	          d
 | D                       }t          |t          |dz
  |                    }	t          j        fd| D             |	          }
|j        dk    rt          j        ||	          }t          j        d | D             |	          }t          j	        |dz   |	          }t          j
        |          }t          j
        |          }t          |||
||||||	  	         nJt          j        |dz   |	          }t          j	        d|	          }t          j	        d|j                  }dk    r"| d                             |||f||f          S | d                             |||f||f          S )zs
    Stacking fast path for CSR/CSC matrices along the minor axis
    (i) hstack for CSR, (ii) vstack for CSC.
    r   zMissing block matricesr   c                 *    h | ]}|j                  S r   r   )rU   r   r   s     r@   	<setcomp>z*_stack_along_minor_axis.<locals>.<setcomp>  s     BBBaq~j1BBBrA   z"Mismatching dimensions along axis rz   c                     g | ]	}|j         
S r   r   r   s     r@   rx   z+_stack_along_minor_axis.<locals>.<listcomp>  s    ,,,18,,,rA   c                     g | ]	}|j         
S r   r   r   s     r@   rx   z+_stack_along_minor_axis.<locals>.<listcomp>  s    666!qv666rA   c              3   2   K   | ]}|j                  V  d S rR   r   r   s     r@   rV   z*_stack_along_minor_axis.<locals>.<genexpr>  s*      771!.&777777rA   c              3   >   K   | ]}t          |j                  V  d S rR   )rZ   r   r   s     r@   rV   z*_stack_along_minor_axis.<locals>.<genexpr>  s*      --c!)nn------rA   r   c                 *    g | ]}|j                  S r   r   r   s     r@   rx   z+_stack_along_minor_axis.<locals>.<listcomp>  s     CCCqanT2CCCrA   ry   c                     g | ]	}|j         
S r   )r   r   s     r@   rx   z+_stack_along_minor_axis.<locals>.<listcomp>  s    %@%@%@Aai%@%@%@rA   rS   )rZ   r2   r5   r   r   r   rv   arrayr   r   
empty_liker   r   r^   _csc_container_csr_container)r   r,   n_blocksother_axis_dimsr   indptr_listdata_catr   r   r   stack_dim_cat
indptr_catindices_catr   r   rh   r   s    `              @r@   _stack_along_minor_axisr    s   
 6{{H1}}12221}}ay aiiQJBBBB6BBBO
?a .j . .+. . / / 	/#ML -,V,,,K~66v66677H 777777777G
--f---
-
-CC!S4I4IJJJIHCCCCFCCC9UUUM}q^KyAAA
n%@%@%@%@%@	RRR,*)<<<-,,}X&&8\={H7D	* 	* 	* 	* ,*)<<<(1I...x000qyyay''w(?!(, 7 ( 9 9 	9 ay''w(?!-w 7 ( 9 9 	9rA   c                     t          j        | d          } t          d | j        D                       rt	          | g||          S t	          | g||d          S )a  
    Stack sparse matrices horizontally (column wise)

    Parameters
    ----------
    blocks
        sequence of sparse matrices with compatible shapes
    format : str
        sparse format of the result (e.g., "csr")
        by default an appropriate sparse matrix format is returned.
        This choice is subject to change.
    dtype : dtype, optional
        The data-type of the output matrix. If not given, the dtype is
        determined from that of `blocks`.

    Returns
    -------
    new_array : sparse matrix or array
        If any block in blocks is a sparse array, return a sparse array.
        Otherwise return a sparse matrix.

        If you want a sparse array built from blocks that are not sparse
        arrays, use ``block(hstack(blocks))`` or convert one block
        e.g. ``blocks[0] = csr_array(blocks[0])``.

    See Also
    --------
    vstack : stack sparse matrices vertically (row wise)

    Examples
    --------
    >>> from scipy.sparse import coo_matrix, hstack
    >>> A = coo_matrix([[1, 2], [3, 4]])
    >>> B = coo_matrix([[5], [6]])
    >>> hstack([A,B]).toarray()
    array([[1, 2, 5],
           [3, 4, 6]])

    objectry   c              3   @   K   | ]}t          |t                    V  d S rR   r[   r+   r   s     r@   rV   zhstack.<locals>.<genexpr>  ,      
7
7a:a!!
7
7
7
7
7
7rA   Tr   r5   r   anyflat_blockr   r:   r^   s      r@   r   r     sh    P Zh///F

7
76;
7
7
777 Evh...vhtDDDDrA   c                     t          j        | d          } t          d | j        D                       rt	          d | D             ||          S t	          d | D             ||d          S )a  
    Stack sparse arrays vertically (row wise)

    Parameters
    ----------
    blocks
        sequence of sparse arrays with compatible shapes
    format : str, optional
        sparse format of the result (e.g., "csr")
        by default an appropriate sparse array format is returned.
        This choice is subject to change.
    dtype : dtype, optional
        The data-type of the output array. If not given, the dtype is
        determined from that of `blocks`.

    Returns
    -------
    new_array : sparse matrix or array
        If any block in blocks is a sparse array, return a sparse array.
        Otherwise return a sparse matrix.

        If you want a sparse array built from blocks that are not sparse
        arrays, use ``block(vstack(blocks))`` or convert one block
        e.g. ``blocks[0] = csr_array(blocks[0])``.

    See Also
    --------
    hstack : stack sparse matrices horizontally (column wise)

    Examples
    --------
    >>> from scipy.sparse import coo_array, vstack
    >>> A = coo_array([[1, 2], [3, 4]])
    >>> B = coo_array([[5, 6]])
    >>> vstack([A, B]).toarray()
    array([[1, 2],
           [3, 4],
           [5, 6]])

    r  ry   c              3   @   K   | ]}t          |t                    V  d S rR   r  r   s     r@   rV   zvstack.<locals>.<genexpr>M  r  rA   c                     g | ]}|gS r   r   r   s     r@   rx   zvstack.<locals>.<listcomp>N      +++qs+++rA   c                     g | ]}|gS r   r   r   s     r@   rx   zvstack.<locals>.<listcomp>P  r  rA   Tr	  r
  r  s      r@   r   r   #  s    R Zh///F

7
76;
7
7
777 R++F+++VU;;;++F+++VUDQQQQrA   c                     t          j        | d          } t          d | j        D                       rt	          | ||          S t	          | ||d          S )a  
    Build a sparse array or matrix from sparse sub-blocks

    Note: `block_array` is preferred over ``bmat``. They are the same function
    except that ``bmat`` returns a deprecated sparse matrix when none of the
    inputs are sparse arrays.

    .. warning::

        This function returns a sparse matrix when no inputs are sparse arrays.
        You are encouraged to use `block_array` to take advantage
        of the sparse array functionality.

    Parameters
    ----------
    blocks : array_like
        Grid of sparse matrices with compatible shapes.
        An entry of None implies an all-zero matrix.
    format : {'bsr', 'coo', 'csc', 'csr', 'dia', 'dok', 'lil'}, optional
        The sparse format of the result (e.g. "csr"). By default an
        appropriate sparse matrix format is returned.
        This choice is subject to change.
    dtype : dtype, optional
        The data-type of the output matrix. If not given, the dtype is
        determined from that of `blocks`.

    Returns
    -------
    bmat : sparse matrix or array
        If any block in blocks is a sparse array, return a sparse array.
        Otherwise return a sparse matrix.

        If you want a sparse array built from blocks that are not sparse
        arrays, use ``block_array()``.

    See Also
    --------
    block_array

    Examples
    --------
    >>> from scipy.sparse import coo_array, bmat
    >>> A = coo_array([[1, 2], [3, 4]])
    >>> B = coo_array([[5], [6]])
    >>> C = coo_array([[7]])
    >>> bmat([[A, B], [None, C]]).toarray()
    array([[1, 2, 5],
           [3, 4, 6],
           [0, 0, 7]])

    >>> bmat([[A, None], [None, C]]).toarray()
    array([[1, 2, 0],
           [3, 4, 0],
           [0, 0, 7]])

    r  ry   c              3   @   K   | ]}t          |t                    V  d S rR   r  r   s     r@   rV   zbmat.<locals>.<genexpr>  r  rA   Tr	  r
  r  s      r@   r	   r	   S  sd    r Zh///F

7
76;
7
7
777 Cffe,,,ffeTBBBBrA   )r:   r^   c                $    t          | ||          S )a  
    Build a sparse array from sparse sub-blocks

    Parameters
    ----------
    blocks : array_like
        Grid of sparse arrays with compatible shapes.
        An entry of None implies an all-zero array.
    format : {'bsr', 'coo', 'csc', 'csr', 'dia', 'dok', 'lil'}, optional
        The sparse format of the result (e.g. "csr"). By default an
        appropriate sparse array format is returned.
        This choice is subject to change.
    dtype : dtype, optional
        The data-type of the output array. If not given, the dtype is
        determined from that of `blocks`.

    Returns
    -------
    block : sparse array

    See Also
    --------
    block_diag : specify blocks along the main diagonals
    diags : specify (possibly offset) diagonals

    Examples
    --------
    >>> from scipy.sparse import coo_array, block_array
    >>> A = coo_array([[1, 2], [3, 4]])
    >>> B = coo_array([[5], [6]])
    >>> C = coo_array([[7]])
    >>> block_array([[A, B], [None, C]]).toarray()
    array([[1, 2, 5],
           [3, 4, 6],
           [0, 0, 7]])

    >>> block_array([[A, None], [None, C]]).toarray()
    array([[1, 2, 0],
           [3, 4, 0],
           [0, 0, 7]])

    )r  r  s      r@   r   r     s    V &&%(((rA   c                 	    t          j         d            j        dk    rt          d           j        \  }}|dv rt          d  j        D                       rm|dk    r1 fdt          |          D              t          j         d           t           d d d	f         d	|          }||	                    |d
          }|S |dv rt          d  j        D                       rn|dk    r2 fdt          |          D             g t          j         d           t           d	d d f         d|          }||	                    |d
          }|S t          j
         j        t                    }t          j
        |t           j                  }t          j
        |t           j                  }	t          |          D ]}
t          |          D ]} |
|f         t           |
|f                   }| |
|f<   d||
|f<   ||
         d	k    r|j        d	         ||
<   nI||
         |j        d	         k    r2d|
 d|
 d| d|j        d	          d||
          d}t          |          |	|         d	k    r|j        d         |	|<   |	|         |j        d         k    r2d| d|
 d| d|j        d          d|	|          d}t          |          t          d  |         D                       }|d  |         D             }|r	t!          | nd }t          j        d	t          j        |                    }t          j        d	t          j        |	                    }|d         |d         f}t          j        ||          }t)          d  |         D             t+          |                    }t          j        ||          }t          j        ||          }d	}t          j        |          \  }}t/          ||          D ]\  }
} |
|f         }t1          |||j        z             }|j        ||<   t          j        |j        ||
         ||         |           t          j        |j        ||         ||         |           ||j        z  }|r(t=          |||ff|                              |          S t          |||ff|                              |          S ) Nr  ry   rp   zblocks must be 2-D)Nr   c              3   J   K   | ]}t          |          o
|j        d k    V  dS )r   Nr*   r:   r   s     r@   rV   z_block.<locals>.<genexpr>  s4      CC!HQKK-AH-CCCCCCrA   r   c                 F    g | ]}t          |d d f         d          gS )Nr   r  rU   r   r   s     r@   rx   z_block.<locals>.<listcomp>  s3    SSSQ.vad|Q??@SSSrA   r   Fr.   )Nr   c              3   J   K   | ]}t          |          o
|j        d k    V  dS )r   Nr  r   s     r@   rV   z_block.<locals>.<genexpr>  s4      EEAhqkk/ah%/EEEEEErA   c                 D    g | ]}t          d d |f         d          S )Nr   r  r  s     r@   rx   z_block.<locals>.<listcomp>  s0    RRRA.vaaad|Q??RRRrA   Tzblocks[z0,:] has incompatible row dimensions. Got blocks[,z].shape[0] == z, expected .z	blocks[:,z1] has incompatible column dimensions. Got blocks[z].shape[1] == c              3   $   K   | ]}|j         V  d S rR   )r   )rU   blocks     r@   rV   z_block.<locals>.<genexpr>  s$      88Eei888888rA   c                     g | ]	}|j         
S r   ry   )rU   blks     r@   rx   z_block.<locals>.<listcomp>  s    >>>Cci>>>rA   rO   c                 (    g | ]}|j         d          S rt   rX   r   s     r@   rx   z_block.<locals>.<listcomp>  s     I I I! I I IrA   r   )outr^   rS   ) r5   r   r3   r2   r8   allr  rY   r   astyper   boolint64r#   r   r   r   rb   cumsumr   r   rv   nonzeror   r   r   rh   addr   r   r"   rg   )r   r:   r^   r   r   Nr<   
block_maskbrow_lengthsbcol_lengthsir   rM   r   
all_dtypesrow_offsetscol_offsetsr8   rh   r   r   r   iijjr   r=   s   `                         r@   r  r    s   Zh///F{a-...
,CAa 	-CCv{CCCCC 	  q55SSSS%PQ((SSSFZh777F %VAAAqD\1oFFU++A
M
!
!
EEEEE
E
E " q55RRRRqRRRSFZh777F %VAqqqD\1oFFU++A&,d333J8ARX...L8ARX...L 1XX * *q 	* 	*Aac{&fQqSk**qs"&
1Q3?a''&'nQ&7LOO!!_q(999:Q : :)*: :-.: :>?nQ>O: :'3A: : :C %S//)?a''&'nQ&7LOO!!_q(999:q : :)*: :-.: :>?nQ>O: : (4A: : :C %S//)+	*. 88VJ%7888
8
8C}>>6*+=>>>
'1;
##t)Ary6677K)Ary6677K_k"o.E8Cu%%%D I IfZ6H I I I'*5zz3 3 3I
(3i
(
(
(C
(3i
(
(
(C
CZ
##FBB  11a4LCqu%%FS	
quk!n#c()DDDD
quk!n#c()DDDDqu L4#s,E:::CCFKKKdS#J'u555>>vFFFrA   c                    t          d | D                       rt          }nt          }g }g }g }g }d}d}	| D ]}
t          |
t          t
          j        z            r!t          t          j        |
                    }
t          |
          r|

                                }
|s@|
j        d         j        t          j        k    r |                    |
j        d                    |
j        \  }}|                    |
j        |z              |                    |
j        |	z              |                    |
j                   n|
j        \  }}t          j        t          j        ||z            |          \  }}|                    ||z              |                    ||	z              |                    |
                                           ||z  }|	|z  }	t/          |t1          ||	                    }t          j        ||          }t          j        ||          }t          j        |          }||	f} ||||ff||                              |          S )ab  
    Build a block diagonal sparse matrix or array from provided matrices.

    Parameters
    ----------
    mats : sequence of matrices or arrays
        Input matrices or arrays.
    format : str, optional
        The sparse format of the result (e.g., "csr"). If not given, the result
        is returned in "coo" format.
    dtype : dtype specifier, optional
        The data-type of the output. If not given, the dtype is
        determined from that of `blocks`.

    Returns
    -------
    res : sparse matrix or array
        If at least one input is a sparse array, the output is a sparse array.
        Otherwise the output is a sparse matrix.

    Notes
    -----

    .. versionadded:: 0.11.0

    See Also
    --------
    block_array
    diags_array

    Examples
    --------
    >>> from scipy.sparse import coo_array, block_diag
    >>> A = coo_array([[1, 2], [3, 4]])
    >>> B = coo_array([[5], [6]])
    >>> C = coo_array([[7]])
    >>> block_diag((A, B, C)).toarray()
    array([[1, 2, 0, 0],
           [3, 4, 0, 0],
           [0, 0, 5, 0],
           [0, 0, 6, 0],
           [0, 0, 0, 7]])

    c              3   @   K   | ]}t          |t                    V  d S rR   r  )rU   r   s     r@   rV   zblock_diag.<locals>.<genexpr>N  s,      
0
0a:a!!
0
0
0
0
0
0rA   r   r   ry   )r8   r^   )r  r#   r"   r[   r\   numbersNumberr5   
atleast_2dr*   r4   r7   r^   r*  rb   r   r   r   rh   r8   divmodrD   r   r   rv   r   rg   )matsr:   r^   	containerr   r   rh   
idx_arraysr_idxc_idxr   nrowsncolsa_rowa_colr   	new_shapes                    r@   r   r   !  sD   Z 
0
04
0
0
000 			
C
CDJEE  a$/11 	,"-**++AA;; 	#		A /!(1+"3rx"?"?!!!(1+...>LE5JJquu}%%%JJquu}%%%KK7LE59RYuU{%;%;UCCLE5JJuu}%%%JJuu}%%%KK		"""
3ue3D3DEEEI
.I
.
.
.C
.I
.
.
.C>$DI9dS#J'yFFFOOPVWWWrA   random_state{Gz?r1   )densityr:   r^   rngdata_samplerc                    t          | |||||          \  }}t          t          |                     t          fd|D                       }t	          ||f|                               |          S )a(  Return a sparse array of uniformly random numbers in [0, 1)

    Returns a sparse array with the given shape and density
    where values are generated uniformly randomly in the range [0, 1).

    Parameters
    ----------
    shape : tuple of int
        shape of the array.
    density : real, optional (default: 0.01)
        density of the generated matrix: density equal to one means a full
        matrix, density of 0 means a matrix with no non-zero items.
    format : str, optional (default: 'coo')
        sparse matrix format.
    dtype : dtype, optional (default: np.float64)
        type of the returned matrix values.
    rng : `numpy.random.Generator`, optional
        Pseudorandom number generator state. When `rng` is None, a new
        `numpy.random.Generator` is created using entropy from the
        operating system. Types other than `numpy.random.Generator` are
        passed to `numpy.random.default_rng` to instantiate a ``Generator``.

        This random state will be used for sampling ``indices`` (the sparsity
        structure), and by default for the data values too (see `data_sampler`).
    data_sampler : callable, optional (default depends on dtype)
        Sampler of random data values with keyword arg ``size``.
        This function should take a single keyword argument ``size`` specifying
        the length of its returned ndarray. It is used to generate the nonzero
        values in the matrix after the locations of those values are chosen.
        By default, uniform [0, 1) random values are used unless `dtype` is
        an integer (default uniform integers from that dtype) or
        complex (default uniform over the unit square in the complex plane).
        For these, the `rng` is used e.g. ``rng.uniform(size=size)``.

    Returns
    -------
    res : sparse array

    Examples
    --------

    Passing a ``np.random.Generator`` instance for better performance:

    >>> import numpy as np
    >>> import scipy as sp
    >>> rng = np.random.default_rng()

    Default sampling uniformly from [0, 1):

    >>> S = sp.sparse.random_array((3, 4), density=0.25, rng=rng)

    Providing a sampler for the values:

    >>> rvs = sp.stats.poisson(25, loc=10).rvs
    >>> S = sp.sparse.random_array((3, 4), density=0.25,
    ...                            rng=rng, data_sampler=rvs)
    >>> S.toarray()
    array([[ 36.,   0.,  33.,   0.],   # random
           [  0.,   0.,   0.,   0.],
           [  0.,   0.,  36.,   0.]])

    Providing a sampler for uint values:

    >>> def random_uint32_to_100(size=None):
    ...     return rng.integers(100, size=size, dtype=np.uint32)
    >>> S = sp.sparse.random_array((3, 4), density=0.25, rng=rng,
    ...                            data_sampler=random_uint32_to_100)

    Building a custom distribution.
    This example builds a squared normal from np.random:

    >>> def np_normal_squared(size=None, rng=rng):
    ...     return rng.standard_normal(size) ** 2
    >>> S = sp.sparse.random_array((3, 4), density=0.25, rng=rng,
    ...                            data_sampler=np_normal_squared)

    Or we can build it from sp.stats style rvs functions:

    >>> def sp_stats_normal_squared(size=None, rng=rng):
    ...     std_normal = sp.stats.distributions.norm_gen().rvs
    ...     return std_normal(size=size, random_state=rng) ** 2
    >>> S = sp.sparse.random_array((3, 4), density=0.25, rng=rng,
    ...                            data_sampler=sp_stats_normal_squared)

    Or we can subclass sp.stats rv_continuous or rv_discrete:

    >>> class NormalSquared(sp.stats.rv_continuous):
    ...     def _rvs(self,  size=None, random_state=rng):
    ...         return rng.standard_normal(size) ** 2
    >>> X = NormalSquared()
    >>> Y = X().rvs
    >>> S = sp.sparse.random_array((3, 4), density=0.25,
    ...                            rng=rng, data_sampler=Y)
    r   c              3   D   K   | ]}t          j        |           V  dS )ry   Nr5   r   rU   r   r   s     r@   rV   zrandom_array.<locals>.<genexpr>  s2      >>B
2Y///>>>>>>rA   rS   )_randomr   rv   rI   r#   rg   )	r8   rJ  r:   r^   rK  rL  rh   indr   s	           @r@   r   r   u  s    B wsLIIID#  s5zz222I
>>>>#>>>
>
>CdC[...77???rA   c                 Z   |dk     s|dk    rt          d          t          j        |           }t          t	          ||z                      }t                    |Rt          j        t          j                  rfd}n,t          j        t          j	                  rfd}nj
        }t          t          |                     |t          j        t          j                  j        k    rK                    ||d          }t          j        || d	
          }	t#          fd|	D                       }	nt%          |           }
t'                      }t%          |          |k     r_|t%          |          z
  }|                    t+          t"          t-          | ||
f                               t%          |          |k     _t#          t          j        t1          |                    j                  }	 ||                              d          }||	fS )Nr   r   z(density expected to be 0 <= density <= 1c                     t          t          j                  j        t          j                  j        |           S )Nry   )r   r5   iinforu   rv   )r   r^   rK  s    r@   rL  z_random.<locals>.data_sampler  s>    #C$&HUOO$7$&HUOO$7$(*/	1 1 1 1rA   c                 d                         |                                |           dz  z   S )Nr   y              ?)uniform)r   rK  s    r@   rL  z_random.<locals>.data_sampler  s4    ....34 5rA   r   F)r   replaceF)r8   orderc              3   B   K   | ]}t          j        |          V  d S rR   rO  rP  s     r@   rV   z_random.<locals>.<genexpr>  s/      <<"BJr9--<<<<<<rA   rW  ry   r.   )r2   r   r   r~   roundr   r5   r]   r`   complexfloatingrX  r   rv   rU  r*  choiceunravel_indexrI   rZ   rc   updater|   r   r   r\   Tr(  )r8   rJ  r:   r^   rK  rL  tot_prodr   raveled_indrR  r3   seendsizevalsr   s      ``         @r@   rQ  rQ    s/   {{gkkCDDDyH uWx'(())D
S
!
!C=
++ 	'1 1 1 1 1 1 1 ]5""455 	'5 5 5 5 5 5 ;Ls5zz222I28BH%%)))jjejDD{%sCCC<<<<<<<<< 5zzuu$ii$3t99$EKKE<U%#O#O#OPPQQQ $ii$ BHT$ZZy999;<< <T"""))%e)<<D9rA      )position_numc                     || }t          |           t          |          }} fd}nd}t          | |f|||||          \  }}	t          ||	f| |f                              |          S )au  Generate a sparse matrix of the given shape and density with randomly
    distributed values.

    .. warning::

        This function returns a sparse matrix -- not a sparse array.
        You are encouraged to use `random_array` to take advantage of the
        sparse array functionality.

    Parameters
    ----------
    m, n : int
        shape of the matrix
    density : real, optional
        density of the generated matrix: density equal to one means a full
        matrix, density of 0 means a matrix with no non-zero items.
    format : str, optional
        sparse matrix format.
    dtype : dtype, optional
        type of the returned matrix values.
    rng : `numpy.random.Generator`, optional
        Pseudorandom number generator state. When `rng` is None, a new
        `numpy.random.Generator` is created using entropy from the
        operating system. Types other than `numpy.random.Generator` are
        passed to `numpy.random.default_rng` to instantiate a ``Generator``.

        This random state will be used for sampling the sparsity structure, but
        not necessarily for sampling the values of the structurally nonzero
        entries of the matrix.
    data_rvs : callable, optional
        Samples a requested number of random values.
        This function should take a single argument specifying the length
        of the ndarray that it will return. The structurally nonzero entries
        of the sparse random matrix will be taken from the array sampled
        by this function. By default, uniform [0, 1) random values will be
        sampled using the same random state as is used for sampling
        the sparsity structure.

    Returns
    -------
    res : sparse matrix

    See Also
    --------
    random_array : constructs sparse arrays instead of sparse matrices

    Examples
    --------

    Passing a ``np.random.Generator`` instance for better performance:

    >>> import scipy as sp
    >>> import numpy as np
    >>> rng = np.random.default_rng()
    >>> S = sp.sparse.random(3, 4, density=0.25, rng=rng)

    Providing a sampler for the values:

    >>> rvs = sp.stats.poisson(25, loc=10).rvs
    >>> S = sp.sparse.random(3, 4, density=0.25, rng=rng, data_rvs=rvs)
    >>> S.toarray()
    array([[ 36.,   0.,  33.,   0.],   # random
           [  0.,   0.,   0.,   0.],
           [  0.,   0.,  36.,   0.]])

    Building a custom distribution.
    This example builds a squared normal from np.random:

    >>> def np_normal_squared(size=None, rng=rng):
    ...     return rng.standard_normal(size) ** 2
    >>> S = sp.sparse.random(3, 4, density=0.25, rng=rng,
    ...                      data_rvs=np_normal_squared)

    Or we can build it from sp.stats style rvs functions:

    >>> def sp_stats_normal_squared(size=None, rng=rng):
    ...     std_normal = sp.stats.distributions.norm_gen().rvs
    ...     return std_normal(size=size, random_state=rng) ** 2
    >>> S = sp.sparse.random(3, 4, density=0.25, rng=rng,
    ...                      data_rvs=sp_stats_normal_squared)

    Or we can subclass sp.stats rv_continuous or rv_discrete:

    >>> class NormalSquared(sp.stats.rv_continuous):
    ...     def _rvs(self,  size=None, random_state=rng):
    ...         return rng.standard_normal(size) ** 2
    >>> X = NormalSquared()
    >>> Y = X()  # get a frozen version of the distribution
    >>> S = sp.sparse.random(3, 4, density=0.25, rng=rng, data_rvs=Y.rvs)
    Nc                      |           S rR   r   )r   data_rvss    r@   data_rvs_kwzrandom.<locals>.data_rvs_kwo  s    8D>>!rA   rS   )r~   rQ  r"   rg   )
ri   rj   rJ  r:   r^   rK  rl  rm  rg  rR  s
         `   r@   r   r     s    z 	yq663q66qA	" 	" 	" 	" 	" 	" A[IIID#tSk!Q00099&AAArA   c                 *    t          | |||||          S )a  Generate a sparse matrix of the given shape and density with uniformly
    distributed values.

    .. warning::

        This function returns a sparse matrix -- not a sparse array.
        You are encouraged to use `random_array` to take advantage
        of the sparse array functionality.

    Parameters
    ----------
    m, n : int
        shape of the matrix
    density : real, optional
        density of the generated matrix: density equal to one means a full
        matrix, density of 0 means a matrix with no non-zero items.
    format : str, optional
        sparse matrix format.
    dtype : dtype, optional
        type of the returned matrix values.
    rng : `numpy.random.Generator`, optional
        Pseudorandom number generator state. When `rng` is None, a new
        `numpy.random.Generator` is created using entropy from the
        operating system. Types other than `numpy.random.Generator` are
        passed to `numpy.random.default_rng` to instantiate a ``Generator``.

    Returns
    -------
    res : sparse matrix

    Notes
    -----
    Only float types are supported for now.

    See Also
    --------
    random : Similar function allowing a custom random data sampler
    random_array : Similar to random() but returns a sparse array

    Examples
    --------
    >>> from scipy.sparse import rand
    >>> matrix = rand(3, 4, density=0.25, format="csr", rng=42)
    >>> matrix
    <Compressed Sparse Row sparse matrix of dtype 'float64'
        with 3 stored elements and shape (3, 4)>
    >>> matrix.toarray()
    array([[0.05641158, 0.        , 0.        , 0.65088847],  # random
           [0.        , 0.        , 0.        , 0.14286682],
           [0.        , 0.        , 0.        , 0.        ]])

    )r   )ri   rj   rJ  r:   r^   rK  s         r@   r
   r
   w  s    l !Q444rA   )NF)NNN)r   NrR   )T)NN)F)rI  NNNN)rI  r1   NNN)rI  r1   NN)B__doc____docformat____all__r:  r   r   r   r   numpyr5   scipy._lib._utilr   r   r   scipy._lib.deprecationr   _sputilsr   r   r   r   _sparsetoolsr   _bsrr    r!   _coor"   r#   _cscr$   r%   _csrr&   r'   _diar(   r)   _baser*   r+   r   r   r   r   r   r   r   floatr   r   r   r   r   r   r  r   r   r	   r   r  r   r   rQ  r   r
   r   rA   r@   <module>r~     s[    &6 6 6
   				 



      Q Q Q Q Q Q Q Q Q Q + + + + + + F F F F F F F F F F F F $ $ $ $ $ $ ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' $ $ $ $ $ $ $ $   2 2 2 2 2j+1 +1 +1\I I I IX?D ?D ?D ?DD *+$t8 iI iI iI iI iIX d4x c* c* c* c*L11 11 11 11h'(auT '( '( '( '( '(T"W "W "W "WJ QeD // // // //dpR pR pR pRfC$ C$ C$ C$L(9 (9 (9V59 59 59p,E ,E ,E ,E^-R -R -R -R`=C =C =C =C@ #'d +) +) +) +) +)\]G ]G ]G ]G@QX QX QX QXh N###'Te@ e@ e@ e@ $#e@P 59#', , , ,^ N33337"fB fB fB 43fBR N33355 55 55 4355 55 55rA   