a
    lhJ                     @   s   d dl mZ d dlmZmZ d dlmZ d dlmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lZd dlmZ G dd deZG dd deZG dd deeZd
S )    )Basic)DictTuple)Expr)Kind
NumberKindUndefinedKind)Integer)S)sympify)
SYMPY_INTS)	PrintableN)Iterablec                       s>   e Zd ZdZef fdd	Zdd Zed dddZ  Z	S )		ArrayKinda  
    Kind for N-dimensional array in SymPy.

    This kind represents the multidimensional array that algebraic
    operations are defined. Basic class for this kind is ``NDimArray``,
    but any expression representing the array can have this.

    Parameters
    ==========

    element_kind : Kind
        Kind of the element. Default is :obj:NumberKind `<sympy.core.kind.NumberKind>`,
        which means that the array contains only numbers.

    Examples
    ========

    Any instance of array class has ``ArrayKind``.

    >>> from sympy import NDimArray
    >>> NDimArray([1,2,3]).kind
    ArrayKind(NumberKind)

    Although expressions representing an array may be not instance of
    array class, it will have ``ArrayKind`` as well.

    >>> from sympy import Integral
    >>> from sympy.tensor.array import NDimArray
    >>> from sympy.abc import x
    >>> intA = Integral(NDimArray([1,2,3]), x)
    >>> isinstance(intA, NDimArray)
    False
    >>> intA.kind
    ArrayKind(NumberKind)

    Use ``isinstance()`` to check for ``ArrayKind` without specifying
    the element kind. Use ``is`` with specifying the element kind.

    >>> from sympy.tensor.array import ArrayKind
    >>> from sympy.core import NumberKind
    >>> boolA = NDimArray([True, False])
    >>> isinstance(boolA.kind, ArrayKind)
    True
    >>> boolA.kind is ArrayKind(NumberKind)
    False

    See Also
    ========

    shape : Function to return the shape of objects with ``MatrixKind``.

    c                    s   t  | |}||_|S N)super__new__element_kind)clsr   obj	__class__ K/var/www/auris/lib/python3.9/site-packages/sympy/tensor/array/ndim_array.pyr   D   s    zArrayKind.__new__c                 C   s
   d| j  S )NzArrayKind(%s))r   selfr   r   r   __repr__I   s    zArrayKind.__repr__)returnc                 C   s.   dd |D }t |dkr"|\}nt}t|S )Nc                 S   s   h | ]
}|j qS r   )kind.0er   r   r   	<setcomp>N       z#ArrayKind._union.<locals>.<setcomp>   )lenr   r   )r   kindsZ
elem_kindsZelemkindr   r   r   _unionL   s
    zArrayKind._union)
__name__
__module____qualname____doc__r   r   r   classmethodr'   __classcell__r   r   r   r   r      s
   4r   c                   @   s\  e Zd ZdZdZdZdQddZdd Zd	d
 Zdd Z	dd Z
dd Zedd ZedRddZdd Ze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d1d2 Zd3d4 Zd5d6 Z d7d8 Z!d9d: Z"d;d< Z#d=d> Z$d?d@ Z%dAdB Z&dCdD Z'dEdF Z(dGdH Z)dIdJ Z*dKdL Z+edMdN Z,dOdP Z-dS )S	NDimArraya  N-dimensional array.

    Examples
    ========

    Create an N-dim array of zeros:

    >>> from sympy import MutableDenseNDimArray
    >>> a = MutableDenseNDimArray.zeros(2, 3, 4)
    >>> a
    [[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]

    Create an N-dim array from a list;

    >>> a = MutableDenseNDimArray([[2, 3], [4, 5]])
    >>> a
    [[2, 3], [4, 5]]

    >>> b = MutableDenseNDimArray([[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]])
    >>> b
    [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]

    Create an N-dim array from a flat list with dimension shape:

    >>> a = MutableDenseNDimArray([1, 2, 3, 4, 5, 6], (2, 3))
    >>> a
    [[1, 2, 3], [4, 5, 6]]

    Create an N-dim array from a matrix:

    >>> from sympy import Matrix
    >>> a = Matrix([[1,2],[3,4]])
    >>> a
    Matrix([
    [1, 2],
    [3, 4]])
    >>> b = MutableDenseNDimArray(a)
    >>> b
    [[1, 2], [3, 4]]

    Arithmetic operations on N-dim arrays

    >>> a = MutableDenseNDimArray([1, 1, 1, 1], (2, 2))
    >>> b = MutableDenseNDimArray([4, 4, 4, 4], (2, 2))
    >>> c = a + b
    >>> c
    [[5, 5], [5, 5]]
    >>> a - b
    [[-3, -3], [-3, -3]]

    TFNc                 K   s   ddl m} |||fi |S )Nr   )ImmutableDenseNDimArray)sympy.tensor.arrayr/   )r   iterableshapekwargsr/   r   r   r   r      s    zNDimArray.__new__c                 C   s   t dd S )Nz4A subclass of NDimArray should implement __getitem__NotImplementedErrorr   indexr   r   r   __getitem__   s    zNDimArray.__getitem__c                 C   s   t |ttfr$|| jkr td|S | jdkr6tdt|| jkrLtdd}t| jD ]h}|| | j| ks|| | j|  k rtdt	| d || dk r|d7 }|| j|  ||  }qZ|S )NzOnly a tuple index is acceptedr   z#Index not valid with an empty arrayzWrong number of array axeszIndex z out of borderr$   )

isinstancer   r	   
_loop_size
ValueErrorr%   _rankranger2   str)r   r7   Z
real_indexir   r   r   _parse_index   s     

&zNDimArray._parse_indexc                 C   s:   g }t | jD ]}|||  || }q|  t|S r   )reversedr2   appendreversetuple)r   Zinteger_indexr7   shr   r   r   _get_tuple_index   s    
zNDimArray._get_tuple_indexc                 C   s|   t |tr|n|f}tdd |D rxt|| jD ](\}}|dk dksR||kdkr2tdq2ddlm} || g|R  S d S )Nc                 s   s    | ]}t |to|j V  qd S r   )r9   r   Z	is_numberr    r?   r   r   r   	<genexpr>   r#   z2NDimArray._check_symbolic_index.<locals>.<genexpr>r   Tzindex out of range)Indexed)r9   rD   anyzipr2   r;   Zsympy.tensorrI   )r   r7   Ztuple_indexr?   Znth_dimrI   r   r   r   _check_symbolic_index   s    
zNDimArray._check_symbolic_indexc                 C   s$   ddl m} t|t|tfr td S )Nr   
MatrixBase)sympy.matrices.matrixbaserN   r9   r   r.   r5   )r   valuerN   r   r   r   _setter_iterable_check   s    z NDimArray._setter_iterable_checkc                    s    fdd  |S )Nc                    s   t | ts| gdfS t| dkr(g dfS g }t fdd| D  \}}tt|dkr^td|D ]}|| qb|t|f|d  fS )Nr   r   r   c                    s   g | ]} |qS r   r   rG   fr   r   
<listcomp>   r#   z=NDimArray._scan_iterable_shape.<locals>.f.<locals>.<listcomp>r$   z'could not determine shape unambiguously)r9   r   r%   rK   setr;   extend)pointerresultelemsZshapesr?   rS   r   r   rT      s    

z)NDimArray._scan_iterable_shape.<locals>.fr   )r   r1   r   rS   r   _scan_iterable_shape   s    zNDimArray._scan_iterable_shapec                 K   s@  ddl m} ddlm} |d u r|d u r2d}d}n^t||rH|j|jfS t|trZ|j}n6t|t	rt| 
|\}}nt||r|j}n
d}|f}t|ttfr|d ur| }|D ]J}t|ttfrd}t|D ]\}	}
|||	  |
 }q|| ||< ||= qt|ttfr|f}tdd |D s4tdt||fS )Nr   rM   SparseNDimArrayr   c                 s   s   | ]}t |ttfV  qd S r   )r9   r   r	   )r    dimr   r   r   rH     r#   z<NDimArray._handle_ndarray_creation_inputs.<locals>.<genexpr>z#Shape should contain integers only.)rO   rN   r0   r]   r9   _shape_sparse_arrayr.   r2   r   r[   r   dictcopyrD   r   	enumerater   r	   all	TypeError)r   r1   r2   r3   rN   r]   Znew_dictkZnew_keyr?   idxr   r   r   _handle_ndarray_creation_inputs   s<    



z)NDimArray._handle_ndarray_creation_inputsc                 C   s   | j S )a-  Overload common function len(). Returns number of elements in array.

        Examples
        ========

        >>> from sympy import MutableDenseNDimArray
        >>> a = MutableDenseNDimArray.zeros(3, 3)
        >>> a
        [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
        >>> len(a)
        9

        )r:   r   r   r   r   __len__  s    zNDimArray.__len__c                 C   s   | j S )z
        Returns array shape (dimension).

        Examples
        ========

        >>> from sympy import MutableDenseNDimArray
        >>> a = MutableDenseNDimArray.zeros(3, 3)
        >>> a.shape
        (3, 3)

        )r_   r   r   r   r   r2     s    zNDimArray.shapec                 C   s   | j S )z
        Returns rank of array.

        Examples
        ========

        >>> from sympy import MutableDenseNDimArray
        >>> a = MutableDenseNDimArray.zeros(3,4,5,6,3)
        >>> a.rank()
        5

        )r<   r   r   r   r   rank&  s    zNDimArray.rankc                 O   s2   ddl m} |dd ||  g|R i |S )a5  
        Calculate the derivative of each element in the array.

        Examples
        ========

        >>> from sympy import ImmutableDenseNDimArray
        >>> from sympy.abc import x, y
        >>> M = ImmutableDenseNDimArray([[x, y], [1, x*y]])
        >>> M.diff(x)
        [[1, 0], [0, y]]

        r   )ArrayDerivativeevaluateT)Z$sympy.tensor.array.array_derivativesrk   
setdefaultas_immutable)r   argsr3   rk   r   r   r   diff5  s    zNDimArray.diffc                    s   |   fddS )Nc                    s
     | S r   )rp   )xbaser   r   <lambda>I  r#   z,NDimArray._eval_derivative.<locals>.<lambda>)	applyfunc)r   rs   r   rr   r   _eval_derivativeG  s    zNDimArray._eval_derivativec                 C   s   t | ||S r   )r   _eval_derivative_n_times)r   snr   r   r   rw   K  s    z"NDimArray._eval_derivative_n_timesc                    sn   ddl m} ddlm} t| |rT tjdkrTt|  fdd| j	 D | j
S t| t || | j
S )a[  Apply a function to each element of the N-dim array.

        Examples
        ========

        >>> from sympy import ImmutableDenseNDimArray
        >>> m = ImmutableDenseNDimArray([i*2+j for i in range(2) for j in range(2)], (2, 2))
        >>> m
        [[0, 1], [2, 3]]
        >>> m.applyfunc(lambda i: 2*i)
        [[0, 2], [4, 6]]
        r   r\   Flattenc                    s&   i | ]\}} |d kr| |qS rR   r   r    rf   vrS   r   r   
<dictcomp>_  r#   z'NDimArray.applyfunc.<locals>.<dictcomp>)r0   r]   sympy.tensor.array.arrayopr{   r9   r
   Zerotyper`   itemsr2   map)r   rT   r]   r{   r   rS   r   ru   N  s
    $zNDimArray.applyfuncc                    s^    fdd   dkr*d S djv rJjj dj dS  jjdjS )Nc                    sn   t dkr4ddfddt |D  d S d  dd fddtd D  d S )	Nr$   [z, c                    s    g | ]}  | qS r   )_printrF   r   )printerr   r   r   rU   f  r#   z2NDimArray._sympystr.<locals>.f.<locals>.<listcomp>]r   c              	      s6   g | ].} d d |  |d    qS )r$   Nr   r   )rT   r?   rE   
