B
    &]\UI                 @   s   d Z ddlmZmZmZ dZddgZddlZddlZddl	Z	ddl
ZddlmZmZmZmZmZ dd	lmZ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  yddlm!Z" W n e#k
r   dd Z"Y nX G dd deee$Z%dd Z&dd Z'dS )zDictionary Of Keys based matrix    )divisionprint_functionabsolute_importzrestructuredtext en
dok_matrixisspmatrix_dokN)zipxrange	iteritemsiterkeys
itervalues   )spmatrix
isspmatrix)
isdensegetdtypeisshape	isintlikeisscalarlikeupcastupcast_scalar
IndexMixinget_index_dtypecheck_shape)isSequenceTypec             C   s   t | dpt | dpt | dS )N__len____next__next)hasattr)x r   /lib/python3.7/site-packages/scipy/sparse/dok.py_is_sequence   s    r!   c               @   sp  e Zd ZdZdZdCddZdd Zd	d
 Zdd Ze	e
jedZdDddZdd Ze
jje_e
jje_dd ZdEd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/d0 ZdFd1d2Ze
jje_d3d4 Zd5d6 Z e
j je _d7d8 Z!d9d: Z"dGd;d<Z#e
j#je#_dHd=d>Z$e
j$je$_dId?d@Z%e
j%je%_dAdB Z&e
j&je&_dS )Jr   a  
    Dictionary Of Keys based sparse matrix.

    This is an efficient structure for constructing sparse
    matrices incrementally.

    This can be instantiated in several ways:
        dok_matrix(D)
            with a dense matrix, D

        dok_matrix(S)
            with a sparse matrix, S

        dok_matrix((M,N), [dtype])
            create the matrix with initial shape (M,N)
            dtype is optional, defaulting to dtype='d'

    Attributes
    ----------
    dtype : dtype
        Data type of the matrix
    shape : 2-tuple
        Shape of the matrix
    ndim : int
        Number of dimensions (this is always 2)
    nnz
        Number of nonzero elements

    Notes
    -----

    Sparse matrices can be used in arithmetic operations: they support
    addition, subtraction, multiplication, division, and matrix power.

    Allows for efficient O(1) access of individual elements.
    Duplicates are not allowed.
    Can be efficiently converted to a coo_matrix once constructed.

    Examples
    --------
    >>> import numpy as np
    >>> from scipy.sparse import dok_matrix
    >>> S = dok_matrix((5, 5), dtype=np.float32)
    >>> for i in range(5):
    ...     for j in range(5):
    ...         S[i, j] = i + j    # Update element

    ZdokNFc       	      C   s(  t |  t|  t|td| _t|trLt|rL|\}}t	||f| _
nt|rt|rj|rj| }n| }|d k	r||}t | | t	|j| _
|j| _n~yt|}W n tk
r   tdY nX t|jdkrtdddlm} |||d }t | | t	|j| _
|j| _d S )N)defaultzInvalid input format.   z(Expected rank <=2 dense array or matrix.r   )
coo_matrix)dtype)dict__init__r   r   floatr%   
isinstancetupler   r   _shaper   r   copytodokZastypeupdateshapenpasarray	Exception	TypeErrorlencoor$   )	selfZarg1r/   r%   r,   MNr$   dr   r   r    r'   Q   s4    




zdok_matrix.__init__c             C   s   t dd S )Nz9Direct modification to dok_matrix element is not allowed.)NotImplementedError)r6   valr   r   r    r.   t   s    zdok_matrix.updatec             C   s   t | |S )zAn update method for dict data defined for direct access to
        `dok_matrix` data. Main purpose is to be used for effcient conversion
        from other spmatrix classes. Has no checking if `data` is valid.)r&   r.   )r6   datar   r   r    _updatey   s    zdok_matrix._updatec             C   s8   | j |dd| j}|j| _t|  t| | d S )NF)r,   )ZreshapeZasformatformat__dict__r&   clearr.   )r6   r/   Z
new_matrixr   r   r    	set_shape   s    
zdok_matrix.set_shape)fgetfsetc             C   s   |d k	rt dt| S )Nz6getnnz over an axis is not implemented for DOK format.)r:   r&   r   )r6   Zaxisr   r   r    getnnz   s    zdok_matrix.getnnzc             C   s   t dd t| D S )Nc             s   s   | ]}|d kV  qdS )r   Nr   ).0r   r   r   r    	<genexpr>   s    z+dok_matrix.count_nonzero.<locals>.<genexpr>)sumr   )r6   r   r   r    count_nonzero   s    zdok_matrix.count_nonzeroc             C   s
   t | S )N)r&   r   )r6   r   r   r    r      s    zdok_matrix.__len__        c          
   C   s   y |\}}t |rt |stW n" tttfk
