U
    Š±Ëhó  ã                   @   sœ   d dl mZ d dlmZmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZ d dlZG d	d
„ d
eƒZG dd„ deeƒZG dd„ de
eƒZdS )é    )ÚBasic)ÚDictÚTuple)ÚS)Ú_sympify)ÚMutableNDimArray)Ú	NDimArrayÚImmutableNDimArray)ÚflattenNc                   @   s8   e Zd Zdd„ Zdd„ Zedd„ ƒZdd„ Zd	d
„ ZdS )ÚSparseNDimArrayc                 O   s
   t ||ŽS ©N©ÚImmutableSparseNDimArray)ÚselfÚargsÚkwargs© r   úH/tmp/pip-unpacked-wheel-6t8vlncq/sympy/tensor/array/sparse_ndim_array.pyÚ__new__   s    zSparseNDimArray.__new__c                    sž   ˆ  ˆ ¡}|dk	r|S ˆ ˆ ¡‰ tˆ tƒr€tdd„ ˆ D ƒƒr€ˆ ˆ ¡\}}‡fdd„|D ƒ}‡ fdd„t|ƒD ƒ}tˆƒ||ƒS ˆ ˆ ¡‰ ˆj	 
ˆ tj¡S dS )aP  
        Get an element from a sparse N-dim array.

        Examples
        ========

        >>> from sympy import MutableSparseNDimArray
        >>> a = MutableSparseNDimArray(range(4), (2, 2))
        >>> a
        [[0, 1], [2, 3]]
        >>> a[0, 0]
        0
        >>> a[1, 1]
        3
        >>> a[0]
        [0, 1]
        >>> a[1]
        [2, 3]

        Symbolic indexing:

        >>> from sympy.abc import i, j
        >>> a[i, j]
        [[0, 1], [2, 3]][i, j]

        Replace `i` and `j` to get element `(0, 0)`:

        >>> a[i, j].subs({i: 0, j: 0})
        0

        Nc                 s   s   | ]}t |tƒV  qd S r   ©Ú
isinstanceÚslice©Ú.0Úir   r   r   Ú	<genexpr>7   s     z.SparseNDimArray.__getitem__.<locals>.<genexpr>c                    s"   g | ]}ˆ j  ˆ  |¡tj¡‘qS r   )Ú_sparse_arrayÚgetÚ_parse_indexr   ÚZeror   ©r   r   r   Ú
<listcomp>9   s     z/SparseNDimArray.__getitem__.<locals>.<listcomp>c                    s&   g | ]\}}t ˆ | tƒrt|ƒ‘qS r   )r   r   Úlen)r   r   Úel)Úindexr   r   r!   :   s      )Z_check_symbolic_indexZ_check_index_for_getitemr   ÚtupleÚanyZ _get_slice_data_for_array_accessÚ	enumerateÚtyper   r   r   r   r   )r   r$   ZsyindexZ
sl_factorsÚeindicesÚarrayZnshaper   )r$   r   r   Ú__getitem__   s     


zSparseNDimArray.__getitem__c                 G   s
   | i |ƒS )z7
        Return a sparse N-dim array of zeros.
        r   )ÚclsÚshaper   r   r   Úzeros@   s    zSparseNDimArray.zerosc                 C   s^   ddl m} |  ¡ dkr tdƒ‚i }| j ¡ D ]\}}|||  |¡< q.|| jd | jd |ƒS )a…  
        Converts MutableDenseNDimArray to Matrix. Can convert only 2-dim array, else will raise error.

        Examples
        ========

        >>> from sympy import MutableSparseNDimArray
        >>> a = MutableSparseNDimArray([1 for i in range(9)], (3, 3))
        >>> b = a.tomatrix()
        >>> b
        Matrix([
        [1, 1, 1],
        [1, 1, 1],
        [1, 1, 1]])
        r   )ÚSparseMatrixé   zDimensions must be of size of 2é   )Zsympy.matricesr/   ZrankÚ
ValueErrorr   ÚitemsZ_get_tuple_indexr-   )r   r/   Z
mat_sparseÚkeyÚvaluer   r   r   ÚtomatrixG   s    zSparseNDimArray.tomatrixc                 G   s6   t  dd„ |¡}|| jkr&td| ƒ‚t| ƒ| j|ƒS )Nc                 S   s   | | S r   r   ©ÚxÚyr   r   r   Ú<lambda>b   ó    z)SparseNDimArray.reshape.<locals>.<lambda>zInvalid reshape parameters )Ú	functoolsÚreduceÚ
_loop_sizer2   r(   r   )r   ZnewshapeZnew_total_sizer   r   r   Úreshapea   s    
zSparseNDimArray.reshapeN)	Ú__name__Ú
__module__Ú__qualname__r   r+   Úclassmethodr.   r6   r?   r   r   r   r   r      s   0
r   c                   @   s&   e Zd Zddd„Zdd„ Zdd„ ZdS )	r   Nc           
      K   sÊ   | j ||f|Ž\}}ttt|ƒŽ }|  ||¡ |rBt dd„ |¡nt|ƒ}t|t	t
