B
    &]\                 @   s   d Z ddlmZmZm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 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#m$Z$m%Z%m&Z&m'Z' G dd deee#Z(dS )z>Base class for sparse matrix formats using compressed storage.    )divisionprint_functionabsolute_import)warnN)zip)_prune_array   )spmatrix
isspmatrixSparseEfficiencyWarning)_data_matrix_minmax_mixin)
dia_matrix)_sparsetools)upcastupcast_char	to_nativeisdenseisshapegetdtypeisscalarlike
IndexMixinget_index_dtypedowncast_intp_indexget_sum_dtypecheck_shapec               @   s  e Zd ZdZdgddZdhddZejje_didd	Zdjd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dkd,d-Zejje_d.d/ Zd0d1 Zejje_d2d3 Zejje_dld4d5Zejje_dmd6d7Zd8d9 Zd:d; Zd<d= Z d>d? Z!d@dA Z"dBdC Z#dDdE Z$dFdG Z%dndHdIZ&ej&je&_dodJdKZ'ej'je'_dLdM Z(dNdO Z)dPdQ Z*e+e)e*dRZ,dSdT Z-dUdV Z.dWdX Z/e+e.e/dRZ0dYdZ Z1d[d\ Z2d]d^ Z3d_d` Z4ej4je4_dpdadbZ5dcdd Z6dedf Z7dS )q
_cs_matrixzAbase 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rt|\}
}}d }|d k	r*t|}t||f|d
d}tj|||d| _tj|||d| _tj|
||d| _ntd| jnZyt|}W n& tk
r   td| jY nX ddlm} | | |||d |d k	rt
|| _n`| jd krVy t| jd }| j d }W n tk
r@   tdY nX t
| ||f| _|d k	rrtj| j|d| _| jdd d S )N)maxvalr   )defaultr   )dtype   )
coo_matrix)shape   T)r   Zcheck_contents)copyr   z(unrecognized {}_matrix constructor usagez!unable to infer matrix dimensionsF)
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check_format)selfZarg1r"   r   r$   MN	idx_dtyper!   otherr1   r2   r4   r   	major_dim	minor_dim rD   6lib/python3.7/site-packages/scipy/sparse/compressed.pyr&      sj    








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)
intr4   r3   r"   r.   Zbincountr   r2   diffr9   )r=   axis_r?   rD   rD   rE   getnnzi   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$   r1   r2   r4   r   r"   r,   )r=   rA   r$   rD   rD   rE   r)   z   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 sizerF   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)r3   r"   r4   r   kindr   r'   namer2   r   r.   r:   r   r1   ndimr9   r5   prunennzr-   minrH   )r=   r%   Z
major_nameZ
minor_namerB   rC   r@   xrD   rD   rE   r<      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_datar1   eliminate_zeros)r=   rA   opresrD   rD   rE   _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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#   )rO   zHComparing sparse matrices using == is inefficient, try using != instead.F_ne_)r   r.   isnanr7   r"   bool_r   r   onesr\   operatorneeqr   todenser
   r'   r(   _binopt)r=   rA   all_trueinvr[   rD   rD   rE   __eq__   s0    

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 nTt|r|  |k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#   )rO   )r   r   z^Comparing a sparse matrix with a nonzero scalar using != is inefficient, try using == instead.Tr]   )r   r.   r^   r   r   r7   r`   r"   r_   r\   ra   rc   rb   r   rd   r
   r'   r(   re   )r=   rA   rf   rg   rD   rD   rE   __ne__   s,    


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)rk   rj   zUComparing sparse matrices using >= and <= is inefficient, using <, >, or !=, instead.rj   _gt__lt_zOperands could not be compared.)r   NotImplementedErrorr   r   r.   emptyr"   Zresult_typefillr7   re   r\   r   rd   r
   r9   r'   r(   r`   r_   )r=   rA   rZ   op_nameZbad_scalar_msg	other_arrrf   r[   rD   rD   rE   _inequality  s2    