shape_leftr   r   rU   i  r#   )r%   joinr=   )rE   r   r?   jrT   r   r   )r?   rE   r   r   rT   d  s    (zNDimArray._sympystr.<locals>.fr   r   z([], ))rj   r   r2   r   r(   r:   )r   r   r   r   r   	_sympystrc  s    
zNDimArray._sympystrc                    s"    fdd  j jdj S )a?  
        Converting MutableDenseNDimArray to one-dim list

        Examples
        ========

        >>> from sympy import MutableDenseNDimArray
        >>> a = MutableDenseNDimArray([1, 2, 3, 4], (2, 2))
        >>> a
        [[1, 2], [3, 4]]
        >>> b = a.tolist()
        >>> b
        [[1, 2], [3, 4]]
        c              
      sz   t |dkr$fddt||D S g }| |d  } t|d D ]4}| | |dd  |||   ||d |    q@|S )Nr$   c                    s   g | ]}   | qS r   )rF   r   r   r   r   rU     r#   z/NDimArray.tolist.<locals>.f.<locals>.<listcomp>r   )r%   r=   rB   )rE   r   r?   r   rY   r!   rT   r   r   r   rT     s    2zNDimArray.tolist.<locals>.fr   )r:   r2   r   r   r   r   tolistq  s    	zNDimArray.tolistc                 C   sZ   ddl m} t|tstS | j|jkr.tddd t|| ||D }t| || jS )Nr   rz   array shape mismatchc                 S   s   g | ]\}}|| qS r   r   r    r?   r   r   r   r   rU     r#   z%NDimArray.__add__.<locals>.<listcomp>	r   r{   r9   r.   NotImplementedr2   r;   rK   r   r   otherr{   result_listr   r   r   __add__  s    