fƒrbt
|ƒ}n.i }tt|ƒƒD ]\}}|dkrrt|ƒ||< qrt
|ƒ}tj| ||f|Ž}	||	_t|ƒ|	_||	_||	_|	S )Nc                 S   s   | | S r   r   r7   r   r   r   r:   n   r;   z2ImmutableSparseNDimArray.__new__.<locals>.<lambda>r   )Ú_handle_ndarray_creation_inputsr   Úmapr   Z_check_special_boundsr<   r=   r"   r   Údictr   r'   r
   r   r   Ú_shapeÚ_rankr>   r   )
r,   Úiterabler-   r   Ú	flat_listZ	loop_sizeZsparse_arrayr   r#   r   r   r   r   r   j   s"    

z ImmutableSparseNDimArray.__new__c                 C   s   t dƒ‚d S )Nzimmutable N-dim array)Ú	TypeError)r   r$   r5   r   r   r   Ú__setitem__ƒ   s    z$ImmutableSparseNDimArray.__setitem__c                 C   s   t | ƒS r   )ÚMutableSparseNDimArrayr    r   r   r   Ú
as_mutable†   s    z#ImmutableSparseNDimArray.as_mutable)NN)r@   rA   rB   r   rL   rN   r   r   r   r   r   h   s   
r   c                   @   s2   e Zd Zd
dd„Zdd„ Zdd„ Zedd	„ ƒZdS )rM   Nc                 K   sž   | j ||f|Ž\}}t | ¡}||_t|ƒ|_|rBt dd„ |¡nt|ƒ|_t	|t
tfƒrht
|ƒ|_|S i |_tt|ƒƒD ]\}}|dkrzt|ƒ|j|< qz|S )Nc                 S   s   | | S r   r   r7   r   r   r   r:   ‘   r;   z0MutableSparseNDimArray.__new__.<locals>.<lambda>r   )rD   Úobjectr   rG   r"   rH   r<   r=   r>   r   rF   r   r   r'   r
   r   )r,   rI   r-   r   rJ   r   r   r#   r   r   r   r   Œ   s    


zMutableSparseNDimArray.__new__c           	      C   sÊ   t |tƒrŠtdd„ |D ƒƒrŠ|  ||¡\}}}|D ]T}dd„ t||ƒD ƒ}|| }|  |¡}|dkrp|| j|< q2|| jkr2| j |¡ q2n<|  |¡}t|ƒ}|dkr¼|| jkr¼| j |¡ n
|| j|< dS )a  Allows to set items to MutableDenseNDimArray.

        Examples
        ========

        >>> from sympy import MutableSparseNDimArray
        >>> a = MutableSparseNDimArray.zeros(2, 2)
        >>> a[0, 0] = 1
        >>> a[1, 1] = 1
        >>> a
        [[1, 0], [0, 1]]
        c                 s   s   | ]}t |tƒV  qd S r   r   r   r   r   r   r   ­   s     z5MutableSparseNDimArray.__setitem__.<locals>.<genexpr>c                 S   s    g | ]\}}|d k	r|| ‘qS r   r   )r   ÚindÚjr   r   r   r!   °   s      z6MutableSparseNDimArray.__setitem__.<locals>.<listcomp>r   N)	r   r%   r&   Z$_get_slice_data_for_array_assignmentÚzipr   r   Úpopr   )	r   r$   r5   r)   Zslice_offsetsr   Zother_iZother_valueZcomplete_indexr   r   r   rL       s    


z"MutableSparseNDimArray.__setitem__c                 C   s   t | ƒS r   r   r    r   r   r   Úas_immutable¿   s    z#MutableSparseNDimArray.as_immutablec                 C   s   dd„ | j  ¡ D ƒS )Nc                 S   s   h | ]}|j D ]}|’qqS r   )Úfree_symbols)r   rQ   r   r   r   r   Ú	<setcomp>Ä   s       z6MutableSparseNDimArray.free_symbols.<locals>.<setcomp>)r   Úvaluesr    r   r   r   rU   Â   s    z#MutableSparseNDimArray.free_symbols)NN)r@   rA   rB   r   rL   rT   ÚpropertyrU   r   r   r   r   rM   Š   s
   
rM   )Zsympy.core.basicr   Zsympy.core.containersr   r   Zsympy.core.singletonr   Zsympy.core.sympifyr   Z%sympy.tensor.array.mutable_ndim_arrayr   Zsympy.tensor.array.ndim_arrayr   r	   Zsympy.utilities.iterablesr
   r<   r   r   rM   r   r   r   r   Ú<module>   s   ]"