
    4[gY                        d Z dZg dZddlZddlZddlZddlmZm	Z	 ddl
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Z"ddddddZ#d+dZ$d,dZ%d-de&dddZ'd.dZ(dde&dfdZ)d-dZ*d-dZ+d Z,d Z-d/dZ.d/dZ/d/dZ0dddd Z1d0d!Z2d/d"Z3d#d$dddd%d&Z4	 	 d1d'Z5	 	 d2d(Z6d3d)Z7y)4z2Functions 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    N)check_random_staterng_integers   )upcastget_index_dtypeisscalarlike)
csr_hstack)
bsr_matrix	bsr_array)
coo_matrix	coo_array)
csc_matrix	csc_array)
csr_matrix	csr_array)
dia_matrix	dia_array)issparsesparrayc                 z    ||t        | d         x}}n||\  }}t        | |f||f      j                  |      S )a  
    Return a sparse matrix from diagonals.

    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.

    .. 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.

    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]])

    r   shape)lenr"   asformat)datar   mnformats        R/var/www/html/bid-api/venv/lib/python3.12/site-packages/scipy/sparse/_construct.pyr   r      sN    ^ 	yQYDGA	
1tUmAq62;;FCC    )offsetsr(   r.   dtypec         
      R   t        |      r>t        |       dk(  st        | d         rt        j                  |       g} n.t	        d      t        t        t        j                  |             } t        j                  |      }t        |       t        |      k7  rt	        d      |*t        | d         t        t        |d               z   }||f}|t        j                  |  }|\  }}t        |D cg c]!  }t        ||z   ||z
        t        d|      z   # c}      }t        d|      }t        j                  t        |      |f|      }	t        ||      }
t        |       D ]R  \  }}||   }t        d|      }t        ||z   ||z
  |
      }|dk  rt	        d||fz        	 |dd|f   |	||||z   f<   T t        |	|f||f	      j                  |      S c c}w # t        $ r?}t        |      |k7  r+t        |      dk7  rt	        d|t        |      |||fz        | d}~ww xY w)
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:
          - 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.

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

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

    Repeated diagonal offsets are disallowed.

    .. versionadded:: 1.11

    Examples
    --------
    >>> from scipy.sparse import diags_array
    >>> diagonals = [[1, 2, 3, 4], [1, 2, 3], [1, 2]]
    >>> 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, -2, 1], 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, 2, 3], 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r2   z"Offset %d (index %d) out of bounds.r   zTDiagonal length (index %d: %d at offset %d) does not agree with array size (%d, %d).r'   )r   r)   np