zNDimArray.__add__c                 C   sZ   ddl m} t|tstS | j|jkr.tddd t|| ||D }t| || jS )Nr   rz   r   c                 S   s   g | ]\}}|| qS r   r   r   r   r   r   rU     r#   z%NDimArray.__sub__.<locals>.<listcomp>r   r   r   r   r   __sub__  s    
zNDimArray.__sub__c                    s   ddl m} ddlm} ddlm} t tt|fr<t	dt
  t| |r jrdt| i | jS t|  fdd| j D | jS  fdd	|| D }t| || jS )
Nr   rM   r\   rz   =scalar expected, use tensorproduct(...) for tensorial productc                    s   i | ]\}}| | qS r   r   r|   r   r   r   r~     r#   z%NDimArray.__mul__.<locals>.<dictcomp>c                    s   g | ]}|  qS r   r   rG   r   r   r   rU     r#   z%NDimArray.__mul__.<locals>.<listcomp>rO   rN   r0   r]   r   r{   r9   r   r.   r;   r   is_zeror   r2   r`   r   r   r   rN   r]   r{   r   r   r   r   __mul__  s    
$zNDimArray.__mul__c                    s   ddl m} ddlm} ddlm} t tt|fr<t	dt
  t| |r jrdt| i | jS t|  fdd| j D | jS  fdd	|| D }t| || jS )
