o
    GZhJ                     @   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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__ L/var/www/auris/lib/python3.10/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      
zArrayKind.__repr__returnc                 C   s4   dd |D }t |dkr|\}t|S 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)r   r   )
__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.arrayr0   )r   iterableshapekwargsr0   r   r   r   r      s   zNDimArray.__new__c                 C      t d)Nz4A subclass of NDimArray should implement __getitem__NotImplementedErrorr   indexr   r   r   __getitem__      zNDimArray.__getitem__c                 C   s   t |ttfr|| jkrtd|S | jdkrtdt|| jkr&tdd}t| jD ]4}|| | j| ksB|| | j|  k rLtdt	| d || dk rV|d7 }|| j|  ||  }q-|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ranger3   str)r   r9   Z
real_indexir   r   r   _parse_index   s    

&zNDimArray._parse_indexc                 C   s:   g }t | jD ]}|||  || }q|  t|S r   )reversedr3   appendreversetuple)r   Zinteger_indexr9   shr   r   r   _get_tuple_index   s   
zNDimArray._get_tuple_indexc                 C   s|   t |tr|n|f}tdd |D r<t|| jD ]\}}|dk dks)||kdkr-tdqddlm} || g|R  S d S )Nc                 s   s"    | ]}t |to|j V  qd S r   )r<   r   Z	is_numberr!   rB   r   r   r   	<genexpr>   s     z2NDimArray._check_symbolic_index.<locals>.<genexpr>r   Tzindex out of range)Indexed)r<   rG   anyzipr3   r>   Zsympy.tensorrL   )r   r9   Ztuple_indexrB   Znth_dimrL   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.matrixbaserQ   r<   r   r/   r7   )r   valuerQ   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 ]}|| q1|t|f|d  fS )Nr   r   r   c                    s   g | ]} |qS r   r   rJ   fr   r   
<listcomp>       z=NDimArray._scan_iterable_shape.<locals>.f.<locals>.<listcomp>r%   z'could not determine shape unambiguously)r<   r   r&   rN   setr>   extend)ZpointerresultZelemsZshapesrB   rV   r   r   rW      s   

z)NDimArray._scan_iterable_shape.<locals>.fr   )r   r2   r   rV   r   _scan_iterable_shape   s   zNDimArray._scan_iterable_shapec                 K   s8  ddl m} ddlm} |d u rH|d u rd}d}n/t||r$|j|jfS t|tr-|j}nt|t	r:| 
|\}}nt||rC|j}nd}|f}t|ttfr|d ur| }|D ]%}t|ttfr~d}t|D ]\}	}
|||	  |
 }qh|| ||< ||= qYt|ttfr|f}tdd |D stdt||fS )Nr   rP   SparseNDimArrayr   c                 s   s    | ]
}t |ttfV  qd S r   )r<   r   r	   )r!   dimr   r   r   rK     s    z<NDimArray._handle_ndarray_creation_inputs.<locals>.<genexpr>z#Shape should contain integers only.)rR   rQ   r1   r_   r<   _shape_sparse_arrayr/   r3   r   r]   r   dictcopyrG   r   	enumerater   r	   all	TypeError)r   r2   r3   r4   rQ   r_   Znew_dictkZnew_keyrB   idxr   r   r   _handle_ndarray_creation_inputs   s>   



z)NDimArray._handle_ndarray_creation_inputsc                 C      | 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__     zNDimArray.__len__c                 C   rk   )z
        Returns array shape (dimension).

        Examples
        ========

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

        )ra   r   r   r   r   r3     rm   zNDimArray.shapec                 C   rk   )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_derivativesro   