rB   tdY nX |dk sp|| jd ksp|dk sp|| jd krxtdt| ||S )ztThis overrides the dict.get method, providing type checking
        but otherwise equivalent functionality.
        z!Index must be a pair of integers.r   r   zIndex out of bounds.)r   AssertionErrorr3   
ValueError
IndexErrorr/   r&   get)r6   keyr"   ijr   r   r    rM      s    ,zdok_matrix.getc             C   s  | j d}| |\}}t|}t|}|r|rt|}t|}|dk rX|| jd 7 }|dk sn|| jd krvtd|dk r|| jd 7 }|dk s|| jd krtdt| ||f|S |st	|t
r||st	|t
r||rt
||d n|}|rt
||d n|}|| jd }	|| jd }
t|	 }t|
 }t|t|f}t|}t| d| k r||dkr|| |	|
|S | ||\}}|jdkrt|j| j dS | }|| jd  k s| | jd krtd| | jd | jd d f |dk r(| }||dk   | jd 7  < | }|| jd  k sV| | jd kr|td| | jd | jd d f |dk r| }||dk   | jd 7  < t|j| j d}xXtt|jd t|jd D ]4}t| || || f|}|rt||| qW |S )zIf key=(i, j) is a pair of integers, return the corresponding
        element.  If either i or j is a slice or sequence, return a new sparse
        matrix with just these elements.
        r   zIndex out of bounds.r   r#   )r%   z"Index (%d) out of range -%d to %d.)r%   type_unpack_indexr   intr/   rL   r&   rM   r)   sliceindicesr   r4   _prod_getitem_ranges_index_to_arrayssizer   minmaxr,   	itertoolsproduct__setitem__)r6   indexZzerorO   rP   Z	i_intlikeZ	j_intlikeZi_sliceZj_slice	i_indices	j_indicesZi_seqZj_seqZnewshapeZnewsizemin_imin_jnewdokrN   vr   r   r    __getitem__   sf    &"
&"
&zdok_matrix.__getitem__c          
   C   s   t t|\}}}t t|\}}}	t|| jd}
xt| D ]\}}t|}t|}t|| |\}}|dk s8||d ks8|dkrq8t|| |	\}}|dk s8||d ks8|dkrq8t|
||ft| ||f q8W |
S )N)r%   r   r   )	maprS   r   r%   r
   divmodr&   r^   rf   )r6   r`   ra   r/   Zi_startZi_stopZi_strideZj_startZj_stopZj_striderd   ZiiZjjaZrabrbr   r   r    rW      s    zdok_matrix._getitem_rangesc             C   s  t |trt|dkr|\}}t|rt|rd|  krH| jd k rn nbd|  krf| jd k rn nDtj|| jd}|jdkr|dkrt	
| t|t|f|d  d S | |\}}| ||\}}t|r| }tj|| jd}t||\}}|j|jkrtdt|dkr&d S | }|| jd  k sT| | jd krztd| | jd | jd d f |dk r| }||dk   | jd 7  < | }|| jd  k s| | jd krtd| | jd | jd d f |dk r&| }||dk   | jd 7  < t	| tt|j|j|j d|kr|dk}	x8t||	 j||	 jD ]}
t	| |
dkrn| |
= qnW d S )Nr#   r   r   )r%   r   zShape mismatch in assignment.z"Index (%d) out of range -%d to %d.)r)   r*   r4   r   r/   r0   r1   r%   ndimr&   r^   rS   rR   rX   r   ZtoarrayZbroadcast_arraysrK   rY   rZ   r[   rL   r,   r.   izipZflatrf   )r6   r_   r   rO   rP   re   _rb   rc   ZzeroesrN   r   r   r    r^     sL    .&"
&"

zdok_matrix.__setitem__c          	      s$  t rjt| j}t| j|d | j\}}xtt|t|D ]"}t	| |d }|rB| |< qBW nt
rj| jkrtdt| jj}t| j|d t |  tjdd& t  fddtD  W d Q R X n8tr|  }|  ntr|    ntS  S )N)r%   r   z Matrix dimensions are not equal.ignore)Zoverc             3   s"   | ]}| | |  fV  qd S )Nr   )rE   k)newotherr   r    rF   K  s    z%dok_matrix.__add__.<locals>.<genexpr>)r   r   r%   r   r/   r\   r]   r   r&   rM   r   rK   r   r.   r0   Zerrstater
   r   tocscr   todenseNotImplemented)r6   rr   	res_dtyper7   r8   rN   aijcscr   )rq   rr   r    __add__6  s0    
&


zdok_matrix.__add__c                s   t  r`tjjd}j\}}xtt|t|D ]"}t|d  }|r8|||< q8W nt	 r jjkr|t
dtjjd}t| t| fddt D  n4t rԈ }|  }nt r   }ntS |S )N)r%   r   z Matrix dimensions are not equal.c             3   s"   | ]}||  |  fV  qd S )Nr   )rE   rp   )rr   r6   r   r    rF   c  s    z&dok_matrix.__radd__.<locals>.<genexpr>)r   r   r/   r%   r\   r]   r   r&   rM   r   rK   r.   r
   r   rs   r   rt   ru   )r6   rr   rq   r7   r8   rN   rw   rx   r   )rr   r6   r    __radd__U  s*    

