B
    0d;                 @   s  d Z g ZddlmZ ddlZddlZddlmZ ddl	m
Z
mZmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZmZ ddlmZ ddlmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- G dd deeeZ.dd Z/dS )z>Base class for sparse matrix formats using compressed storage.    )warnN)_prune_array   )spmatrix
isspmatrixSparseEfficiencyWarning)_data_matrix_minmax_mixin)
dia_matrix)_sparsetools)get_csr_submatrixcsr_sample_offsetscsr_todensecsr_sample_valuescsr_row_indexcsr_row_slicecsr_column_index1csr_column_index2)
IndexMixin)upcastupcast_char	to_nativeisdenseisshapegetdtypeisscalarlike	isintlikeget_index_dtypedowncast_intp_indexget_sum_dtypecheck_shapematrixasmatrixis_pydata_spmatrixc               @   sZ  e Zd ZdZdyddZdzddZejje_d{dd	Zd|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,d-Zejje_d.d/ Zd0d1 Zejje_d2d3 Zejje_d~d4d5Zejje_dd6d7Zd8d9 Zd:d; Zd<d= Z d>d? Z!d@dA Z"ddBdCZ#dDdE Z$ddFdGZ%ddHdIZ&dJdK Z'dLdM Z(dNdO Z)dPdQ Z*dRdS Z+dTdU Z,dVdW Z-dXdY Z.ddZd[Z/ej/je/_dd\d]Z0ej0je0_d^d_ Z1d`da Z2dbdc Z3e4e2e3ddZ5dedf Z6dgdh Z7didj Z8e4e7e8ddZ9dkdl Z:dmdn Z;dodp Z<dqdr Z=ej=je=_ddsdtZ>dudv Z?dwdx Z@dS )
_cs_matrixzBbase matrix class for compressed row- and column-oriented matricesNFc          
   C   s  t |  t|rF|j| jkr,|r,| }n|| j}| | nt|trt	|rt
|| _| j\}}tt||d}tdt|td| _td|| _tj| ||fd d |d| _nt|dkrddlm} | ||||d}	| |	 nt|d	krv|\}
}}d }|d k	r,t|}t||f|d
d}tj|||d| _tj|||d| _tj|
||d| _ntd| jnjyt|}W n6 tk
r } ztd| j|W d d }~X Y nX ddlm} | | |||d |d k	rt
|| _np| jd krxy t| jd }| j d }W n. tk
rb } ztd|W d d }~X Y nX t
| ||f| _|d k	r| jj|dd| _| j dd d S )N)maxvalr   )defaultr   )dtype   )
coo_matrix)shaper'      T)r%   Zcheck_contents)copyr'   z(unrecognized {}_matrix constructor usagez!unable to infer matrix dimensionsF)r,   )
full_check)!r   __init__r   formatr,   asformat	_set_self
isinstancetupler   r    _shaper*   r   maxnpzerosr   floatdataindices_swapindptrlencoor)   	__class__array
ValueErrorasarray	Exceptionastypecheck_format)selfZarg1r*   r'   r,   MN	idx_dtyper)   otherr9   r:   r<   r%   e	major_dim	minor_dim rN   I/var/www/html/venv/lib/python3.7/site-packages/scipy/sparse/compressed.pyr.      sl    










z_cs_matrix.__init__c             C   s   |d krt | jd S |dk r&|d7 }| |d| f\}}| | j\}}|dkrhtjt| j|dS |dkr|t| jS t	dd S )Nr   r(   r   )Z	minlengthzaxis out of bounds)
intr<   r;   r*   r6   Zbincountr   r:   diffrA   )rF   axis_rH   rN   rN   rO   getnnzl   s    z_cs_matrix.getnnzc             C   s4   |r|  }|j| _|j| _|j| _t|j| _dS )z:take the member variables of other and assign them to selfN)r,   r9   r:   r<   r    r*   r4   )rF   rJ   r,   rN   rN   rO   r1   }   s    z_cs_matrix._set_selfTc             C   s  |  d\}}|  | j\}}| jjjdkrDtd| jjjdd | jjjdkrjtd| jjjdd t	| j| jf}t
j| j|d| _t
j| j|d| _t| j| _x.| jj| jj| jjgD ]}|dkrtd	qW t| j|d krtd
t| j|d | jd dkr tdt| jt| jkr>td| jd t| jkr\td|   |r| jdkr| j |krtd||| j dk rtd|t
| j dk rtddS )zcheck whether the matrix format is valid

        Parameters
        ----------
        full_check : bool, optional
            If `True`, rigorous check, O(N) operations. Otherwise
            basic check, O(1) operations (default True).
        )rowcolumniz'indptr array has non-integer dtype ({})r+   )