atleast_1d
ValueErrorlistmapabsintcommon_typemaxminzeros	enumerater#   r*   )	diagonalsr1   r(   r.   r2   r,   r-   offsetMdata_arrKjdiagonalklengthes                   r/   r   r   Q   sG   D Gy>Q,y|"<y12IIJJR]]I67	mmG$G 9~W%EFF }	!C
O 44A }	* DAq"$" VQZ(3q&>9"$ 	%AAq	AxxWq)7HAq	A +86NQZVQ/A:AVQKOPP	&.s7F7{&;HQ!F(
]# ,  h(A7@@HH/$  	8}&3x=A+= 6s8}fa9445 ;<< 	s   2&G$G	H&':H!!H&c                 T    t        | |||      }t        |      j                  |      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:
          - 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.

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

    Notes
    -----
    This function differs from `spdiags` in the way it handles
    off-diagonals.

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

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

    Repeated diagonal offsets are disallowed.

    .. versionadded:: 0.11

    Examples
    --------
    >>> from scipy.sparse import diags
    >>> diagonals = [[1, 2, 3, 4], [1, 2, 3], [1, 2]]
    >>> 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, -2, 1], [-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, 2, 3], 1).toarray()
    array([[ 0.,  1.,  0.,  0.],
           [ 0.,  0.,  2.,  0.],
           [ 0.,  0.,  0.,  3.],
           [ 0.,  0.,  0.,  0.]])
    r1   r(   r2   )r   r"   r*   )rA   r1   r(   r.   r2   As         r/   r   r      s*    ^ 	Iwe5IAa=!!&))r0   c                      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.

    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)>

    )r2   r.   )r   )r-   r2   r.   s      r/   r   r     s    N q!500r0   )rH   r2   r.   c                     t        | ||||      S )a  Identity matrix in sparse array format

    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 or tuple of ints
        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.

    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r,   r-   rH   r2   r.   s        r/   r   r   E  s    D 1a''r0   c           
         |rt         }t        }t        }t        }	nt        }t
        }t        }t        }	|| }t        |       t        |      }} | |k(  r|dk(  r|dv rjt        |      }
t        j                  |dz   |
      }t        j                  ||
      }t        j                  ||      }||d|   } ||||f||f      S |dk(  r`t        |      }
t        j                  ||
      }t        j                  ||
      }t        j                  ||      } ||||ff||f      S t        j                  dt        dt        | |z   |            f|      } |	||g| |f|      j                  |      S )Nr   )csrcscmaxvalr   r4   coorL   )r!   r   r   r   r    r   r   r   r;   r   r5   arangeonesr=   r>   r*   )r,   r-   rH   r2   r.   
as_sparray
csr_sparse
csc_sparse
coo_sparsediags_sparse	idx_dtypeindptrindicesr+   clsrowcols                    r/   rQ   rQ   j  se   


"


yq63q6qAAv!q&^#'q1IYYqs)4Fii3G771E*D$Z8@Cgv.A77u_'q1I))AY/C))AY/C771E*Dtc3Z01a&9977As1c!a%m,-U;Dqc!QuENNvVVr0   c                 "    t        | ||||d      S )a/  Sparse matrix with ones on diagonal

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

    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.

    .. 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.

    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)>

    FrP   rR   s        r/   r   r     s    L 1a..r0   c                 	   t        | t              st        |t              rt        }t        }t        }nt
        }t        }t        } ||      }|j                  dk7  rt        d|j                   d      ||dk(  r[d|j                  z  |j                  d   |j                  d   z  k\  r+ || d      } | j                  dk7  rt        d	| j                   d      | j                  d   |j                  d   z  | j                  d   |j                  d   z  f}| j                  dk(  s|j                  dk(  r ||      j                  |      S |j                         }| j                  j                  |j                         j#                  d
|j                  d   |j                  d         }||z  } ||| j$                  | j&                  f|      S  ||       } | j                  dk7  rt        d	| j                   d      | j                  d   |j                  d   z  | j                  d   |j                  d   z  f}| j                  dk(  s|j                  dk(  r ||      j                  |      S | j(                  j                  |j                        }| j*                  j                  |j                        }	| j                  j                  |j                        }t-        | j                  d   |j                  d   z  | j                  d   |j                  d   z        t/        j0                  d      j,                  kD  r>|j3                  t.        j4                        }|	j3                  t.        j4                        }	||j                  d   z  }|	|j                  d   z  }	|j#                  d
|j                        |	j#                  d
|j                        }	}||j(                  z  }|	|j*                  z  }	|j#                  d
      |	j#                  d
      }	}|j#                  d
|j                        |j                  z  }|j#                  d
      } ||||	ff|      j                  |      S )aF  kronecker product of sparse matrices A and B

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

    Returns
    -------
    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]])

       z&kron requires 2D input arrays. `B` is D.bsrr   r   Tcopyz&kron requires 2D input arrays. `A` is r'   int32)
isinstancer%   r   r!   r   r   r    r   ndimr7   nnzr(   r*   toarrayr+   repeatsizereshaperb   ra   rd   re   r=   r5   iinfoastypeint64)
rM   Br.   
bsr_sparser\   r^   output_shaper+   rd   re   s
             r/   r   r     s   N !WAw!7





1Avv{A!&&LMM 	&E/qw!''!*qwwqz:Q/Qqd#66Q;EaffXRPQQ
1771:-qwwqz!''!*/DE55A:!l+44V<<IIKvv}}QVV$,,R
1771:Fax4		!((3<HH qM66Q;EaffXRPQQ
1771:-qwwqz!''!*/DE55A:!l+44V<< eell155!eell155!vv}}QUU#qwwqz!''!*$aggaj&;<rxx?P?T?TT**RXX&C**RXX&Cqwwqzqwwqz ++b'Bquu(=Cquuquu++b/#++b/C ||Bquu%.||B4S	*,?HHPPr0   c                    t        | t              st        |t              rt        }t        }nt        }t
        } ||       }  ||      }| j                  dk7  rt        d| j                   d      |j                  dk7  rt        d|j                   d      | j                  d   | j                  d   k7  rt        d      |j                  d   |j                  d   k7  rt        d      t        | j                  |j                        } || j                  d   |	      } ||j                  d   |	      }t        || d
      }t        ||d
      }	||	z   j                  |      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
        square matrix
    B
        square matrix
    format : str
        format of the result (e.g. "csr")

    Returns
    -------
    kronecker sum in a sparse matrix format

    rh   z#kronsum requires 2D inputs. `A` is ri   z#kronsum requires 2D inputs. `B` is r   r   zA is not squarezB is not squarer4   rX   )r.   )ro   r%   r   r   r   r   rp   r7   r(   r   r2   r   r*   )
rM   ry   r.   r^   identity_sparser2   I_nI_mLRs
             r/   r   r   !  s:   . !WAw!7
#
"1A1Avv{>qvvhbIJJvv{>qvvhbIJJwwqzQWWQZ*++wwqzQWWQZ*++177AGG$E
!''!*E
2C
!''!*E
2CS!E"AQE"AEF##r0   c                    dk(  rdnd}t        j                  | D cg c]  }|j                   c}      }| d   j                  |   }t	        | D cg c]  }|j
                   c}t        |j                  |            }t        j                  |j                  |      }t        j                  t        fd| D              dz   |      }	 |d      }
d}d}| D ]  }|j                  |   |k7  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<   |r)dk(  rt        |||	f||f	      S t        |||	f||f	      S dk(  rt        |||	f||f	      S t!        |||	f||f	      S c c}w c c}w )
zh
    Stacking fast path for CSR/CSC matrices or arrays
    (i) vstack for CSR, (ii) hstack for CSC.
    r   r   )arraysrW   r4   c              3   <   K   | ]  }|j                        y wN_shape_as_2d.0baxiss     r/   	<genexpr>z+_compressed_sparse_stack.<locals>.<genexpr>a  s     ?1!...   z!incompatible dimensions for axis Nrm   r'   )r5   concatenater+   r   r   ra   r=   rt   emptysumr7   rb   slicer    r   r!   r   )blocksr   return_spmatrix
other_axisr   r+   constant_dimr`   rb   ra   last_indptrsum_dimsum_indicesidxss    `            r/   _compressed_sparse_stackr   V  s   
 aiQJ>>626a166623D!9))*5L&'A&Q&'A'*499l'CEIhhtyy	2GXXc???!C9UFA,KGK>>*%5@MNN:;))K		67qyy~~%Wgt(<<=xx}tt#1>>$''qxx|#  F2J19tWf5%,l$;= = tWf5%17$;= = qy$0!(, 79 	9 $0!-w 79 	9C 3'As   G:G?c                 &   t        |       }|dk(  rt        d      |dk(  r| d   S dk(  rdnd}| D ch c]  }|j                  |    }}t        |      dkD  rt        d| d|       |\  }| D cg c]  }|j                   }}t	        j
                  | D cg c]  }|j                   c}      }t        fd| D              }	t        d | D              }
t        t        |	dz
  |
            }t	        j                  | D cg c]  }|j                      c}|	      }|j                  dkD  rt	        j
                  |      j                  |      }t	        j
                  | D cg c]  }|j                   c}      j                  |      }t	        j                  |dz   |	      }t	        j                  |      }t	        j                  |      }t!        |||||||||	       nRt	        j"                  |dz   |	      }t	        j                  d|	      }t	        j                  d|j$                  	      }dk(  r| d   j'                  |||f|	|f
      S | d   j)                  |||f||	f
      S c c}w c c}w c c}w c c}w c c}w )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   z"Mismatching dimensions along axis z: c              3   <   K   | ]  }|j                        y wr   r   r   s     r/   r   z*_stack_along_minor_axis.<locals>.<genexpr>  s     71!..&r   c              3   F   K   | ]  }t        |j                          y wr   )r)   rb   r   r   s     r/   r   z*_stack_along_minor_axis.<locals>.<genexpr>  s     -fc!))nfs   !rV   r4   r'   )r)   r7   r   ra   r5   r   r+   r   r   r=   arrayrt   rw   rb   r   
empty_liker   r?   r2   _csc_container_csr_container)r   r   n_blocksr   r   other_axis_dimsr   indptr_listdata_catr   rq   r`   stack_dim_cat
indptr_catindices_catra   rb   r+   s    `                r/   _stack_along_minor_axisr     s   
 6{H1}1221}ay aiQJ;AB6aq~~j16OB
?a=j\+,. / 	/#ML &,,V188VK,~~v6v!qvvv67H 777G
-f-
-Cs7Q;'<=IHHFCFqannT2FC9UM}}q^^K077	B
~~&&A&Qqyy&&ABy) 	,*)<--,}}X&8\={H7D	* ,*)<((1I.xx0qyay''w(?!(, 7 ( 9 	9 ay''w(?!-w 7 ( 9 	9O C -6 D 'Bs   I:3I?JJ	,J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]])

    objectr4   c              3   <   K   | ]  }t        |t                y wr   ro   r%   r   s     r/   r   zhstack.<locals>.<genexpr>       
7;a:a!;   Tr   r5   asarrayanyflat_blockr   r.   r2   s      r/   r   r     sK    P ZZh/F

76;;
77vh..vhtDDr0   c                     t        j                  | d      } t        d | j                  D              rt	        | D cg c]  }|g c}||      S t	        | D cg c]  }|g c}||d      S c c}w c c}w )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   r4   c              3   <   K   | ]  }t        |t                y wr   r   r   s     r/   r   zvstack.<locals>.<genexpr>  r   r   Tr   r   )r   r.   r2   r   s       r/   r   r     sq    R ZZh/F

76;;
77F+FqsF+VU;;F+FqsF+VUDQQ ,+s   
A.
A3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` can return a deprecated sparse matrix.
    `bmat` returns a coo_matrix if none of the inputs are a sparse array.

    .. warning::

        This function returns a sparse matrix -- not a sparse array.
        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   r4   c              3   <   K   | ]  }t        |t                y wr   r   r   s     r/   r   zbmat.<locals>.<genexpr>S  r   r   Tr   r   r   s      r/   r	   r	     sG    r ZZh/F