Nr   rM   r\   rz   r   c                    s   i | ]\}}| | qS r   r   r|   r   r   r   r~     r#   z&NDimArray.__rmul__.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   rG   r   r   r   rU     r#   z&NDimArray.__rmul__.<locals>.<listcomp>r   r   r   r   r   __rmul__  s    
$zNDimArray.__rmul__c                    s   ddl m} ddlm} ddlm} t tt|fr<t	dt
  t| |r| tjkr|t|  fdd| j D | jS  fdd	|| D }t| || jS )
Nr   rM   r\   rz   zscalar expectedc                    s   i | ]\}}||  qS r   r   r|   r   r   r   r~     r#   z)NDimArray.__truediv__.<locals>.<dictcomp>c                    s   g | ]}|  qS r   r   rG   r   r   r   rU     r#   z)NDimArray.__truediv__.<locals>.<listcomp>)rO   rN   r0   r]   r   r{   r9   r   r.   r;   r   r
   r   r   r`   r   r2   r   r   r   r   __truediv__  s    $zNDimArray.__truediv__c                 C   s   t dd S )Nz"unsupported operation on NDimArrayr4   r   r   r   r   r   __rtruediv__  s    zNDimArray.__rtruediv__c                 C   sd   ddl m} ddlm} t| |rBt| dd | j D | jS dd || D }t| || jS )Nr   r\   rz   c                 S   s   i | ]\}}|| qS r   r   r|   r   r   r   r~     r#   z%NDimArray.__neg__.<locals>.<dictcomp>c                 S   s   g | ]
}| qS r   r   rG   r   r   r   rU     r#   z%NDimArray.__neg__.<locals>.<listcomp>)	r0   r]   r   r{   r9   r   r`   r   r2   )r   r]   r{   r   r   r   r   __neg__  s    
 zNDimArray.__neg__c                    s    fdd}| S )Nc                  3   s4    j r&t j d D ]}  |  V  qn
 d V  d S )Nr   r   )r_   r=   )r?   r   r   r   iterator  s    z$NDimArray.__iter__.<locals>.iteratorr   )r   r   r   r   r   __iter__  s    zNDimArray.__iter__c                 C   sb   ddl m} t|tsdS | j|jks*dS t| |rRt||rRt| jt|jkS t| t|kS )a  
        NDimArray instances can be compared to each other.
        Instances equal if they have same shape and data.

        Examples
        ========

        >>> from sympy import MutableDenseNDimArray
        >>> a = MutableDenseNDimArray.zeros(2, 3)
        >>> b = MutableDenseNDimArray.zeros(2, 3)
        >>> a == b
        True
        >>> c = a.reshape(3, 2)
        >>> c == b
        False
        >>> a[0,0] = 1
        >>> b[0,0] = 2
        >>> a == b
        False
        r   r\   F)r0   r]   r9   r.   r2   ra   r`   list)r   r   r]   r   r   r   __eq__  s    
zNDimArray.__eq__c                 C   s
   | |k S r   r   r   r   r   r   __ne__  s    zNDimArray.__ne__c                 C   s*   |   dkrtdddlm} || dS )N   zarray rank not 2r$   )permutedims)r$   r   )rj   r;   Zarrayopr   )r   r   r   r   r   _eval_transpose  s    zNDimArray._eval_transposec                 C   s   |   S r   )r   r   r   r   r   	transpose  s    zNDimArray.transposec                 C   s(   ddl m} | dd || D | jS )Nr   rz   c                 S   s   g | ]}|  qS r   )	conjugaterG   r   r   r   rU     r#   z-NDimArray._eval_conjugate.<locals>.<listcomp>)r   r{   funcr2   )r   r{   r   r   r   _eval_conjugate  s    zNDimArray._eval_conjugatec                 C   s   |   S r   )r   r   r   r   r   r     s    zNDimArray.conjugatec                 C   s   |    S r   )r   r   r   r   r   r   _eval_adjoint!  s    zNDimArray._eval_adjointc                 C   s   |   S r   )r   r   r   r   r   adjoint$  s    zNDimArray.adjointc                    s@   t |ts|fS ||\ } fddt|   D S )Nc                    s   g | ]} |  qS r   r   rG   startstepr   r   rU   +  r#   z+NDimArray._slice_expand.<locals>.<listcomp>)r9   sliceindicesr=   )r   rx   r^   stopr   r   r   _slice_expand'  s    
zNDimArray._slice_expandc                    s,    fddt | jD }tj| }||fS )Nc                    s   g | ]\}}  ||qS r   )r   )r    r?   r^   r   r   r   rU   .  r#   z>NDimArray._get_slice_data_for_array_access.<locals>.<listcomp>)rK   r2   	itertoolsproduct)r   r7   
sl_factorseindicesr   r   r    _get_slice_data_for_array_access-  s    
z*NDimArray._get_slice_data_for_array_accessc                 C   s<   t |tst| |}| |\}}dd |D }|||fS )Nc                 S   s"   g | ]}t |trt|nd qS r   )r9   r   minrG   r   r   r   rU   6  r#   zBNDimArray._get_slice_data_for_array_assignment.<locals>.<listcomp>)r9   r.   r   r   )r   r7   rP   r   r   Zslice_offsetsr   r   r   $_get_slice_data_for_array_assignment2  s
    
z.NDimArray._get_slice_data_for_array_assignmentc                 C   s<   |dkrt |dkrtd|dkr8t |dkr8tdd S )Nr   r$   z*arrays without shape need one scalar valuerR   r   z/if array shape is (0,) there cannot be elements)r%   r;   )r   Z	flat_listr2   r   r   r   _check_special_bounds:  s    zNDimArray._check_special_boundsc                 C   sj   t |tttfr|f}t||  k rNt|tdd tt||  D  }t||  krftd|S )Nc                 s   s   | ]}t d V  qd S r   )r   rG   r   r   r   rH   G  r#   z5NDimArray._check_index_for_getitem.<locals>.<genexpr>z-Dimension of index greater than rank of array)	r9   r   r	   r   r%   rj   rD   r=   r;   r6   r   r   r   _check_index_for_getitemA  s    z"NDimArray._check_index_for_getitem)N)NN).r(   r)   r*   r+   Z	_diff_wrtZ	is_scalarr   r8   r@   rF   rL   rQ   r,   r[   rh   ri   propertyr2   rj   rp   rv   rw   ru   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.   V   sZ   4

.


!
r.   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ImmutableNDimArrayg      &@c                 C   s
   t | S r   )r   __hash__r   r   r   r   r   R  s    zImmutableNDimArray.__hash__c                 C   s   | S r   r   r   r   r   r   rn   U  s    zImmutableNDimArray.as_immutablec                 C   s   t dd S )Nzabstract methodr4   r   r   r   r   
as_mutableX  s    zImmutableNDimArray.as_mutableN)r(   r)   r*   Z_op_priorityr   rn   r   r   r   r   r   r   O  s   r   )Zsympy.core.basicr   Zsympy.core.containersr   r   Zsympy.core.exprr   Zsympy.core.kindr   r   r   Zsympy.core.numbersr	   Zsympy.core.singletonr
   Zsympy.core.sympifyr   Zsympy.external.gmpyr   Zsympy.printing.defaultsr   r   collections.abcr   r   r.   r   r   r   r   r   <module>   s    G   |