stacklevelz(indices array has non-integer dtype ({}))r'   r   z'data, indices, and indptr should be 1-Dz&index pointer size ({}) should be ({})r   z!index pointer should start with 0z*indices and data should have the same sizerP   zQLast value of index pointer should be less than the size of index and data arraysz{} index values must be < {}z{} index values must be >= 0z8index pointer values must form a non-decreasing sequenceN)r;   r*   r<   r'   kindr   r/   namer:   r   r6   rB   r   r9   ndimrA   r=   prunennzr5   minrR   )rF   r-   Z
major_nameZ
minor_namerL   rM   rI   xrN   rN   rO   rE      sF    

z_cs_matrix.check_formatc             C   s*   |    | j|| j|dd}|  |S )zScalar version of self._binopt, for cases in which no new nonzeros
        are added. Produces a new spmatrix in canonical form.
        T)r,   )sum_duplicates
_with_datar9   eliminate_zeros)rF   rJ   opresrN   rN   rO   _scalar_binopt   s    z_cs_matrix._scalar_binoptc             C   s  t |rxt|r$| j| jtjdS |dkrhtdtdd | tj| jtjd}| 	|t
j}|| S | 	|t
jS nt|r|  |kS t|rtS t|rtdtdd | j|jkrdS | j|jkr|| j}| |d}| tj| jtjd}|| S dS d S )	N)r'   r   zOComparing a sparse matrix with 0 using == is inefficient, try using != instead.r+   )rY   zHComparing sparse matrices using == is inefficient, try using != instead.F_ne_)r   r6   isnanr?   r*   bool_r   r   onesrf   operatorneeqr   todenser#   NotImplementedr   r/   r0   _binopt)rF   rJ   all_trueinvre   rN   rN   rO   __eq__   s4    


z_cs_matrix.__eq__c             C   s   t |rt|r<tdtdd | tj| jtjd}|S |dkrtdtdd | jt| jtjd}| 	|t
j}|| S | 	|t
jS n`t|r|  |kS t|rtS t|r| j|jkrdS | j|jkr|| j}| |dS dS d S )	Nz:Comparing a sparse matrix with nan using != is inefficientr+   )rY   )r'   r   z^Comparing a sparse matrix with a nonzero scalar using != is inefficient, try using == instead.Trg   )r   r6   rh   r   r   r?   rj   r*   ri   rf   rk   rm   rl   r   rn   r#   ro   r   r/   r0   rp   )rF   rJ   rq   rr   rN   rN   rO   __ne__   s0    


z_cs_matrix.__ne__c             C   s,  t |rzd|kr"|dkr"tdnV|d|rlt|t tj| jt|d}|| | 	|}| 
||S | ||S nt|r||  |S t|r | j|jkrtdn| j|jkr|| j}|dkr| 
||S tdt | 	tj| jtjd}| 
||dkrd	nd
}|| S tdd S )Nr   )_le__ge_z >= and <= don't work with 0.)r'   zinconsistent shapes)rv   ru   zUComparing sparse matrices using >= and <= is inefficient, using <, >, or !=, instead.ru   _gt__lt_zOperands could not be compared.)r   NotImplementedErrorr   r   r6   emptyr*   Zresult_typefillr?   rp   rf   r   rn   r   rA   r/   r0   rj   ri   )rF   rJ   rd   op_nameZbad_scalar_msg	other_arrrq   re   rN   rN   rO   _inequality  s2    






z_cs_matrix._inequalityc             C   s   |  |tjddS )Nrx   zgComparing a sparse matrix with a scalar greater than zero using < is inefficient, try using >= instead.)r~   rk   lt)rF   rJ   rN   rN   rO   __lt__?  s    z_cs_matrix.__lt__c             C   s   |  |tjddS )Nrw   zdComparing a sparse matrix with a scalar less than zero using > is inefficient, try using <= instead.)r~   rk   gt)rF   rJ   rN   rN   rO   __gt__E  s    z_cs_matrix.__gt__c             C   s   |  |tjddS )Nru   zgComparing a sparse matrix with a scalar greater than zero using <= is inefficient, try using > instead.)r~   rk   le)rF   rJ   rN   rN   rO   __le__K  s    z_cs_matrix.__le__c             C   s   |  |tjddS )Nrv   zdComparing a sparse matrix with a scalar less than zero using >= is inefficient, try using < instead.)r~   rk   ge)rF   rJ   rN   rN   rO   __ge__Q  s    z_cs_matrix.__ge__c             C   s   |j | j kr td| j |j t| jj|jj}| dd }tj|||dd}| | j \}}|j	j
rn|n|j}t||| j| j| j| t|ddS )NzIncompatible shapes ({} and {})ZCFr   T)r'   orderr,   F)r,   )r*   rA   r/   r   r'   charr;   r6   r@   flagsc_contiguousTr   r<   r:   r9   r!   )rF   rJ   r'   r   resultrG   rH   yrN   rN   rO   
_add_dense[  s    z_cs_matrix._add_densec             C   s   |  |dS )NZ_plus_)rp   )rF   rJ   rN   rN   rO   _add_sparseg  s    z_cs_matrix._add_sparsec             C   s   |  |dS )NZ_minus_)rp   )rF   rJ   rN   rN   rO   _sub_sparsej  s    z_cs_matrix._sub_sparsec             C   s2  t |r| |S t|r:| j|jkr>| |}| |dS |jdkrZ| | d S | jdkrv||  d S | jd dkr|jd dkr| | S | jd dkr|jd dkr||  S |jd dkr$| jd |jd kr$t	| 
 dgf|jd |jd fd}| |S | jd dkr~| jd |jd kr~t	|  
 dgf| jd | jd fd}||S |jd dkr| jd |jd krt	| 
 dgf|jd |jd fd}|| S | jd dkr2| jd |jd kr2t	|  
 dgf| jd | jd fd}||S tdt|}|jdkr`t|  |S |jdkr|| |jd S | jdkrt|  d |S dd	lm} |  }| j|jkrt|j||j|jf }n@| jd dkr|jd dkrt|j|}n<|jd | jd kr@t|j|d