76;;
77ffe,,ffeTBBr0   )r.   r2   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   Y  s    V &&%((r0   c                 	   t        j                  | d      } | j                  dk7  rt        d      | j                  \  }}|dv rt        d | j                  D              ro|dkD  rAt        |      D cg c]  }t        | |d d f   d      g } }t        j                  | d      } t        | d d df   d|      }||j                  |      }|S |d	v rt        d
 | j                  D              rp|dkD  rBt        |      D cg c]  }t        | d d |f   d       c}g} t        j                  | d      } t        | dd d f   d|      }||j                  |      }|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   |	|<   nB|	|   |j                  d   k7  r-d| d| d| d|j                  d    d|	|    d}t        |      |
|   dk(  r|j                  d   |
|<   |
|   |j                  d   k7  sd| d| d| d|j                  d    d|
|    d}t        |        t!        d | |   D              }|(| |   D cg c]  }|j"                   }}|rt%        | nd }t        j&                  dt        j(                  |	            }t        j&                  dt        j(                  |
            }|d   |d   f}t        j*                  ||      }t-        t/        |            }t        j*                  ||      }t        j*                  ||      }d}t        j0                  |      \  }}t3        ||      D ]  \  }}| ||f   }t5        |||j6                  z         }|j8                  ||<   t        j:                  |j<                  ||   ||   |       t        j:                  |j>                  ||   ||   |       ||j6                  z  } |r tA        |||ff|      jC                  |      S t        |||ff|      jC                  |      S c c}w c c}w c c}w )Nr   r4   rh   zblocks must be 2-D)NrT   c              3   T   K   | ]   }t        |      xr |j                  d k(   " yw)rT   Nr$   r.   r   s     r/   r   z_block.<locals>.<genexpr>  s&     C{!HQK-AHH--{   &(r   r   )NrU   c              3   T   K   | ]   }t        |      xr |j                  d k(   " yw)rU   Nr   r   s     r/   r   z_block.<locals>.<genexpr>  s&     EAhqk/ahh%//r   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   4   K   | ]  }|j                     y wr   )rq   )r   blocks     r/   r   z_block.<locals>.<genexpr>  s     8%7Eeii%7s   rm   rV   )outr2   r'   )"r5   r   rp   r7   r(   allr   ranger   r   rw   r?   boolrx   r   r   r   r2   r   appendcumsumr   r   r=   nonzerozipr   rq   r+   addrd   re   r   r*   )r   r.   r2   r   rC   Nr   rM   