z_cs_matrix._inequalityc             C   s   |  |tjddS )Nrm   zgComparing a sparse matrix with a scalar greater than zero using < is inefficient, try using >= instead.)rs   ra   lt)r=   rA   rD   rD   rE   __lt__6  s    z_cs_matrix.__lt__c             C   s   |  |tjddS )Nrl   zdComparing a sparse matrix with a scalar less than zero using > is inefficient, try using <= instead.)rs   ra   gt)r=   rA   rD   rD   rE   __gt__<  s    z_cs_matrix.__gt__c             C   s   |  |tjddS )Nrj   zgComparing a sparse matrix with a scalar greater than zero using <= is inefficient, try using > instead.)rs   ra   le)r=   rA   rD   rD   rE   __le__B  s    z_cs_matrix.__le__c             C   s   |  |tjddS )Nrk   zdComparing a sparse matrix with a scalar less than zero using >= is inefficient, try using < instead.)rs   ra   ge)r=   rA   rD   rD   rE   __ge__H  s    z_cs_matrix.__ge__c             C   s   |j | j krtdt| jj|jj}| dd }tj|||dd}| | j \}}|jj	rb|n|j
}t||| j| j| j| tj|ddS )NzIncompatible shapes.ZCFr   T)r   orderr$   F)r$   )r"   r9   r   r   charr3   r.   r8   flagsc_contiguousTr   csr_todenser4   r2   r1   matrix)r=   rA   r   r|   resultr>   r?   yrD   rD   rE   
_add_denseR  s    z_cs_matrix._add_densec             C   s   |  |dS )NZ_plus_)re   )r=   rA   rD   rD   rE   _add_sparse]  s    z_cs_matrix._add_sparsec             C   s   |  |dS )NZ_minus_)re   )r=   rA   rD   rD   rE   _sub_sparse`  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"   r7   re   toarray_mul_sparse_matrixtocscr   ravelr9   r.   Z
atleast_2drR   multiplysizeZflatr6   r!   tocoor1   rL   colrepeataranger5   tileZviewZndarray)r=   rA   r$   r!   retr1   rL   r   rD   rD   rE   r   c  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"   r.   r/   r   r   r}   getattrr   r'   r4   r2   r1   )r=   rA   r>   r?   r   fnrD   rD   rE   _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"   r.   r/   r   r   r}   r   r   r'   r4   r2   r1   r   )r=   rA   r>   r?   Zn_vecsr   r   rD   rD   rE   _mul_multivector  s    


z_cs_matrix._mul_multivectorc             C   s  | j \}}|j \}}| ||fd }| |}t| j| j|j|jf|| d}tj|d |d}tt	| j
d }	|	||tj| j|dtj| j|dtj|j|dtj|j|d| |d }
t| j| j|j|jf|
d}tj||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   )r   r   )r   Z_matmat_pass1rF   Z_matmat_pass2)r"   )r"   r3   r7   r   r4   r2   r.   ro   r   r   r'   r:   r   r   r1   )r=   rA   r>   ZK1ZK2r?   Z
major_axisr@   r4   r   rT   r2   r1   rD   rD   rE   r     s>    







z_cs_matrix._mul_sparse_matrixr   c             C   s   | j \}}|| ks||kr$tdtt| jd }tjt|t|d |t|d t	| j
d}||| j d | j d | j| j| j| |S )Nzk exceeds matrix dimensionsZ	_diagonalr   )r   r   )r"   r9   r   r   r'   r.   ro   rU   r-   r   r   r4   r2   r1   )r=   kZrowsZcolsr   r   rD   rD   rE   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#   )rO   )r   )r   r"   zOperands not compatible.)r   r   r   r.   ro   r"   r:   r   rp   r7   re   rW   r1   r2   r4   r   rd   r
   r9   )r=   rA   Znpoprq   Zdense_checkrr   Znew_dataZmatrD   rD   rE   _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   )r.   r:   )rV   rD   rD   rE   <lambda>7  s    z$_cs_matrix.maximum.<locals>.<lambda>)r   r.   maximum)r=   rA   rD   rD   rE   r   5  s    
z_cs_matrix.maximumc             C   s   |  |tjddd S )NZ	_minimum_c             S   s   t | dk S )Nr   )r.   r:   )rV   rD   rD   rE   r   =  s    z$_cs_matrix.minimum.<locals>.<lambda>)r   r.   minimum)r=   rA   rD   rD   rE   r   ;  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rr|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   rF   )r   r    r   r   )r   r    Nzdimensions do not matchrD   )rI   r   out)hasattrr3   r   r   r.   r/   r5   r4   _minor_reduceaddZasmatrixr   r"   r9   sumr	   )r=   rI   r   r   Z	res_dtyper   major_indexvaluerD   rD   rE   r   E  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)r1   r.   ZflatnonzerorH   r4   Zreduceatr   )r=   Zufuncr1   r   r   rD   rD   rE   r   b  s    z_cs_matrix._minor_reducec             C   s  |  |\}}| ||\}}t|r|jd dkoB|jd dk}|jd dko^|jd dk}|sx|jd |jd kr|s|jd |jd kstd| | | f\}}| || |jdd}|	  |j
|j }	}
tj|j| jd}|r8tt|jd t|	}	t|
|jd }
t||jd }|r~t|	|jd }	tt|jd t|
}
t||jd }||	|
f }||	|
f }n6tj|| jd}t||\}}|j|jkrtdt|dkrd S | | | f\}}| |||  d S )Nr   r   zshape mismatch in assignmentT)r$   )r   )Z_unpack_indexZ_index_to_arraysr
   r"   r9   r3   r   
_zero_manyr   rW   rL   r   r.   r:   r1   r   r   r   r5   r   Zbroadcast_arraysr   	_set_many)r=   indexrV   rN   jZbroadcast_rowZbroadcast_colZciZcjrcrJ   rD   rD   rE   __setitem__|  s@    
z_cs_matrix.__setitem__c       	      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"   rR   rU   r5   r.   r   r2   r   )	r=   valuesr   r>   r?   Z	broadcastZ	max_indexrN   r   rD   rD   rE   _setdiag  s(    



z_cs_matrix._setdiagc             C   s\   |  | j\}}dd }||| ||| tj|| jjd}tj|| jj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))r-   
IndexErrorrU   )r2   ZboundidxrD   rD   rE   check_bounds  s    
z1_cs_matrix._prepare_indices.<locals>.check_bounds)r   )r3   r"   r.   r:   r2   r   )r=   rN   r   r>   r?   r   rD   rD   rE   _prepare_indices  s    


z_cs_matrix._prepare_indicesc       
   
   C   s  |  ||\}}}}t|}tj|| jjd}t||| j| j||||}|dkrv| 	  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.
        )r   r   rF   NzZChanging the sparsity structure of a {}_matrix is expensive. lil_matrix is more efficient.r#   )rO   r   )r   r5   r.   ro   r2   r   r   csr_sample_offsetsr4   rW   r1   r   r'   r   _insert_many)
r=   rN   r   rV   r>   r?   	n_samplesoffsetsr   maskrD   rD   rE   r     s0    


z_cs_matrix._set_manyc          
   C   s   |  ||\}}}}t|}tj|| jjd}t||| j| j||||}|dkrv| 	  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   rF   N)r   r5   r.   ro   r2   r   r   r   r4   rW   r1   )r=   rN   r   r>   r?   r   r   r   rD   rD   rE   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)rP   Zclip)moderF   )r   )r   T)Zreturn_indexr   r   N)r   F)r%   )r.   ZargsortZtakehas_sorted_indicesr   r2   r4   r   r:   uniqueappendr5   rH   	enumerateizipr1   Zconcatenatero   r"   cumsumsort_indicesr<   )r=   rN   r   rV   r|   Zdo_sortr@   Zindices_partsZ
data_partsZuiZ	ui_indptrZnew_nnzsprevr   ZiiZjsZjestartstopZujZ	uj_indptrZnnzsZindptr_diffrD   rD   rE   r     sZ    	
*

$  
z_cs_matrix._insert_manyc             C   s8  | j \}}|dk r||7 }|dk r*||7 }d|  kr>|k rXn nd|  krV|k sln td||||f | ||f\}}| j| }| j|d  }| jr| jj|}| j|| }	tj	|	|dd}
|
tj	|	|
d  |dd }| j
||
 ||  j| jdS t|| j|| k| j
|| j| jdS d S )Nr   z'index out of bounds: 0<=%d<%d, 0<=%d<%dr   left)Zsideright)r   )r"   r   r3   r4   r   r2   r   typer.   Zsearchsortedr1   r   compress)r=   rL   r   r>   r?   r   Zminor_indexr   endminor_indicesZinsert_pos_leftZinsert_pos_rightrD   rD   rE   _get_single_element^  s,    
.

z_cs_matrix._get_single_elementc             C   s   |  ||f\}}|  | j\}}dd }dd }|||\}}|||\}	}
|||| ||	|
| t||| j| j| j|||	|
	}|d |d |d   }}}|  || |
|	 f}| j|||f|dS )	z:Return a submatrix of this matrix (new matrix is created).c             S   s   t | tr\| j| j }}|d kr&d}n|dk r6|| }|d krD|}n|dk rT|| }||fS t| r| dk rv| |7 } | | d fS | d | d fS d S )Nr   r   )r*   slicer   r   r.   Zisscalar)Zslnumi0i1rD   rD   rE   _process_slice  s     

z1_cs_matrix._get_submatrix.<locals>._process_slicec             S   sP   d|   kr|k r8n n d|  k r,|kr8n n| |k sLt dj| ||dd S )Nr   z<index out of bounds: 0<={i0}<{num}, 0<={i1}<{num}, {i0}<{i1})r   r   r   )r   r'   )r   r   r   rD   rD   rE   
_in_bounds  s    8z-_cs_matrix._get_submatrix.<locals>._in_boundsr    r   r   )r"   )r3   r"   r   Zget_csr_submatrixr4   r2   r1   r7   )r=   Zslice0Zslice1Zshape0Zshape1r   r   r   r   Zj0Zj1Zauxr1   r2   r4   r"   rD   rD   rE   _get_submatrix{  s    z_cs_matrix._get_submatrixc       	      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   )r3   r"   r2   r.   ro   r5   r   r   Z	expandptrr4   r6   r!   r1   )	r=   r$   rB   rC   r   Zmajor_indicesrL   r   r!   rD   rD   rE   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 )NZcfr   z&Output array must be C or F contiguous)r3   Z_process_toarray_argsr~   r   f_contiguousr9   Ztocsrr   r   r"   r   r   r4   r2   r1   )r=   r|   r   rV   r   r>   r?   rD   rD   rE   r     s    z_cs_matrix.toarrayc             C   s4   |  | j\}}t||| j| j| j |   dS )zURemove zero entries from the matrix

        This is an *in place* operation
        N)r3   r"   r   Zcsr_eliminate_zerosr4   r2   r1   rS   )r=   r>   r?   rD   rD   rE   rY     s    z_cs_matrix.eliminate_zerosc             C   sB   t | ddsd| _n(t| ds<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   r   Zcsr_has_canonical_formatr5   r4   r2   has_canonical_format)r=   rD   rD   rE   Z__get_has_canonical_format  s    
z%_cs_matrix.__get_has_canonical_formatc             C   s   t || _|rd| _d S )NT)boolr   r   )r=   valrD   rD   rE   Z__set_has_canonical_format  s    
z%_cs_matrix.__set_has_canonical_format)fgetfsetc             C   sL   | j r
dS |   | | j\}}t||| j| j| j | 	  d| _ dS )zkEliminate duplicate matrix entries by adding them together

        The is an *in place* operation
        NT)
r   r   r3   r"   r   Zcsr_sum_duplicatesr4   r2   r1   rS   )r=   r>   r?   rD   rD   rE   rW     s    z_cs_matrix.sum_duplicatesc             C   s.   t | ds(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   Zcsr_has_sorted_indicesr5   r4   r2   r   )r=   rD   rD   rE   Z__get_sorted  s    

z_cs_matrix.__get_sortedc             C   s   t || _d S )N)r   r   )r=   r   rD   rD   rE   Z__set_sorted  s    z_cs_matrix.__set_sortedc             C   s   |   }|  |S )z9Return a copy of this matrix with sorted indices
        )r$   r   )r=   ArD   rD   rE   sorted_indices!  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_indicesr5   r4   r2   r1   )r=   rD   rD   rE   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)	r3   r"   r5   r4   r9   r2   rT   r1   r   )r=   rB   rD   rD   rE   rS   5  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   divmodr9   r"   r3   r2   r4   r1   r.   resizerp   allr   r   r   r,   )r=   r"   ZbmZbnZnew_MZrmZnew_NZrnr>   r?   r   r   r   rD   rD   rE   r   D  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)r7   r2   r$   r4   r"   r   )r=   r1   r$   rD   rD   rE   rX   m  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   r]   rm   rl   rj   rk   r   r   )r"   )r7   r   r   r'   rT   r   r4   r2   r.   ro   r"   r_   r   r   r:   r1   rS   )r=   rA   rZ   r   Zmaxnnzr@   r4   r2   Zbool_opsr1   r   rD   rD   rE   re   {  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"   r9   re   r.   Z
issubdtyper   Zinexactro   rp   nanZnonzeror   r1   rL   r   r   )r=   rA   r   r   rL   r   rD   rD   rE   _divide_sparse  s    z_cs_matrix._divide_sparse)NNF)N)F)T)r   )NNN)N)T)NN)T)8__name__
__module____qualname____doc__r&   rK   r	   r)   r<   r\   rh   ri   rs   ru   rw   ry   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rY   Z$_cs_matrix__get_has_canonical_formatZ$_cs_matrix__set_has_canonical_formatpropertyr   rW   Z_cs_matrix__get_sortedZ_cs_matrix__set_sortedr   r   r   rS   r   rX   re   r   rD   rD   rD   rE   r      sx   
P



F	!"
h'






,'H7




	"

"r   ))r   Z
__future__r   r   r   __all__warningsr   ra   Znumpyr.   Zscipy._lib.sixr   r   Zscipy._lib._utilr   baser	   r
   r   r1   r   r   Zdiar    r   Zsputilsr   r   r   r   r   r   r   r   r   r   r   r   r   rD   rD   rD   rE   <module>   s   8