d
|jf }ntdtt|jd t|j}t|j|jd }||tj
 ||ff|jd | jd fddS | jd dkr|jd dkrt|jd
d
d
f |}n@|jd | jd kr t|jd
d
d
f ||j }ntdt|j|jd }tt|jd t|j}||tj
 ||ff| jd |jd fddS |jd dkr| jd |jd krt|j|d
d
|jf 
 }nH|jd dkr| jd |jd krt|j||j 
 }ntd|tj
 |_|S )zPPoint-wise multiplication by another matrix, vector, or
        scalar.
        Z_elmul_)r   r   )r   r   r   r   )r*   zinconsistent shapesr(   )r)   NF)r*   r,   )r   Z_mul_scalarr   r*   r?   rp   toarray_mul_sparse_matrixtocscr
   ravelrA   r6   Z
atleast_2dr\   multiplysizeZflatr>   r)   tocoor9   rV   colrepeataranger=   tileviewZndarray)rF   rJ   r,   r)   retr9   rV   r   rN   rN   rO   r   m  s    




&
&
&
&

"&"&z_cs_matrix.multiplyc             C   sT   | j \}}tj|t| jj|jjd}tt| jd }|||| j	| j
| j|| |S )N)r'   Z_matvec)r*   r6   r7   r   r'   r   getattrr   r/   r<   r:   r9   )rF   rJ   rG   rH   r   fnrN   rN   rO   _mul_vector  s    
z_cs_matrix._mul_vectorc          
   C   sl   | j \}}|j d }tj||ft| jj|jjd}tt| jd }||||| j	| j
| j| |  |S )Nr   )r'   Z_matvecs)r*   r6   r7   r   r'   r   r   r   r/   r<   r:   r9   r   )rF   rJ   rG   rH   Zn_vecsr   r   rN   rN   rO   _mul_multivector  s    