block_maskbrow_lengthsbcol_lengthsirF   msgrq   blk
all_dtypesrow_offsetscol_offsetsr(   r+   r`   rd   re   iijjry   idxs                               r/   r   r     s   ZZh/F{{a-..
,,CAa 	-Cv{{CCq5JOPQ(S(Q.vad|Q?@(FSZZh7F %VAqD\1oFA
M
!
EE
Eq5INqRA.vad|Q?RSFZZh7F %VAqD\1oFA&,,d3J88ARXX.L88ARXX.L 1XqAac{&fQqSk*qs"&
1Q3?a'&'nnQ&7LO!!_q(99$QC ())*1QC~annQ>O=P Q''3A&7q:C %S/)?a'&'nnQ&7LO!!_q(99&qc *))*1QC~annQ>O=P Q''3A&7q:C %S/)+  0 8VJ%78
8C}+1*+=>+=Ccii+=
>'1
#t))Aryy67K))Aryy67K_k"o.E88Cu%Ds5z2I
((3i
(C
((3i
(C
CZZ
#FBB11a4LCquu%FFS	
quuk!n#c()D
quuk!n#c()Dquu  4#s,E:CCFKKdS#J'u5>>vFF] T SP ?s   3SS	-Sc                    t        d | D              rt        }nt        }g }g }g }d}d}| D ]R  }	t        |	t        t
        j                  f      rt        t        j                  |	            }	t        |	      rw|	j                         }	|	j                  \  }
}|j                  |	j                  |z          |j                  |	j                  |z          |j                  |	j                         n|	j                   \  }
}t        j"                  t        j$                  |
|z        |      \  }}|j                  ||z          |j                  ||z          |j                  |	j'                                ||
z  }||z  }U t        j(                  |      }t        j(                  |      }t        j(                  |      } ||||ff||f|      j+                  |      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                y wr   r   )r   as     r/   r   zblock_diag.<locals>.<genexpr>  s     
04a:a!4r   r   )r(   r2   )r   r   r   ro   r8   numbersNumberr5   
atleast_2dr$   tocoor   r   rd   re   r+   r(   divmodrY   ravelr   r*   )matsr.   r2   	containerrd   re   r+   r_idxc_idxr   nrowsncolsa_rowa_cols                 r/   r   r     s   Z 
04
00		
C
CDEEa$/0"--*+AA;	A>>LE5JJquuu}%JJquuu}%KK77LE599RYYuU{%;UCLE5JJuu}%JJuu}%KK	"! " ..
C
..
C>>$DdS#J'"EN!##+8F#34r0   {Gz?rX   )densityr.   r2   random_statedata_samplerc                    |t         j                  j                         }t        | |||||      \  }}t	        ||f|       j                  |      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).

    .. warning::

        Since numpy 1.17, passing a ``np.random.Generator`` (e.g.
        ``np.random.default_rng``) for ``random_state`` will lead to much
        faster execution times.

        A much slower implementation is used by default for backwards
        compatibility.

    Parameters
    ----------
    shape : int or tuple of ints
        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.
    random_state : {None, int, `Generator`, `RandomState`}, optional
        A random number generator to determine nonzero structure. We recommend using
        a `numpy.random.Generator` manually provided for every call as it is much
        faster than RandomState.

        - If `None` (or `np.random`), the `numpy.random.RandomState`
          singleton is used.
        - If an int, a new ``Generator`` instance is used,
          seeded with the int.
        - If a ``Generator`` or ``RandomState`` instance then
          that instance is used.

        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 `random_state` 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, random_state=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,
    ...                            random_state=rng, data_sampler=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, random_state=rng):
    ...     return random_state.standard_normal(size) ** 2
    >>> S = sp.sparse.random_array((3, 4), density=0.25, random_state=rng,
    ...                      data_sampler=np_normal_squared)

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

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

    Or we can subclass sp.stats rv_continous or rv_discrete:

    >>> class NormalSquared(sp.stats.rv_continuous):
    ...     def _rvs(self,  size=None, random_state=rng):
    ...         return random_state.standard_normal(size) ** 2
    >>> X = NormalSquared()
    >>> Y = X().rvs
    >>> S = sp.sparse.random_array((3, 4), density=0.25,
    ...                            random_state=rng, data_sampler=Y)
    r'   )r5   r   default_rng_randomr   r*   )r(   r   r.   r2   r   r   r+   inds           r/   r   r   6  sQ    T yy,,.w|\RID#dC[.77??r0   c                    |dk  s|dkD  rt        d      t        j                  |       }t        t	        ||z              }t        |      |at        j                  t        j                        rfd}n6t        j                  t        j                        rfd}nj                  }|t        j                  t        j                        j                  k  r-j                  ||d      }t        j                  || d	      }	nt!        |       }
t#               }t!        |      |k  rJ|t!        |      z
  }|j%                  t'        t(        t+        | ||
f
                   t!        |      |k  rJt)        t        j,                  t/        |            j0                        }	 ||
      j3                  d      }||	fS )Nr   r   z(density expected to be 0 <= density <= 1c                     t        t        j                        j                  t        j                        j                  |       S )Nr4   )r   r5   rv   r>   r=   )rt   r2   rngs    r/   r   z_random.<locals>.data_sampler  s:    #C$&HHUO$7$7$&HHUO$7$7$(*/	1 1r0   c                 T    j                  |       j                  |       dz  z   S )Nrt   y              ?)uniform)rt   r   s    r/   r   z_random.<locals>.data_sampler  s.    ..34 5r0   F)rt   replaceF)r(   orderr   rk   )r7   mathprodr;   roundr   r5   
issubdtypeintegercomplexfloatingr   rv   rx   r=   choiceunravel_indexr)   setupdater9   tupler   r   r8   Trw   )r(   r   r.   r2   r   r   tot_prodrt   raveled_indr   rp   seendsizevalsr   s      `          @r/   r   r     sq   {gkCDDyyH uWx'()D
\
*C==

+1 ]]5""4"455 ;;L "((288$(((jjejD{%sC 5zu$i$3t9$EKKE<U%#OPQ $i$ BHHT$Z(**+ T"))%e)<D9r0   c                     || }t        |       t        |      }} fd}nd}t        | |f|||||      \  }}	t        ||	f| |f      j                  |      S )aU  Generate a sparse matrix of the given shape and density with randomly
    distributed values.

    .. warning::

        Since numpy 1.17, passing a ``np.random.Generator`` (e.g.
        ``np.random.default_rng``) for ``random_state`` will lead to much
        faster execution times.

        A much slower implementation is used by default for backwards
        compatibility.

    .. 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.
    random_state : {None, int, `numpy.random.Generator`,
                    `numpy.random.RandomState`}, optional

        - If `seed` is None (or `np.random`), the `numpy.random.RandomState`
          singleton is used.
        - If `seed` is an int, a new ``RandomState`` instance is used,
          seeded with `seed`.
        - If `seed` is already a ``Generator`` or ``RandomState`` instance then
          that instance is used.

        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, random_state=rng)

    Providing a sampler for the values:

    >>> rvs = sp.stats.poisson(25, loc=10).rvs
    >>> S = sp.sparse.random(3, 4, density=0.25, random_state=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, random_state=rng):
    ...     return random_state.standard_normal(size) ** 2
    >>> S = sp.sparse.random(3, 4, density=0.25, random_state=rng,
    ...                      data_rvs=np_normal_squared)

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

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

    Or we can subclass sp.stats rv_continous or rv_discrete:

    >>> class NormalSquared(sp.stats.rv_continuous):
    ...     def _rvs(self,  size=None, random_state=rng):
    ...         return random_state.standard_normal(size) ** 2
    >>> X = NormalSquared()
    >>> Y = X()  # get a frozen version of the distribution
    >>> S = sp.sparse.random(3, 4, density=0.25, random_state=rng, data_rvs=Y.rvs)
    Nc                      |       S r    )rt   data_rvss    r/   data_rvs_kwzrandom.<locals>.data_rvs_kwA  s    D>!r0   r'   )r;   r   r   r*   )
r,   r-   r   r.   r2   r   r  r  r  r   s
         `   r/   r   r     so    R 	yq63q6qA	" AkRID#tSk!Q099&AAr0   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.
    random_state : {None, int, `numpy.random.Generator`,
                    `numpy.random.RandomState`}, optional

        If `seed` is None (or `np.random`), the `numpy.random.RandomState`
        singleton is used.
        If `seed` is an int, a new ``RandomState`` instance is used,
        seeded with `seed`.
        If `seed` is already a ``Generator`` or ``RandomState`` instance then
        that instance is used.

    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", random_state=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   )r,   r-   r   r.   r2   r   s         r/   r
   r
   I  s    r !Q==r0   )NNN)r   NNN)dNr   )T)NN)F)r   NNNN)r   rX   NNN)r   rX   NN)8__doc____docformat____all__r   r   numpyr5   scipy._lib._utilr   r   _sputilsr   r   r   _sparsetoolsr   _bsrr   r   _coor   r   _cscr   r   _csrr    r!   _diar"   r#   _baser$   r%   r   r   r   r   floatr   rQ   r   r   r   r   r   r   r   r	   r   r   r   r   r   r   r
   r  r0   r/   <module>r$     s   &F    = ; ; $ ' ' ' ' ' $3Dl *+$t4 tInP*f'1T"(auT "(J"WJ QeD &/RfQR2$j(9V69r,E^-R`=C@ #'d +)\\G~M4` $(T"m@` 59,0*Z 48'+sBl9>r0   