setdefaultas_immutable)r   argsr4   ro   r   r   r   diff5  s   zNDimArray.diffc                    s   |   fddS )Nc                    s
     | S r   )rt   )xbaser   r   <lambda>I  s   
 z,NDimArray._eval_derivative.<locals>.<lambda>)	applyfunc)r   rw   r   rv   r   _eval_derivativeG  s   zNDimArray._eval_derivativec                 C   s   t | ||S r   )r   _eval_derivative_n_times)r   snr   r   r   r{   K  s   z"NDimArray._eval_derivative_n_timesc                    sn   ddl m} ddlm} t| |r* tjdkr*t|  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 rU   r   r!   rh   vrV   r   r   
<dictcomp>_  s   & z'NDimArray.applyfunc.<locals>.<dictcomp>)r1   r_   sympy.tensor.array.arrayopr   r<   r
   Zerotyperb   itemsr3   map)r   rW   r_   r   r   rV   r   ry   N  s
   $zNDimArray.applyfuncc                    s^    fdd   dkrd S djv r%jj dj dS  jjdjS )Nc                    sn   t dkrd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   )_printrI   r    )printerr   r   r   rX   f  s     z2NDimArray._sympystr.<locals>.f.<locals>.<listcomp>]r   c              	      s6   g | ]} d d |  |d    qS )r%   Nr   r    )rW   rB   rH   
shape_leftr   r   rX   i  s   6 )r&   joinr@   )rH   r   rB   jrW   r   r   )rB   rH   r   r   rW   d  s   (.zNDimArray._sympystr.<locals>.fr   r   z([], ))rn   r   r3   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 ]}| | |dd  |||   ||d |    q |S )Nr%   c                    s   g | ]	}   | qS r   )rI   r    r   r   r   rX         z/NDimArray.tolist.<locals>.f.<locals>.<listcomp>r   )r&   r@   rE   )rH   r   rB   r   r\   r"   rW   r   r   r   rW     s   2zNDimArray.tolist.<locals>.fr   )r=   r3   r   r   r   r   tolistq  s   	zNDimArray.tolistc                 C   Z   ddl m} t|tstS | j|jkrtddd t|| ||D }t| || jS )Nr   r~   array shape mismatchc                 S   s   g | ]\}}|| qS r   r   r!   rB   r   r   r   r   rX         z%NDimArray.__add__.<locals>.<listcomp>	r   r   r<   r/   NotImplementedr3   r>   rN   r   r   otherr   result_listr   r   r   __add__     
zNDimArray.__add__c                 C   r   )Nr   r~   r   c                 S   s   g | ]\}}|| qS r   r   r   r   r   r   rX     r   z%NDimArray.__sub__.<locals>.<listcomp>r   r   r   r   r   __sub__  r   zNDimArray.__sub__c                       ddl m} ddlm} ddlm} t tt|frt	dt
  t| |rD jr2t| i | jS t|  fdd| j D | jS  fdd	|| D }t| || jS )
Nr   rP   r^   r~   =scalar expected, use tensorproduct(...) for tensorial productc                       i | ]	\}}| | qS r   r   r   r   r   r   r     r   z%NDimArray.__mul__.<locals>.<dictcomp>c                    s   g | ]}|  qS r   r   rJ   r   r   r   rX     rY   z%NDimArray.__mul__.<locals>.<listcomp>rR   rQ   r1   r_   r   r   r<   r   r/   r>   r   is_zeror   r3   rb   r   r   r   rQ   r_   r   r   r   r   r   __mul__     
$zNDimArray.__mul__c                    r   )
Nr   rP   r^   r~   r   c                    r   r   r   r   r   r   r   r     r   z&NDimArray.__rmul__.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   rJ   r   r   r   rX     rY   z&NDimArray.__rmul__.<locals>.<listcomp>r   r   r   r   r   __rmul__  r   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   rP   r^   r~   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   rJ   r   r   r   rX     rY   z)NDimArray.__truediv__.<locals>.<listcomp>)rR   rQ   r1   r_   r   r   r<   r   r/   r>   r   r
   r   r   rb   r   r3   r   r   r   r   __truediv__  s   $zNDimArray.__truediv__c                 C   r5   )Nz"unsupported operation on NDimArrayr6   r   r   r   r   r   __rtruediv__  r;   zNDimArray.__rtruediv__c                 C   sd   ddl m} ddlm} t| |r!t| dd | j D | jS dd || D }t| || jS )Nr   r^   r~   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   rJ   r   r   r   rX     r$   z%NDimArray.__neg__.<locals>.<listcomp>)	r1   r_   r   r   r<   r   rb   r   r3   )r   r_   r   r   r   r   r   __neg__  s   
 zNDimArray.__neg__c                    s    fdd}| S )Nc                  3   s8     j rt j d D ]}  |  V  qd S  d V  d S )Nr   r   )ra   r@   )rB   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| |r)t||r)t| 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)r1   r_   r<   r/   r3   rc   rb   list)r   r   r_   r   r   r   __eq__  s   