z_cs_matrix._mul_multivectorc             C   sf  | j \}}|j \}}| ||fd }| |}t| j| j|j|jf}tt| jd }|||t	j
| j|dt	j
| j|dt	j
|j|dt	j
|j|d}	t| j| j|j|jf|	d}t	j|d |d}
t	j|	|d}t	j|	t| j|jd}tt| jd }|||t	j
| j|dt	j
| j|d| jt	j
|j|dt	j
|j|d|j|
|| | j|||
f||fdS )Nr   Z_matmat_maxnnz)r'   )r%   r   Z_matmat)r*   )r*   r;   r?   r   r<   r:   r   r   r/   r6   rB   rz   r   r'   r9   )rF   rJ   rG   ZK1ZK2rH   Z
major_axisrI   r   r^   r<   r:   r9   rN   rN   rO   r     s6    






z_cs_matrix._mul_sparse_matrixr   c             C   s   | j \}}|| ks||kr.tjd| jjdS tt| jd }tjt|t|d |t	|d t
| jd}||| j d | j d | j| j| j| |S )Nr   )r'   Z	_diagonalr   )r*   r6   rz   r9   r'   r   r   r/   r_   r5   r   r<   r:   )rF   krowscolsr   r   rN   rN   rO   diagonal  s    
 
z_cs_matrix.diagonalc             C   s   t |r||rVtdtdd tj| jt|jd}|| | 	|}| 
||S |   || jt|}| j	|| j| jf|j| jd}|S n2t|r||  |S t|r| 
||S tdd S )NzITaking maximum (minimum) with > 0 (< 0) number results to a dense matrix.r+   )rY   )r'   )r'   r*   zOperands not compatible.)r   r   r   r6   rz   r*   rB   r'   r{   r?   rp   ra   r9   r:   r<   r   rn   r   rA   )rF   rJ   Znpopr|   Zdense_checkr}   Znew_datamatrN   rN   rO   _maximum_minimum%  s&    

z_cs_matrix._maximum_minimumc             C   s   |  |tjddd S )NZ	_maximum_c             S   s   t | dkS )Nr   )r6   rB   )r`   rN   rN   rO   <lambda>>      z$_cs_matrix.maximum.<locals>.<lambda>)r   r6   maximum)rF   rJ   rN   rN   rO   r   <  s    
z_cs_matrix.maximumc             C   s   |  |tjddd S )NZ	_minimum_c             S   s   t | dk S )Nr   )r6   rB   )r`   rN   rN   rO   r   D  r   z$_cs_matrix.minimum.<locals>.<lambda>)r   r6   minimum)rF   rJ   rN   rN   rO   r   B  s    
z_cs_matrix.minimumc             C   s   t | ds|| dd krt| j}tjt| jd |d}| tj	\}}|||< t
|}|d dkrp|j}|dk	r|j|jkrtd|jd	||d
S tj| |||d
S dS )z~Sum the matrix over the given axis.  If the axis is None, sum
        over both rows and columns, returning a scalar.
        	blocksize))r   rP   )r   r(   r   r   )r'   r(   Nzdimensions do not matchrN   )rS   r'   out)hasattrr;   r   r'   r6   r7   r=   r<   _minor_reduceaddr"   r   r*   rA   sumr   )rF   rS   r'   r   Z	res_dtyper   major_indexvaluerN   rN   rO   r   L  s    

z_cs_matrix.sumc             C   s>   |dkr| j }tt| j}||t| j| }||fS )a  Reduce nonzeros with a ufunc over the minor axis when non-empty

        Can be applied to a function of self.data by supplying data parameter.

        Warning: this does not call sum_duplicates()

        Returns
        -------
        major_index : array of ints
            Major indices where nonzero

        value : array of self.dtype
            Reduce result for nonzeros in each major_index
        N)r9   r6   ZflatnonzerorR   r<   Zreduceatr   )rF   Zufuncr9   r   r   rN   rN   rO   r   i  s    z_cs_matrix._minor_reducec       
      C   s\   |  | j\}}|  ||f\}}t||| j| j| j||d ||d 	\}}}	|	j| jdS )Nr   )r'   )r;   r*   r   r<   r:   r9   r   r'   )
rF   rV   r   rG   rH   majorminorr<   r:   r9   rN   rN   rO   _get_intXint  s    z_cs_matrix._get_intXintc             C   sF   |  ||f\}}|jdkr6|jdkr6| j||ddS | ||S )N)r   NT)r,   )r;   step_get_submatrix_major_slice_minor_slice)rF   rV   r   r   r   rN   rN   rO   _get_sliceXslice  s    z_cs_matrix._get_sliceXslicec       	   
   C   s   | j j}| | j\}}| ||f\}}tj||d}tj||d}tj|j| jd}t||| j	| j | j
