B
    &]\6                 @   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	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 ddlmZ G dd deZdd ZdS )zSparse DIAgonal format    )divisionprint_functionabsolute_importzrestructuredtext en
dia_matrixisspmatrix_diaN   )
isspmatrix_formatsspmatrix)_data_matrix)isshapeupcast_chargetdtypeget_index_dtypeget_sum_dtypevalidateaxischeck_shape)
dia_matvecc               @   s  e Zd ZdZdZd'ddZdd Zd	d
 Zdd Zd(ddZ	e
j	je	_e
jje_d)ddZe
jje_dd Zdd Zd*ddZd+ddZe
jje_d,ddZe
jje_d-ddZe
jje_d.ddZe
jje_d/d d!Ze
jje_d0d#d$Zd%d& Ze
jje_dS )1r   a   Sparse matrix with DIAgonal storage

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

        dia_matrix(S)
            with another sparse matrix S (equivalent to S.todia())

        dia_matrix((M, N), [dtype])
            to construct an empty matrix with shape (M, N),
            dtype is optional, defaulting to dtype='d'.

        dia_matrix((data, offsets), shape=(M, N))
            where the ``data[k,:]`` stores the diagonal entries for
            diagonal ``offsets[k]`` (See example below)

    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
    data
        DIA format data array of the matrix
    offsets
        DIA format offset array of the matrix

    Notes
    -----

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

    Examples
    --------

    >>> import numpy as np
    >>> from scipy.sparse import dia_matrix
    >>> dia_matrix((3, 4), dtype=np.int8).toarray()
    array([[0, 0, 0, 0],
           [0, 0, 0, 0],
           [0, 0, 0, 0]], dtype=int8)

    >>> data = np.array([[1, 2, 3, 4]]).repeat(3, axis=0)
    >>> offsets = np.array([0, -1, 2])
    >>> dia_matrix((data, offsets), shape=(4, 4)).toarray()
    array([[1, 0, 3, 0],
           [1, 2, 0, 4],
           [0, 2, 3, 0],
           [0, 0, 3, 4]])

    ZdiaNFc       
      C   sv  t |  t|r>|r| }|j| _|j| _t|j| _nt	|rt|r\|r\| }n|
 }|j| _|j| _t|j| _nPt|trft|rt|| _tdt|td| _tt| jd}tjd|d| _ny|\}}W n tk
