o
    jgeJ                     @   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__ U/var/www/html/zoom/venv/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   kinds
elem_kinds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.arrayr2   )r   iterableshapekwargsr2   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ranger5   str)r   r;   
real_indexir   r   r   _parse_index   s    

&zNDimArray._parse_indexc                 C   s:   g }t | jD ]}|||  || }q|  t|S r   )reversedr5   appendreversetuple)r   integer_indexr;   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   	is_numberr!   rE   r   r   r   	<genexpr>   s     z2NDimArray._check_symbolic_index.<locals>.<genexpr>r   Tzindex out of range)Indexed)r>   rJ   anyzipr5   r@   sympy.tensorrQ   )r   r;   tuple_indexrE   nth_dimrQ   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.matrixbaserY   r>   r   r1   r9   )r   valuerY   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   rO   fr   r   
<listcomp>       z=NDimArray._scan_iterable_shape.<locals>.f.<locals>.<listcomp>r%   z'could not determine shape unambiguously)r>   r   r&   rS   setr@   extend)pointerresultelemsshapesrE   r^   r   r   r_      s   

z)NDimArray._scan_iterable_shape.<locals>.fr   )r   r4   r   r^   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   rX   SparseNDimArrayr   c                 s   s    | ]
}t |ttfV  qd S r   )r>   r   r	   )r!   dimr   r   r   rP     s    z<NDimArray._handle_ndarray_creation_inputs.<locals>.<genexpr>z#Shape should contain integers only.)rZ   rY   r3   rj   r>   _shape_sparse_arrayr1   r5   r   rh   r   dictcopyrJ   r   	enumerater   r	   all	TypeError)r   r4   r5   r6   rY   rj   new_dictknew_keyrE   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   rx   )z
        Returns array shape (dimension).

        Examples
        ========

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

        )rl   r   r   r   r   r5     rz   zNDimArray.shapec                 C   rx   )z
        Returns rank of array.

        Examples
        ========

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

        )rA   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)$sympy.tensor.array.array_derivativesr|   
setdefaultas_immutable)r   argsr6   r|   r   r   r   diff5  s   zNDimArray.diffc                    s   |   fddS )Nc                    s
     | S r   )r   )xbaser   r   <lambda>I  s   
 z,NDimArray._eval_derivative.<locals>.<lambda>)	applyfunc)r   r   r   r   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   ri   Flattenc                    s&   i | ]\}} |d kr| |qS r]   r   r!   rt   vr^   r   r   
<dictcomp>_  s   & z'NDimArray.applyfunc.<locals>.<dictcomp>)r3   rj   sympy.tensor.array.arrayopr   r>   r
   Zerotyperm   itemsr5   map)r   r_   rj   r   r   r^   r   r   N  s
   $zNDimArray.applyfuncc                    s>    fdd   dkr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   )_printrM   r    )printerr   r   r   r`   f  s     z2NDimArray._sympystr.<locals>.f.<locals>.<listcomp>]r   c              	      s6   g | ]} d d |  |d    qS )r%   Nr   r    )r_   rE   rL   
shape_leftr   r   r`   i  s   6 )r&   joinrB   )rL   r   rE   jr_   r   r   )rE   rL   r   r   r_   d  s   (.zNDimArray._sympystr.<locals>.fr   r   )r{   r   r?   r5   )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   )rM   r    r   r   r   r`         z/NDimArray.tolist.<locals>.f.<locals>.<listcomp>r   )r&   rB   rH   )rL   r   rE   r   re   r"   r_   r   r   r   r_     s   2zNDimArray.tolist.<locals>.fr   )r?   r5   r   r   r   r   tolistp  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!   rE   r   r   r   r   r`         z%NDimArray.__add__.<locals>.<listcomp>	r   r   r>   r1   NotImplementedr5   r@   rS   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   r`     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   rX   ri   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   rO   r   r   r   r`     ra   z%NDimArray.__mul__.<locals>.<listcomp>rZ   rY   r3   rj   r   r   r>   r   r1   r@   r   is_zeror   r5   rm   r   r   r   rY   rj   r   r   r   r   r   __mul__     
$zNDimArray.__mul__c                    r   )
Nr   rX   ri   r   r   c                    r   r   r   r   r   r   r   r     r   z&NDimArray.__rmul__.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   rO   r   r   r   r`     ra   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   rX   ri   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   rO   r   r   r   r`     ra   z)NDimArray.__truediv__.<locals>.<listcomp>)rZ   rY   r3   rj   r   r   r>   r   r1   r@   r   r
   r   r   rm   r   r5   r   r   r   r   __truediv__  s   $zNDimArray.__truediv__c                 C   r7   )Nz"unsupported operation on NDimArrayr8   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   ri   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   rO   r   r   r   r`     r$   z%NDimArray.__neg__.<locals>.<listcomp>)	r3   rj   r   r   r>   r   rm   r   r5   )r   rj   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   )rl   rB   )rE   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   ri   F)r3   rj   r>   r1   r5   rn   rm   list)r   r   rj   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   )r{   r@   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   )	conjugaterO   r   r   r   r`     ra   z-NDimArray._eval_conjugate.<locals>.<listcomp>)r   r   funcr5   )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   rO   startstepr   r   r`   *  r   z+NDimArray._slice_expand.<locals>.<listcomp>)r>   sliceindicesrB   )r   r   rk   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!   rE   rk   r   r   r   r`   -  s    z>NDimArray._get_slice_data_for_array_access.<locals>.<listcomp>)rS   r5   	itertoolsproduct)r   r;   
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   minrO   r   r   r   r`   5  s   " zBNDimArray._get_slice_data_for_array_assignment.<locals>.<listcomp>)r>   r1   r   r   )r   r;   r[   r   r   slice_offsetsr   r   r   $_get_slice_data_for_array_assignment1  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 valuer]   r   z/if array shape is (0,) there cannot be elements)r&   r@   )r   	flat_listr5   r   r   r   _check_special_bounds9  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   rO   r   r   r   rP   F  s    z5NDimArray._check_index_for_getitem.<locals>.<genexpr>z-Dimension of index greater than rank of array)	r>   r   r	   r   r&   r{   rJ   rB   r@   r:   r   r   r   _check_index_for_getitem@  s   z"NDimArray._check_index_for_getitemr   )NN).r+   r,   r-   r.   	_diff_wrt	is_scalarr   r<   rF   rM   rW   r\   r/   rh   rw   ry   propertyr5   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   r   r   r   r   r1   V   s\    4

.


!
r1   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   Q  r   zImmutableNDimArray.__hash__c                 C   s   | S r   r   r   r   r   r   r   T  s   zImmutableNDimArray.as_immutablec                 C   r7   )Nzabstract methodr8   r   r   r   r   
as_mutableW  r=   zImmutableNDimArray.as_mutableN)r+   r,   r-   _op_priorityr   r   r   r   r   r   r   r   N  s
    r   )sympy.core.basicr   sympy.core.containersr   r   sympy.core.exprr   sympy.core.kindr   r   r   sympy.core.numbersr	   sympy.core.singletonr
   sympy.core.sympifyr   sympy.external.gmpyr   sympy.printing.defaultsr   r   collections.abcr   r   r1   r   r   r   r   r   <module>   s"    G   {