|j| | |	 |jdkrt|S | ||jS )N)r'   r   )r:   r'   r;   r*   r6   rB   rz   r   r   r<   r9   r   r\   r"   r?   Zreshape)	rF   rV   r   rI   rG   rH   r   r   valrN   rN   rO   _get_arrayXarray  s    
z_cs_matrix._get_arrayXarrayc             C   s"   |  ||f\}}| ||S )N)r;   _major_index_fancy_minor_index_fancy)rF   rV   r   r   r   rN   rN   rO   _get_columnXarray  s    z_cs_matrix._get_columnXarrayc             C   s   | j j}tj||d }| | j\}}t|}| ||f}|dkrR| |S | j	|d  | j	|  }| j j}tj
|d |d}	tj||	dd d |	d }
tj|
|d}tj|
| jd}t||| j	| j | j|| | j|||	f|ddS )	zBIndex along the major axis where idx is an array of ints.
        )r'   r   r   N)r   rP   F)r*   r,   )r:   r'   r6   rB   r   r;   r*   r=   r?   r<   r7   cumsumrz   r   r9   )rF   idxrI   r:   rT   rH   rG   	new_shaperow_nnz
res_indptrr^   res_indicesres_datarN   rN   rO   r     s$    
z_cs_matrix._major_index_fancyc          	   C   s  |t dkr|r|  S | S | | j\}}||\}}}tt|||}| ||f}|dkrl| |S || }	}
|dkr|dkrd}
|d |d  }}| j||| | j|	|
|  }| jj	}t
j|d |d}t
j||dd d |dkr6t | j| | j| }t
j| j| |d}t
j| j| |d}nB|d }t
j||d}t
j|| j	d}t|||| j| j| j|| | j|||f|dd	S )
z@Index along the major axis where idx is a slice object.
        Nr   rP   r   )r'   )r   )r,   F)r*   r,   )slicer,   r;   r*   r:   r=   ranger?   r<   r'   r6   r7   r   r@   r9   rz   r   )rF   r   r,   rG   rH   startstopr   r   Zstart0Zstop0Zstart1Zstop1r   rI   r   Zall_idxr   r   r^   rN   rN   rO   r     s8    


z_cs_matrix._major_slicec          	   C   s   | j j}tj||d }| | j\}}t|}| ||f}|dkrR| |S tj	||d}t
| j}t||||| j| j || t|j|dd}	|d }
tj|
|d}tj|
| jd}t|	|t| j | j | j|| | j|||f|ddS )zBIndex along the minor axis where idx is an array of ints.
        )r'   r   F)r,   rP   )r*   r,   )r:   r'   r6   rB   r   r;   r*   r=   r?   r7   Z
empty_liker<   r   argsortrD   rz   r   r9   )rF   r   rI   rG   rH   r   r   Zcol_offsetsr   Z	col_orderr^   r   r   rN   rN   rO   r     s&    
z_cs_matrix._minor_index_fancyc             C   s   |t dkr|r|  S | S | | j\}}||\}}}tt|||}|dkrh| | ||fS |dkr~| j||dS | 	t
|||S )z@Index along the minor axis where idx is a slice object.
        Nr   r   )r   r,   )r   r,   r;   r*   r:   r=   r   r?   r   r   r6   r   )rF   r   r,   rG   rH   r   r   r   rN   rN   rO   r     s    z_cs_matrix._minor_slicec          
   C   s   |  | j\}}t||\}}t||\}}	|dkr\|dkr\||kr\|	|kr\|rX|  S | S t||| j| j| j||||		\}
}}|  || |	| f}| j|||
f|| j	ddS )zbReturn a submatrix of this matrix.

        major, minor: None, int, or slice with step 1
        r   F)r*   r'   r,   )