zdok_matrix.__radd__c                sF    j jdkrtdt j j d}t| fddt D  |S )Nrj   z2Negating a sparse boolean matrix is not supported.)r%   c             3   s   | ]}| |  fV  qd S )Nr   )rE   rp   )r6   r   r    rF   r  s    z%dok_matrix.__neg__.<locals>.<genexpr>)r%   Zkindr:   r   r/   r&   r.   r
   )r6   rq   r   )r6   r    __neg__m  s
    zdok_matrix.__neg__c                s<   t | j }t| j|d}t| fddt| D  |S )N)r%   c             3   s   | ]\}}||  fV  qd S )Nr   )rE   rp   re   )rr   r   r    rF   y  s    z)dok_matrix._mul_scalar.<locals>.<genexpr>)r   r%   r   r/   r&   r.   r	   )r6   rr   rv   rq   r   )rr   r    _mul_scalaru  s    zdok_matrix._mul_scalarc             C   sT   t j| jd t| j|jd}x0t| D ]$\\}}}||  |||  7  < q(W |S )Nr   )r%   )r0   zerosr/   r   r%   r	   )r6   rr   resultrO   rP   re   r   r   r    _mul_vector|  s    zdok_matrix._mul_vectorc          	   C   sv   | j d |j d f}t| j|j}tj||d}x@t| D ]4\\}}}||d d f  |||d d f  7  < q:W |S )Nr   r   )r%   )r/   r   r%   r0   r}   r	   )r6   rr   Zresult_shapeZresult_dtyper~   rO   rP   re   r   r   r    _mul_multivector  s    ,zdok_matrix._mul_multivectorc                s.   t  r*t|  fddt| D  | S tS )Nc             3   s   | ]\}}||  fV  qd S )Nr   )rE   rp   re   )rr   r   r    rF     s    z&dok_matrix.__imul__.<locals>.<genexpr>)r   r&   r.   r	   ru   )r6   rr   r   )rr   r    __imul__  s    zdok_matrix.__imul__c                sP   t  rDt| j }t| j|d}t| fddt| D  |S |    S )N)r%   c             3   s   | ]\}}||  fV  qd S )Nr   )rE   rp   re   )rr   r   r    rF     s    z)dok_matrix.__truediv__.<locals>.<genexpr>)	r   r   r%   r   r/   r&   r.   r	   Ztocsr)r6   rr   rv   rq   r   )rr   r    __truediv__  s    zdok_matrix.__truediv__c                s.   t  r*t|  fddt| D  | S tS )Nc             3   s   | ]\}}||  fV  qd S )Nr   )rE   rp   re   )rr   r   r    rF     s    z*dok_matrix.__itruediv__.<locals>.<genexpr>)r   r&   r.   r	   ru   )r6   rr   r   )rr   r    __itruediv__  s    zdok_matrix.__itruediv__c             C   s
   t | S )N)r&   
__reduce__)r6   r   r   r    r     s    zdok_matrix.__reduce__c             C   sL   |d k	rt d| j\}}t||f| j|d}t|dd t| D  |S )NzoSparse matrices do not support an 'axes' parameter because swapping dimensions is the only logical permutation.)r%   r,   c             s   s"   | ]\\}}}||f|fV  qd S )Nr   )rE   leftrightr;   r   r   r    rF     s   z'dok_matrix.transpose.<locals>.<genexpr>)rK   r/   r   r%   r&   r.   r	   )r6   Zaxesr,   r7   r8   rq   r   r   r    	transpose  s    
zdok_matrix.transposec             C   s:   | j \}}t||f| jd}t|dd t| D  |S )zReturn the conjugate transpose.)r%   c             s   s(   | ] \\}}}||ft |fV  qd S )N)r0   Zconj)rE   r   r   r;   r   r   r    rF     s   z(dok_matrix.conjtransp.<locals>.<genexpr>)r/   r   r%   r&   r.   r	   )r6   r7   r8   rq   r   r   r    
conjtransp  s
    
