U
    9%etJ                     @   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__ \/var/www/html/Darija-Ai-API/env/lib/python3.8/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   s     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|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ranger1   str)r   r6   Z
real_indexir   r   r   _parse_index   s     

&zNDimArray._parse_indexc                 C   sB   g }t t| jD ]\}}|||  || }q|  t|S r   )	enumeratereversedr1   appendreversetuple)r   Zinteger_indexr6   r>   shr   r   r   _get_tuple_index   s    
zNDimArray._get_tuple_indexc                 C   sz   t |tr|n|f}tdd |D rvt|| jD ](\}}|dk dksR||kdkr2tdq2ddlm} || f| S d S )Nc                 s   s    | ]}t |to|j V  qd S r   )r8   r   Z	is_numberr    r>   r   r   r   	<genexpr>   s     z2NDimArray._check_symbolic_index.<locals>.<genexpr>r   Tzindex out of range)Indexed)r8   rD   anyzipr1   r:   Zsympy.tensorrI   )r   r6   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.matricesrN   r8   r   r-   r4   )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>   s     z=NDimArray._scan_iterable_shape.<locals>.f.<locals>.<listcomp>r#   z'could not determine shape unambiguously)r8   r   r$   rK   setr:   extend)ZpointerresultZelemsZshapesr>   rS   r   r   rT      s    

z)NDimArray._scan_iterable_shape.<locals>.fr   )r   r0   r   rS   r   _scan_iterable_shape   s    zNDimArray._scan_iterable_shapec                 K   sH  ddl m} ddlm} |d kr|d k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 k	r
| }| D ]N\}}t|ttfrd}	t|D ]\}
}|	||
  | }	q|| ||	< ||= qt|ttfr |f}tdd |D s<tdt||fS )Nr   rM   SparseNDimArrayr   c                 s   s   | ]}t |ttfV  qd S r   )r8   r   r	   )r    dimr   r   r   rH     s     z<NDimArray._handle_ndarray_creation_inputs.<locals>.<genexpr>z#Shape should contain integers only.)rO   rN   r/   r[   r8   _shape_sparse_arrayr-   r1   r   rY   r   dictcopyitemsrD   r   r@   r   r	   all	TypeError)r   r0   r1   r2   rN   r[   Znew_dictkvZ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

        )r9   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   r1     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   s,   ddl m} |dd ||  f||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_derivativesrj   
setdefaultas_immutable)r   argsr2   rj   r   r   r   diff5  s    zNDimArray.diffc                    s   |   fddS )Nc                    s
     | S r   )ro   )xbaser   r   <lambda>I      z,NDimArray._eval_derivative.<locals>.<lambda>)	applyfunc)r   rr   r   rq   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   rZ   Flattenc                    s&   i | ]\}} |d kr| |qS rR   r   r    rd   re   rS   r   r   
<dictcomp>_  s       z'NDimArray.applyfunc.<locals>.<dictcomp>)r/   r[   sympy.tensor.array.arrayopr{   r8   r
   Zerotyper^   ra   r1   map)r   rT   r[   r{   r   rS   r   ru   N  s
    $zNDimArray.applyfuncc                    s>    fdd   dkr*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  s     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  s     )r$   joinr<   )rE   r   r>   jrT   r   r   )r>   rE   r   r   rT   d  s    (zNDimArray._sympystr.<locals>.fr   r   )ri   r   r9   r1   )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     s     z/NDimArray.tolist.<locals>.f.<locals>.<listcomp>r   )r$   r<   rB   )rE   r   r>   r   rX   r!   rT   r   r   r   rT     s    2zNDimArray.tolist.<locals>.fr   )r9   r1   r   r   r   r   tolistp  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     s     z%NDimArray.__add__.<locals>.<listcomp>	r~   r{   r8   r-   NotImplementedr1   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     s     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   rZ   rz   =scalar expected, use tensorproduct(...) for tensorial productc                    s   i | ]\}}| | qS r   r   r|   r   r   r   r}     s      z%NDimArray.__mul__.<locals>.<dictcomp>c                    s   g | ]}|  qS r   r   rG   r   r   r   rU     s     z%NDimArray.__mul__.<locals>.<listcomp>rO   rN   r/   r[   r~   r{   r8   r   r-   r:   r   is_zeror   r1   r^   ra   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   rZ   rz   r   c                    s   i | ]\}}| | qS r   r   r|   r   r   r   r}     s      z&NDimArray.__rmul__.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   rG   r   r   r   rU     s     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   rZ   rz   zscalar expectedc                    s   i | ]\}}||  qS r   r   r|   r   r   r   r}     s      z)NDimArray.__truediv__.<locals>.<dictcomp>c                    s   g | ]}|  qS r   r   rG   r   r   r   rU     s     z)NDimArray.__truediv__.<locals>.<listcomp>)rO   rN   r/   r[   r~   r{   r8   r   r-   r:   r   r
   r   r   r^   ra   r1   r   r   r   r   __truediv__  s    $zNDimArray.__truediv__c                 C   s   t dd S )Nz"unsupported operation on NDimArrayr3   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   rZ   rz   c                 S   s   i | ]\}}|| qS r   r   r|   r   r   r   r}     s      z%NDimArray.__neg__.<locals>.<dictcomp>c                 S   s   g | ]
}| qS r   r   rG   r   r   r   rU     s     z%NDimArray.__neg__.<locals>.<listcomp>)	r/   r[   r~   r{   r8   r   r^   ra   r1   )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   rZ   F)r/   r[   r8   r-   r1   r_   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   )ri   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     s     z-NDimArray._eval_conjugate.<locals>.<listcomp>)r~   r{   funcr1   )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   *  s     z+NDimArray._slice_expand.<locals>.<listcomp>)r8   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   -  s     z>NDimArray._get_slice_data_for_array_access.<locals>.<listcomp>)rK   r1   	itertoolsproduct)r   r6   
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   )r8   r   minrG   r   r   r   rU   5  s     zBNDimArray._get_slice_data_for_array_assignment.<locals>.<listcomp>)r8   r-   r   r   )r   r6   rP   r   r   Z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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_listr1   r   r   r   _check_special_bounds9  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   F  s     z5NDimArray._check_index_for_getitem.<locals>.<genexpr>z-Dimension of index greater than rank of array)	r8   r   r	   r   r$   ri   rD   r<   r:   r5   r   r   r   _check_index_for_getitem@  s    z"NDimArray._check_index_for_getitem)N)NN).r'   r(   r)   r*   Z	_diff_wrtZ	is_scalarr   r7   r?   rF   rL   rQ   r+   rY   rg   rh   propertyr1   ri   ro   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   Q  s    zImmutableNDimArray.__hash__c                 C   s   | S r   r   r   r   r   r   rm   T  s    zImmutableNDimArray.as_immutablec                 C   s   t dd S )Nzabstract methodr3   r   r   r   r   
as_mutableW  s    zImmutableNDimArray.as_mutableN)r'   r(   r)   Z_op_priorityr   rm   r   r   r   r   r   r   N  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   {