zNDimArray.__eq__c                 C   s
   | |k S r   r   r   r   r   r   __ne__  r   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   )rn   r>   Zarrayopr   )r   r   r   r   r   _eval_transpose  s   
zNDimArray._eval_transposec                 C      |   S r   )r   r   r   r   r   	transpose  r;   zNDimArray.transposec                 C   s(   ddl m} | dd || D | jS )Nr   r~   c                 S   s   g | ]}|  qS r   )	conjugaterJ   r   r   r   rX     rY   z-NDimArray._eval_conjugate.<locals>.<listcomp>)r   r   funcr3   )r   r   r   r   r   _eval_conjugate  s   zNDimArray._eval_conjugatec                 C   r   r   )r   r   r   r   r   r     r;   zNDimArray.conjugatec                 C   s   |    S r   )r   r   r   r   r   r   _eval_adjoint!  s   zNDimArray._eval_adjointc                 C   r   r   )r   r   r   r   r   adjoint$  r;   zNDimArray.adjointc                    s@   t |ts|fS ||\ } fddt|   D S )Nc                    s   g | ]} |  qS r   r   rJ   startstepr   r   rX   +  r   z+NDimArray._slice_expand.<locals>.<listcomp>)r<   sliceindicesr@   )r   r|   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!   rB   r`   r   r   r   rX   .  s    z>NDimArray._get_slice_data_for_array_access.<locals>.<listcomp>)rN   r3   	itertoolsproduct)r   r9   
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   )r<   r   minrJ   r   r   r   rX   6  s   " zBNDimArray._get_slice_data_for_array_assignment.<locals>.<listcomp>)r<   r/   r   r   )r   r9   rS   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rt |dkrtdd S d S )Nr   r%   z*arrays without shape need one scalar valuerU   r   z/if array shape is (0,) there cannot be elements)r&   r>   )r   Z	flat_listr3   r   r   r   _check_special_bounds:  s
   zNDimArray._check_special_boundsc                 C   sj   t |tttfr|f}t||  k r't|tdd tt||  D  }t||  kr3td|S )Nc                 s   s    | ]}t d V  qd S r   )r   rJ   r   r   r   rK   G  s    z5NDimArray._check_index_for_getitem.<locals>.<genexpr>z-Dimension of index greater than rank of array)	r<   r   r	   r   r&   rn   rG   r@   r>   r8   r   r   r   _check_index_for_getitemA  s   z"NDimArray._check_index_for_getitemr   )NN).r)   r*   r+   r,   Z	_diff_wrtZ	is_scalarr   r:   rC   rI   rO   rT   r-   r]   rj   rl   propertyr3   rn   rt   rz   r{   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   r   r   r   r/   V   s\    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  r   zImmutableNDimArray.__hash__c                 C   s   | S r   r   r   r   r   r   rr   U  s   zImmutableNDimArray.as_immutablec                 C   r5   )Nzabstract methodr6   r   r   r   r   
as_mutableX  r;   zImmutableNDimArray.as_mutableN)r)   r*   r+   Z_op_priorityr   rr   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   |