r;   r*   _process_slicer,   r   r<   r:   r9   r?   r'   )rF   r   r   r,   rG   rH   i0i1Zj0Zj1r<   r:   r9   r*   rN   rN   rO   r     s     "z_cs_matrix._get_submatrixc             C   s$   |  ||f\}}| ||| d S )N)r;   	_set_many)rF   rV   r   r`   rX   jrN   rN   rO   _set_intXint&  s    z_cs_matrix._set_intXintc             C   s$   |  ||f\}}| ||| d S )N)r;   r   )rF   rV   r   r`   rX   r   rN   rN   rO   _set_arrayXarray*  s    z_cs_matrix._set_arrayXarrayc             C   s  | j | ||f  |j\}}|dko2|jd dk}|dkoH|jd dk}|j|j }}	tj|j| jd}|j	dkrxd S |rt
t|t|}t|	|}	t||}|rt
||}tt|t|	}	t
||}| |||	f |||	f f\}
}| |
|| d S )Nr   r   )r'   )
_zero_manyr;   r*   rV   r   r6   rB   r9   r'   r   r   r   r=   r   r   )rF   rV   r   r`   rG   rH   Zbroadcast_rowZbroadcast_colrcrX   r   rN   rN   rO   _set_arrayXarray_sparse.  s$    

"z"_cs_matrix._set_arrayXarray_sparsec       	      C   s   d| j krd S | j \}}|jdk}|dk r|r>t|| |}nt|| |t|}tj|| jjd}tj|| jjd}||8 }nT|rt||| }nt||| t|}tj|| jjd}tj|| jjd}||7 }|s|d t| }|| ||f< d S )Nr   )r'   )r*   r\   r_   r=   r6   r   r:   r'   )	rF   valuesr   rG   rH   	broadcastZ	max_indexrX   r   rN   rN   rO   _setdiagG  s(    



z_cs_matrix._setdiagc             C   sl   |  | j\}}dd }tj|| jjddd }tj|| jjddd }||| ||| ||||fS )Nc             S   sF   |   }||kr td||f |  }|| k rBtd||f d S )Nzindex (%d) out of range (>= %d)zindex (%d) out of range (< -%d))r5   
IndexErrorr_   )r:   boundr   rN   rN   rO   check_boundsh  s    
z1_cs_matrix._prepare_indices.<locals>.check_boundsFr   )r'   r,   ndmin)r;   r*   r6   r@   r:   r'   r   )rF   rX   r   rG   rH   r   rN   rN   rO   _prepare_indicese  s    


z_cs_matrix._prepare_indicesc       
   	   C   s"  |  ||\}}}}tj|| jddd }|j}tj|| jjd}t||| j	| j||||}|dkr| 
  t||| j	| j|||| d|kr|| j|< dS td| jtdd	 |dk}	||	 | j||	 < |	 }	||	 }||d
k   |7  < ||	 }||d
k   |7  < | ||||	  dS )zSets value at each (i, j) to x

        Here (i,j) index major and minor respectively, and must not contain
        duplicate entries.
        Fr   )r'   r,   r   )r'   rP   NzZChanging the sparsity structure of a {}_matrix is expensive. lil_matrix is more efficient.r+   )rY   r   )r   r6   r@   r'   r   r   rz   r:   r   r<   ra   r9   r   r/   r   _insert_many)
rF   rX   r   r`   rG   rH   	n_samplesoffsetsr   maskrN   rN   rO   r   x  s0    



z_cs_matrix._set_manyc          	   C   s   |  ||\}}}}t|}tj|| jjd}t||| j| j||||}|dkrr|   t||| j| j|||| d| j	||dk < dS )zSets value at each (i, j) to zero, preserving sparsity structure.

        Here (i,j) index major and minor respectively.
        )r'   r   r   rP   N)
r   r=   r6   rz   r:   r'   r   r<   ra   r9   )rF   rX   r   rG   rH   r   r   r   rN   rN   rO   r     s    

z_cs_matrix._zero_manyc             C   s  t j|dd}|j|dd}|j|dd}|j|dd}| j}t| j| jf| jd |j d}t j| j|d| _t j| j|d| _t j||d}t j||d}g }g }t j	|dd	\}	}
t 
|
t|}
t |
}d
}xtt|	|
|
dd D ]\}\}}}| j| }| j| }|
| j||  |
| j||  t j	||| ddd dd	\}}t||| kr|
|||  |
|||  nL|
||| ddd |  |
||| ddd |  t|||< |}qW | j| }|
| j|d  |
| j|d  t || _t || _t j| jj|d}|d
|d
< t | j}||	  |7  < ||dd< t j||d| _|rd| _|   | jdd dS )a:  Inserts new nonzero at each (i, j) with value x

        Here (i,j) index major and minor respectively.
        i, j and x must be non-empty, 1d arrays.
        Inserts each major group (e.g. all entries per row) at a time.
        Maintains has_sorted_indices property.
        Modifies i, j, x in place.
        Z	mergesort)rZ   Zclip)moderP   )r%   )r'   T)Zreturn_indexr   r   N)r   F)r-   )r6   r   Ztakehas_sorted_indicesr   r:   r<   r   rB   uniqueappendr=   rR   	enumeratezipr9   Zconcatenaterz   r*   r   sort_indicesrE   )rF   rX   r   r`   r   Zdo_sortrI   Zindices_partsZ