zdok_matrix.conjtranspc             C   s    t | j| jd}t||  |S )N)r%   )r   r/   r%   r&   r.   )r6   rq   r   r   r    r,     s    zdok_matrix.copyc                sB   t djd fjd}t| fddtjd D  |S )z-Returns the i-th row as a (1 x n) DOK matrix.r   )r%   c             3   s"   | ]}d |f |f fV  qdS )r   Nr   )rE   rP   )rO   r6   r   r    rF     s    z$dok_matrix.getrow.<locals>.<genexpr>)r   r/   r%   r&   r.   r   )r6   rO   rq   r   )rO   r6   r    getrow  s    &zdok_matrix.getrowc                sB   t jd dfjd}t| fddtjd D  |S )z0Returns the j-th column as a (m x 1) DOK matrix.r   r   )r%   c             3   s"   | ]}|d f| f fV  qdS )r   Nr   )rE   rO   )rP   r6   r   r    rF     s    z$dok_matrix.getcol.<locals>.<genexpr>)r   r/   r%   r&   r.   r   )r6   rP   rq   r   )rP   r6   r    getcol  s    &zdok_matrix.getcolc             C   s   ddl m} | jdkr&|| j| jdS tt| jd}tjt	| | j| jd}tjdd t
| D || jd}tjd	d t
| D || jd}||||ff| j| jd
}d|_|S )Nr   )r$   r   )r%   )Zmaxval)r%   countc             s   s   | ]\}}|V  qd S )Nr   )rE   rO   rn   r   r   r    rF     s    z#dok_matrix.tocoo.<locals>.<genexpr>c             s   s   | ]\}}|V  qd S )Nr   )rE   rn   rP   r   r   r    rF     s    )r/   r%   T)r5   r$   Znnzr/   r%   r   r[   r0   Zfromiterr   r
   Zhas_canonical_format)r6   r,   r$   Z	idx_dtyper<   rowcolAr   r   r    tocoo  s    
  zdok_matrix.tocooc             C   s   |r|   S | S )N)r,   )r6   r,   r   r   r    r-     s    zdok_matrix.todokc             C   s   | j ddj|dS )NF)r,   )r   rs   )r6   r,   r   r   r    rs     s    zdok_matrix.tocscc             G   sh   t |}|\}}| j\}}||k s*||k r^x2tt| D ]"\}}||ksP||kr8| ||f= q8W || _d S )N)r   r/   listr
   r+   )r6   r/   ZnewMZnewNr7   r8   rO   rP   r   r   r    resize  s    
zdok_matrix.resize)NNF)N)rI   )NF)F)F)F)'__name__
__module____qualname____doc__r>   r'   r.   r=   rA   propertyr   Z	get_shaper/   rD   rH   r   rM   rf   rW   r^   ry   rz   r{   r|   r   r   r   r   r   r   r   r   r,   r   r   r   r-   rs   r   r   r   r   r    r      sR   0
#



J4	









c             C   s
   t | tS )a  Is x of dok_matrix type?

    Parameters
    ----------
    x
        object to check for being a dok matrix

    Returns
    -------
    bool
        True if x is a dok matrix, False otherwise

    Examples
    --------
    >>> from scipy.sparse import dok_matrix, isspmatrix_dok
    >>> isspmatrix_dok(dok_matrix([[5]]))
    True

    >>> from scipy.sparse import dok_matrix, csr_matrix, isspmatrix_dok
    >>> isspmatrix_dok(csr_matrix([[5]]))
    False
    )r)   r   )r   r   r   r    r     s    c             C   s   t | dkrdS ttj| S )zFProduct of a list of numbers; ~40x faster vs np.prod for Python tuplesr   r   )r4   	functoolsreduceoperatormul)r   r   r   r    rV     s    rV   )(r   Z
__future__r   r   r   Z__docformat____all__r   r   r\   Znumpyr0   Zscipy._lib.sixr   rm   r   r	   r
   r   baser   r   Zsputilsr   r   r   r   r   r   r   r   r   r   r   r!   ImportErrorr&   r   r   rV   r   r   r   r    <module>   s(   0   a