o
    Eb2                     @   s   d Z ddlZddlmZ zeeejfZW n e	y"   eejfZY nw dd Z
G dd dZd	d
 Zdd Zdd ZdddZdd Zdd ZdS )z*Indexing mixin for sparse matrix classes.
    N   )	isintlikec                 C   s0   t | |\}}| jj|j_|jj|j_||fS )a   
    Same as np.broadcast_arrays(a, b) but old writeability rules.

    NumPy >= 1.17.0 transitions broadcast_arrays to return
    read-only arrays. Set writeability explicitly to avoid warnings.
    Retain the old writeability rules, as our Cython code assumes
    the old behavior.
    )npZbroadcast_arraysflagsZ	writeable)abxy r
   5/usr/lib/python3/dist-packages/scipy/sparse/_index.py_broadcast_arrays   s   	r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*S )+
IndexMixinzS
    This class provides common dispatching and validation logic for indexing.
    c                 C   s   | j rtddS )zWe do not currently support 1D sparse arrays.

        This function is called each time that a 1D array would
        result, raising an error instead.

        Once 1D sparse arrays are implemented, it should be removed.
        zcWe have not yet implemented 1D sparse slices; please index using explicit indices, e.g. `x[:, [0]]`N)Z	_is_arrayNotImplementedError)selfr
   r
   r   _raise_on_1d_array_slice    s
   z#IndexMixin._raise_on_1d_array_slicec                 C   s  |  |\}}t|trDt|tr| ||S t|tr&|   | ||S |jdkr5|   | ||S |jdkr@| ||S t	dt|trt|trX|   | 
||S t|trq|td krk||krk|  S | ||S |jdkr|| ||S t	d|jdkrt|tr|   | ||S t|tr| ||S n5t|tr| ||S t|trt	d|jd dkr|jdks|jd dkr| |d d df | S t||\}}|j|jkrt	d|jdkr| jt|j| jdS | ||S )Nr      zindex results in >2 dimensionsr   'number of row and column indices differdtype)_validate_indices
isinstance	INT_TYPES_get_intXintslicer   _get_intXslicendim_get_intXarray
IndexError_get_sliceXintcopy_get_sliceXslice_get_sliceXarray_get_arrayXint_get_arrayXsliceshape_get_columnXarrayZravelr   size	__class__r   Z
atleast_2dr   _get_arrayXarray)r   keyrowcolr
   r
   r   __getitem__.   sV   













&
zIndexMixin.__getitem__c           
      C   sN  |  |\}}t|tr.t|tr.tj|| jd}|jdkr"td| |||j	d  d S t|t