data_partsZuiZ	ui_indptrZnew_nnzsprevr   iijsZjer   r   ZujZ	uj_indptrZnnzsZindptr_diffrN   rN   rO   r     sZ    	
*

$  
z_cs_matrix._insert_manyc       	      C   sx   |  | j\}}| j}tjt|| jjd}t|| j	| |  ||f\}}ddl
m} || j||ff| j|| jdS )N)r'   r   )r)   )r,   r'   )r;   r*   r:   r6   rz   r=   r'   r   Z	expandptrr<   r>   r)   r9   )	rF   r,   rL   rM   Zminor_indicesZmajor_indicesrV   r   r)   rN   rN   rO   r     s    z_cs_matrix.tocooc             C   s   |d kr|d kr|  dd }| ||}|jjsB|jjsBtd|jjrX|  }|}n|  }|j}| |j	\}}t
|||j|j|j| |S )Ncfr   z&Output array must be C or F contiguous)r;   Z_process_toarray_argsr   r   f_contiguousrA   Ztocsrr   r   r*   r   r<   r:   r9   )rF   r   r   r`   r   rG   rH   rN   rN   rO   r     s    z_cs_matrix.toarrayc             C   s4   |  | j\}}t||| j| j| j |   dS )zVRemove zero entries from the matrix

        This is an *in place* operation.
        N)r;   r*   r   Zcsr_eliminate_zerosr<   r:   r9   r]   )rF   rG   rH   rN   rN   rO   rc   #  s    z_cs_matrix.eliminate_zerosc             C   sF   t | ddsd| _n,t| ds@ttt| jd | j| j| _	| jS )a^  Determine whether the matrix has sorted indices and no duplicates

        Returns
            - True: if the above applies
            - False: otherwise

        has_canonical_format implies has_sorted_indices, so if the latter flag
        is False, so will the former be; if the former is found True, the
        latter flag is also set.
        _has_sorted_indicesTF_has_canonical_formatr   )
r   r   r   boolr   Zcsr_has_canonical_formatr=   r<   r:   has_canonical_format)rF   rN   rN   rO   Z__get_has_canonical_format-  s    
z%_cs_matrix.__get_has_canonical_formatc             C   s   t || _|rd| _d S )NT)r   r   r   )rF   r   rN   rN   rO   Z__set_has_canonical_formatC  s    
z%_cs_matrix.__set_has_canonical_format)fgetfsetc             C   sL   | j r
dS |   | | j\}}t||| j| j| j | 	  d| _ dS )zmEliminate duplicate matrix entries by adding them together

        This is an *in place* operation.
        NT)
r   r   r;   r*   r   Zcsr_sum_duplicatesr<   r:   r9   r]   )rF   rG   rH   rN   rN   rO   ra   K  s    z_cs_matrix.sum_duplicatesc             C   s2   t | ds,ttt| jd | j| j| _| jS )zDetermine whether the matrix has sorted indices

        Returns
            - True: if the indices of the matrix are in sorted order
            - False: otherwise

        r   r   )r   r   r   Zcsr_has_sorted_indicesr=   r<   r:   r   )rF   rN   rN   rO   Z__get_sorted[  s
    

z_cs_matrix.__get_sortedc             C   s   t || _d S )N)r   r   )rF   r   rN   rN   rO   Z__set_sortedk  s    z_cs_matrix.__set_sortedc             C   s   |   }|  |S )z9Return a copy of this matrix with sorted indices
        )r,   r   )rF   ArN   rN   rO   sorted_indicesp  s    z_cs_matrix.sorted_indicesc             C   s0   | j s,tt| jd | j| j| j d| _ dS )z3Sort the indices of this matrix *in place*
        r   TN)r   r   Zcsr_sort_indicesr=   r<   r:   r9   )rF   rN   rN   rO   r   {  s    z_cs_matrix.sort_indicesc             C   s   |  | jd }t| j|d kr*tdt| j| jk rBtdt| j| jk rZtdt| jd| j | _t| jd| j | _dS )z8Remove empty space after all non-zero elements.
        r   r   z index pointer has invalid lengthz)indices array has fewer than nnz elementsz&data array has fewer than nnz elementsN)	r;   r*   r=   r<   rA   r:   r^   r9   r   )rF   rL   rN   rN   rO   r]     s    z_cs_matrix.prunec             G   s  t |}t| drz| j\}}t|d |\}}t|d |\}}|sH|rZtd| j|f | jd | | jd |  }}	n| |\}}| | j\}}	||k r| jd | j|  | _| j	d | j|  | _	| jd |d  | _n<||krt
| j|d | _| j|d d  | j|  ||	k r| j|k }
t
|
s| j|
 | _| j	|
 | _	| t
j|
\}}| jd || jdd  |< t
j| j| jd || _d S )Nr   r   r   z.shape must be divisible into %s blocks. Got %s)r   )r    r   r   divmodrA   r*   r;   r:   r<   r9   r6   resizer{   allr   r   r   r4   )rF   r*   ZbmZbnZnew_MZrmZnew_NZrnrG   rH   r   r   r   rN   rN   rO   r     s8    

 


z_cs_matrix.resizec             C   sL   |r*| j || j | j f| j|jdS | j || j| jf| j|jdS dS )zReturns a matrix with the same sparsity structure as self,
        but with different data.  By default the structure arrays
        (i.e. .indptr and .indices) are copied.
        )r*   r'   N)r?   r:   r,   r<   r*   r'   )rF   r9   r,   rN   rN   rO   rb     s    

z_cs_matrix._with_datac             C   s&  |  |}tt| j| | j }| j|j }t| j| j|j|jf|d}tj	| jj
|d}tj	||d}dddddg}||krtj	|tjd}	ntj	|t| j|jd}	|| j
d | j
d	 tj| j|dtj| j|d| jtj|j|dtj|j|d|j|||	 | j |	||f| j
d
}
|
  |
S )z5apply the binary operation fn to two sparse matrices.)r%   )r'   rg   rx   rw   ru   rv   r   r   )r*   )r?   r   r   r/   r^   r   r<   r:   r6   rz   r*   ri   r   r'   rB   r9   r]   )rF   rJ   rd   r   ZmaxnnzrI   r<   r:   Zbool_opsr9   r   rN   rN   rO   rp     s.    



z_cs_matrix._binoptc             C   s   |j | j krtd| |d}t|jtjrtj| j | jd}|tj	 |
 \}}d|||f< | }|j||j|jf< t|}n|}|S )z?
        Divide this matrix by a second sparse matrix.
        zinconsistent shapesZ_eldiv_)r'   r   )r*   rA   rp   r6   Z
issubdtyper'   Zinexactrz   r{   nanZnonzeror   r9   rV   r   r!   )rF   rJ   r   r   rV   r   rN   rN   rO   _divide_sparse  s    
z_cs_matrix._divide_sparse)NNF)N)F)T)r   )NNN)N)F)F)NNF)T)NN)T)A__name__
__module____qualname____doc__r.   rU   r   r1   rE   rf   rs   rt   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rc   Z$_cs_matrix__get_has_canonical_formatZ$_cs_matrix__set_has_canonical_formatpropertyr   ra   Z_cs_matrix__get_sortedZ_cs_matrix__set_sortedr   r   r   r]   r   rb   rp   r   rN   rN   rN   rO   r$      s   
Q



F	$""
h$







(

'L




	"

"r$   c             C   s   | d krd| }}nt | trJ| |\}}}|dkr>tdt||}nRt| r| dk rb| |7 } | | d  }}|dk s||krtd|||f ntd||fS )Nr   r   z$slicing with step != 1 not supportedz'index out of bounds: 0 <= %d < %d <= %dzexpected slice or scalar)r2   r   r:   rA   r_   r   r   	TypeError)slnumr   r   ZstriderN   rN   rO   r     s     
r   )0r   __all__warningsr   rk   numpyr6   Zscipy._lib._utilr   baser   r   r   r9   r   r	   Zdiar
    r   r   r   r   r   r   r   r   r   _indexr   Zsputilsr   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r   rN   rN   rN   rO   <module>   s.   (D         y