r   tdY n`X |d krtdttj|d ||d| _ttj|d	 tt|d|d| _t|| _nnyt|}W n$ tk
r   td
| j Y nX d	dlm}	 |	|||d
 }|j| _|j| _t|j| _|d k	r| j|| _| jjd	krtd| jjdkrtd| jjd t| jkrNtd| jjd t| jf tt | jt| jkrrtdd S )N)r   r   )default)maxvalr   )dtypez,unrecognized form for dia_matrix constructorzexpected a shape argument)r   copyr   z+unrecognized form for %s_matrix constructor)
coo_matrix)r   shapezoffsets array must have rank 1   zdata array must have rank 2zBnumber of diagonals (%d) does not match the number of offsets (%d)z&offset array contains duplicate values)!r   __init__r   r   dataoffsetsr   r   _shaper   todia
isinstancetupler   npzerosr   floatr   max	Exception
ValueErrorZ
atleast_2dZarrayZ
atleast_1dZasarrayformatcoor   astypendimlenunique)
selfZarg1r   r   r   A	idx_dtyper   r   r    r1   /lib/python3.7/site-packages/scipy/sparse/dia.pyr   N   sh    




zdia_matrix.__init__c             C   s4   t |   d }d| j| jj| j| jjd |f  S )Nr   zW<%dx%d sparse matrix of type '%s'
	with %d stored elements (%d diagonals) in %s format>r   )r	   Z	getformatr   r   typennzr   )r.   r(   r1   r1   r2   __repr__   s    zdia_matrix.__repr__c             C   sV   | j \}}t| jj d }|| jdddf  }|dk}|||k M }|||k M }|S )z~Returns a mask of the same shape as self.data, where
        mask[i,j] is True when data[i,j] corresponds to a stored element.r   Nr   )r   r"   aranger   r   )r.   num_rowsnum_colsoffset_indsrowmaskr1   r1   r2   
_data_mask   s    
zdia_matrix._data_maskc             C   s   |   }t| j| S )N)r<   r"   count_nonzeror   )r.   r;   r1   r1   r2   r=      s    zdia_matrix.count_nonzeroc             C   sd   |d k	rt d| j\}}d}x<| jD ]2}|dkrF|t||| 7 }q&|t|| |7 }q&W t|S )Nz5getnnz over an axis is not implemented for DIA formatr   )NotImplementedErrorr   r   minint)r.   axisMNr4   kr1   r1   r2   getnnz   s    
zdia_matrix.getnnzc          	   C   sX  t | |d k	r |dk r |d7 }t| j}| j\}}d }|dkr|  }| j| jdd}	|	jd |krn|	}
n"tj||	jd}
|	|
d |	jd < tj	|
|d}ntj||d}tj
||d}t||t| j| jjd | j| j|| t	|}|d kr|j||dS |d k	r|j}t	|j|d}|d k	rH|j|jkrHtd|jd||d	S )
Nr   r   )rA   )r   r   )r   outzdimensions do not matchr1   )rA   r   rF   )r   r   r   r   r<   r   sumr"   r#   ZmatrixZonesr   r,   r   Tr'   )r.   rA   r   rF   Z	res_dtyper7   r8   Zretr;   xZresZrow_sumsZoner1   r1   r2   rG      s6    




zdia_matrix.sumc          
   C   sh   |}t j| jd t| jj|jjd}| jjd }| j\}}t||t| j	|| j	| j|
 |
  |S )Nr   )r   r   )r"   r#   r   r   r   charr   r   r,   r   ravel)r.   otherrI   yLrB   rC   r1   r1   r2   _mul_vector   s    
(zdia_matrix._mul_vectorc                s   t  fdd|jD S )Nc                s   g | ]}  |d dqS )r   )rO   Zreshape).0col)r.   r1   r2   
<listcomp>   s    z/dia_matrix._mul_multimatrix.<locals>.<listcomp>)r"   hstackrH   )r.   rL   r1   )r.   r2   _mul_multimatrix   s    zdia_matrix._mul_multimatrixr   c             C   s"  | j \}}|jdkrtj}nt|}|dk rFt|| ||}d}|}nt||| |}|}|| }|jdkrx|d | }|| jkr|| j| j|k||f< nt| j| jj	
|| _t|| jj d }	tj| jj d d |	f| jj	d}
| j|
d dd | jj d f< ||
d||f< |
| _d S )Nr   r   )r   rP   )r   r+   r"   infr,   r?   r   r   appendr   r3   r%   r#   )r.   valuesrD   rB   rC   Zvalues_nnZ	min_indexZ	max_indexmr   r1   r1   r2   _setdiag   s*    



"zdia_matrix._setdiagc             C   s   |r|   S | S d S )N)r   )r.   r   r1   r1   r2   r     s    zdia_matrix.todiac             C   s   |d k	rt d| j\}}t| j}| j }tjt|tjdd d d f }tj|tjd|| d d d f  }td|| jjd  }	t	| jtj
| jjd |	f| jjdf}
|
||f }
t|
|f||f|dS )NzoSparse matrices do not support an 'axes' parameter because swapping dimensions is the only logical permutation.)r   r   r   )r   r   )r'   r   r%   r   r"   r6   r,   Zintcr   rT   r#   r   r   )r.   Zaxesr   r7   r8   Zmax_dimr   rcZ
pad_amountr   r1   r1   r2   	transpose  s    

 $zdia_matrix.transposec             C   s   | j \}}|| ks||kr$tdt| j|k\}td|t|| | }}|jdkrptj|| | j	j
dS | j	|d ||f S )Nzk exceeds matrix dimensionsr   )r   )r   r'   r"   Znonzeror   r%   r?   sizer#   r   r   )r.   rD   ZrowsZcolsidxZ	first_colZlast_colr1   r1   r2   diagonal6  s    

zdia_matrix.diagonalc             C   s  ddl m} | jdkr&|| j| jdS | j\}}| jj\}}t|}|| jd d d f  }|dk}	|	||k M }	|	||k M }	|	| jdkM }	t	t
| jd}
tj|d |
d}t|	jdd|d|d < || ||d d < |j|	j j|
dd}| jj|	j }||||f| j| jd	S )
Nr   )
csc_matrixr   )r   )r   )rA   F)r   )r   r   )Zcscrb   r4   r   r   r   r"   r6   r   r   r%   r#   ZcumsumrG   rH   r*   )r.   r   rb   r7   r8   num_offsets
offset_lenr9   r:   r;   r0   Zindptrindicesr   r1   r1   r2   tocscB  s&    


zdia_matrix.tocscc             C   s   | j \}}| jj \}}t|}|| jd d d f  }|dk}|||k M }|||k M }|| jdkM }|| }t|||  }	| j| }
ddlm} ||
||	ff| j | j	d}d|_
|S )Nr   r   )r   )r   r   T)r   r   r"   r6   r   ZtilerK   r)   r   r   Zhas_canonical_format)r.   r   r7   r8   rc   rd   r9   r:   r;   rR   r   r   r/   r1   r1   r2   tocoo\  s    


zdia_matrix.tocooTc             C   s4   |rt || j f| jdS t || jf| jdS dS )zReturns a matrix with the same sparsity structure as self,
        but with different data.  By default the structure arrays are copied.
        )r   N)r   r   r   r   )r.   r   r   r1   r1   r2   
_with_datar  s    zdia_matrix._with_datac             G   s   t |}|\}}| jd d d |f | _|| jd krt| j| jd  | jjd k r| jd d d f | jd  t| jjd k}d| j|< || _d S )Nr   r   )r   r   r   r"   anyr   r6   r   )r.   r   rB   rC   r;   r1   r1   r2   resize{  s    "
zdia_matrix.resize)NNF)N)NNN)r   )F)NF)r   )F)F)T)__name__
__module____qualname____doc__r(   r   r5   r<   r=   rE   r
   rG   rO   rU   r[   r   r^   ra   rf   rg   rh   rj   r1   r1   r1   r2   r      s6   9
F



)

 











	c             C   s
   t | tS )a  Is x of dia_matrix type?

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

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

    Examples
    --------
    >>> from scipy.sparse import dia_matrix, isspmatrix_dia
    >>> isspmatrix_dia(dia_matrix([[5]]))
    True

    >>> from scipy.sparse import dia_matrix, csr_matrix, isspmatrix_dia
    >>> isspmatrix_dia(csr_matrix([[5]]))
    False
    )r    r   )rI   r1   r1   r2   r     s    )rn   Z
__future__r   r   r   Z__docformat____all__Znumpyr"   baser   r	   r
   r   r   Zsputilsr   r   r   r   r   r   r   Z_sparsetoolsr   r   r   r1   r1   r1   r2   <module>   s   $  }