rEtj|| jd  d d d f }nt|}t|t
rntj|| jd  d d d f }|jdkrm|d d d f }nt|}t||\}}|j|jkrtdddlm} ||r|jdkr|d  }|d  }|jd dko|jd dk}|jd dko|jd dk}	|s|jd |jd kr|	s|jd |jd kstd|jd dks|jd dkrd S |jdd	}|  | ||| d S tj|| jd}| j| jkrt||j}|jdkrd S ||j}| ||| d S )
Nr   r   z&Trying to assign a sequence to an itemr   r   )
isspmatrixzshape mismatch in assignmentT)r   )r   r   r   r   asarrayr   r&   
ValueError_set_intXintZflatr   Zarangeindicesr$   Z
atleast_1dr   r   r   _baser-   ZtocooZsum_duplicates_set_arrayXarray_sparseZsqueezeZbroadcast_toZreshape_set_arrayXarray)
r   r)   r   r*   r+   ijr-   Zbroadcast_rowZbroadcast_colr
   r
   r   __setitem__`   sX   

$

"


zIndexMixin.__setitem__c                 C   s   | j \}}t|\}}t|r+t|}|| k s||kr"td| |dk r*||7 }nt|ts6| ||}t|rYt|}|| k sG||krMtd| |dk rU||7 }||fS t|tsd| ||}||fS )Nzrow index (%d) out of ranger   zcolumn index (%d) out of range)r$   _unpack_indexr   intr   r   r   
_asindices)r   r)   MNr*   r+   r
   r
   r   r      s*   


zIndexMixin._validate_indicesc              
   C   s   zt |}W n tttfy } ztd|d}~ww |jdvr%td|jdkr,|S | }||kr:td| |	 }|dk rc|| k rMtd| ||u sU|j
jsY| }||dk   |7  < |S )zConvert `idx` to a valid index for an axis with a given length.

        Subclasses that need special validation can override this method.
        zinvalid indexN)r   r   zIndex dimension must be 1 or 2r   index (%d) out of range)r   r.   r/   	TypeErrorMemoryErrorr   r   r&   maxminr   Zowndatar   )r   idxlengthr   eZmax_indxZmin_indxr
   r
   r   r:      s*   



zIndexMixin._asindicesc                 C   sP   | j \}}t|}|| k s||krtd| |dk r ||7 }| |tdS )zGReturn a copy of row i of the matrix, as a (1 x n) row vector.
        r=   r   N)r$   r9   r   r   r   r   r5   r;   r<   r
   r
   r   getrow      
zIndexMixin.getrowc                 C   sP   | j \}}t|}|| k s||krtd| |dk r ||7 }| td|S )zMReturn a copy of column i of the matrix, as a (m x 1) column vector.
        r=   r   N)r$   r9   r   r   r   rE   r
   r
   r   getcol   rG   zIndexMixin.getcolc                 C      t  Nr   r   r*   r+   r
   r
   r   r         zIndexMixin._get_intXintc                 C   rI   rJ   rK   rL   r
   r
   r   r      rM   zIndexMixin._get_intXarrayc                 C   rI   rJ   rK   rL   r
   r
   r   r      rM   zIndexMixin._get_intXslicec                 C   rI   rJ   rK   rL   r
   r
   r   r      rM   zIndexMixin._get_sliceXintc                 C   rI   rJ   rK   rL   r
   r
   r   r       rM   zIndexMixin._get_sliceXslicec                 C   rI   rJ   rK   rL   r
   r
   r   r!      rM   zIndexMixin._get_sliceXarrayc                 C   rI   rJ   rK   rL   r
   r
   r   r"      rM   zIndexMixin._get_arrayXintc                 C   rI   rJ   rK   rL   r
   r
   r   r#      rM   zIndexMixin._get_arrayXslicec                 C   rI   rJ   rK   rL   r
   r
   r   r%      rM   zIndexMixin._get_columnXarrayc                 C   rI   rJ   rK   rL   r
   r
   r   r(      rM   zIndexMixin._get_arrayXarrayc                 C   rI   rJ   rK   r   r*   r+   r   r
   r
   r   r0      rM   zIndexMixin._set_intXintc                 C   rI   rJ   rK   rN   r
   r
   r   r4     rM   zIndexMixin._set_arrayXarrayc                 C   s4   t j| | jd}t||\}}| ||| d S )Nr   )r   r.   Ztoarrayr   r   r4   )r   r*   r+   r   _r
   r
   r   r3     s   z"IndexMixin._set_arrayXarray_sparseN)__name__
__module____qualname____doc__r   r,   r7   r   r:   rF   rH   r   r   r   r   r    r!   r"   r#   r%   r(   r0   r4   r3   r
   r
   r
   r   r      s,    24r   c                 C   s*  ddl m}m} t| |tjfr| jdkr| jjdkr| 	 S t
| } t| trGt| dkr3| \}}n:t| dkrC| d td}}n*tdt| }|du rW| td}}n|jdk rdt|tdfS |jdkrm|	 S ||su||rytdt|}t|}|durt|}|durt|}||fS )	z Parse index. Always return a tuple of the form (row, col).
    Valid type for row/col is integer, slice, or array of integers.
    r   )spmatrixr-   r   r   r   Nzinvalid number of indiceszoIndexing with sparse matrices is not supported except boolean indexing where matrix and index are equal shapes.)r2   rT   r-   r   r   Zndarrayr   r   kindZnonzero_check_ellipsistuplelenr   r   _compatible_boolean_index_boolean_index_to_array)indexrT   r-   r*   r+   rB   Zbool_rowZbool_colr
   r
   r   r8     s@   




r8   c                 C   s   | t u rtdtdfS t| ts| S t| D ]\}}|t u r#|} nq| S t| dkr4tdtdfS t| dkr\|dkrT| d t u rLtdtdfS td| d fS | d tdfS g }| |d d D ]}|t urq|| qf|t| }tdd| }| d| tdf|  t| S )z6Process indices with Ellipsis. Returns modified index.Nr   r   r   )Ellipsisr   r   rW   	enumeraterX   appendr@   )r[   r6   vZfirst_ellipsistailZndZnslicer
   r
   r   rV   9  s4   

"rV   c                 C   s   t | } | jjdkr| S dS )z8Returns a compatible array if elements are boolean.
    r   N)r   Z
asanyarrayr   rU   rB   r
   r
   r   _maybe_bool_ndarray`  s   
rb   r   c                 C   sP   |dk rdS z	t t| d}W n
 ty   Y dS w t|tr!dS t||d S )zQReturns True if first element of the incompatible
    array type is boolean.
    r   NT)nextiterr>   r   bool_first_element_bool)rB   Zmax_dimfirstr
   r
   r   rf   i  s   
rf   c                 C   s   t | ds	t| rt| S dS )ztReturns a boolean index array that can be converted to
    integer array. Returns None if no such array exists.
    r   N)hasattrrf   rb   ra   r
   r
   r   rY   x  s   rY   c                 C   s    | j dkr	tdt| d S )Nr   zinvalid index shaper   )r   r   r   wherera   r
   r
   r   rZ     s   
rZ   )r   )rS   Znumpyr   Z_sputilsr   r9   ZlongZintegerr   	NameErrorr   r   r8   rV   rb   rf   rY   rZ   r
   r
   r
   r   <module>   s"     p.'
	
