U
    9%e&                     @   s   d Z ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
 ddl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 edd Zedd Zedd Zedd Zedd Zedd Zedd ZedddZ dS )z
This module implements sums and products containing the Kronecker Delta function.

References
==========

.. [1] https://mathworld.wolfram.com/KroneckerDelta.html

   )product)Sum	summation    )AddMulSDummy)cacheit)default_sort_key)KroneckerDelta	Piecewisepiecewise_fold)factor)Interval)solvec                    sx   | j s
| S d}t}tjg| jD ]N |dkr\ jr\t |r\d} j}fdd jD q  fddD q | S )zB
    Expand the first Add containing a simple KroneckerDelta.
    NTc                    s   g | ]} d  | qS )r    .0t)termsr   S/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/sympy/concrete/delta.py
<listcomp>#   s     z!_expand_delta.<locals>.<listcomp>c                    s   g | ]}|  qS r   r   r   )hr   r   r   %   s     )is_Mulr   r   Oneargsis_Add_has_simple_deltafunc)exprindexdeltar   r   )r   r   r   _expand_delta   s    
r#   c                 C   sx   t | |sd| fS t| tr&| tjfS | js4tdd}g }| jD ]&}|dkr^t||r^|}qB|	| qB|| j
| fS )a  
    Extract a simple KroneckerDelta from the expression.

    Explanation
    ===========

    Returns the tuple ``(delta, newexpr)`` where:

      - ``delta`` is a simple KroneckerDelta expression if one was found,
        or ``None`` if no simple KroneckerDelta expression was found.

      - ``newexpr`` is a Mul containing the remaining terms; ``expr`` is
        returned unchanged if no simple KroneckerDelta expression was found.

    Examples
    ========

    >>> from sympy import KroneckerDelta
    >>> from sympy.concrete.delta import _extract_delta
    >>> from sympy.abc import x, y, i, j, k
    >>> _extract_delta(4*x*y*KroneckerDelta(i, j), i)
    (KroneckerDelta(i, j), 4*x*y)
    >>> _extract_delta(4*x*y*KroneckerDelta(i, j), k)
    (None, 4*x*y*KroneckerDelta(i, j))

    See Also
    ========

    sympy.functions.special.tensor_functions.KroneckerDelta
    deltaproduct
    deltasummation
    NzIncorrect expr)r   
isinstancer   r   r   r   
ValueErrorr   _is_simple_deltaappendr   )r    r!   r"   r   argr   r   r   _extract_delta)   s    "



r)   c                 C   sD   |  tr@t| |rdS | js$| jr@| jD ]}t||r* dS q*dS )z
    Returns True if ``expr`` is an expression that contains a KroneckerDelta
    that is simple in the index ``index``, meaning that this KroneckerDelta
    is nonzero for a single value of the index ``index``.
    TF)hasr   r&   r   r   r   r   )r    r!   r(   r   r   r   r   \   s    



r   c                 C   sB   t | tr>| |r>| jd | jd  |}|r>| dkS dS )zu
    Returns True if ``delta`` is a KroneckerDelta and is nonzero for a single
    value of the index ``index``.
    r   r   F)r$   r   r*   r   Zas_polyZdegree)r"   r!   pr   r   r   r&   m   s
    r&   c                 C   s   | j r| jttt| j S | js&| S g }g }| jD ]4}t|tr^|	|jd |jd   q4|	| q4|sr| S t
|dd}t|dkrtjS t|dkr|d  D ]}|	t||d |  q| j| }| |krt|S | S )z0
    Evaluate products of KroneckerDelta's.
    r   r   Tdict)r   r   listmap_remove_multiple_deltar   r   r$   r   r'   r   lenr   Zerokeys)r    ZeqsZnewargsr(   solnskeyZexpr2r   r   r   r0   z   s,    


r0   c                 C   sp   t | trlzLt| jd | jd  dd}|rTt|dkrTtdd |d  D  W S W n tk
rj   Y nX | S )zB
    Rewrite a KroneckerDelta's indices in its simplest form.
    r   r   Tr,   c                 S   s   g | ]\}}t ||f qS r   )r   )r   r5   valuer   r   r   r      s   z#_simplify_delta.<locals>.<listcomp>)r$   r   r   r   r1   r   itemsNotImplementedError)r    Zslnsr   r   r   _simplify_delta   s    

r9   c              	      s   d d  dk dkrt jS | ts2t| S | jrjd g }t| jtdD ]*} dkrpt	|d rp| qP|
| qP| j| tddd}td trtd trtt fd	d
ttd td d D  }nttttd d |d f d | td |d d f |d d ft	d d }t|S t| d \ } st| d }| |krztt|W S  tk
r   t| Y S X t| S t| d d td d  t jttd d d   S )z
    Handle products containing a KroneckerDelta.

    See Also
    ========

    deltasummation
    sympy.functions.special.tensor_functions.KroneckerDelta
    sympy.concrete.products.product
       r   r   TN)r5   Zkprime)integerc              	      sT   g | ]L}t d  d |d f d  | t d  |d d f qS )r   r   r:   )deltaproductsubs)r   ikr"   limitZnewexprr   r   r      s   z deltaproduct.<locals>.<listcomp>)no_piecewise)r   r   r*   r   r   r   sortedr   r   r   r'   r   r	   r$   intr<   sumrangedeltasummationr=   r0   r)   r#   r   AssertionErrorr9   )fr@   r   r(   kresult_gr   r?   r   r<      sN    





(r<   Fc                    sZ   d  d  dk dkrt jS | ts2t|  S  d }t| |}|jrjt|j fdd|j	D  S t
||\}}|dk	r|jdk	r|j\}} d | dkdkr d | dkdkrd|st|  S t|j	d |j	d  |}	t|	dkrt jS t|	dkrt|  S |	d }
r,|||
S t|||
t dd  |
ft jdfS )	aw  
    Handle summations containing a KroneckerDelta.

    Explanation
    ===========

    The idea for summation is the following:

    - If we are dealing with a KroneckerDelta expression, i.e. KroneckerDelta(g(x), j),
      we try to simplify it.

      If we could simplify it, then we sum the resulting expression.
      We already know we can sum a simplified expression, because only
      simple KroneckerDelta expressions are involved.

      If we could not simplify it, there are two cases:

      1) The expression is a simple expression: we return the summation,
         taking care if we are dealing with a Derivative or with a proper
         KroneckerDelta.

      2) The expression is not simple (i.e. KroneckerDelta(cos(x))): we can do
         nothing at all.

    - If the expr is a multiplication expr having a KroneckerDelta term:

      First we expand it.

      If the expansion did work, then we try to sum the expansion.

      If not, we try to extract a simple KroneckerDelta term, then we have two
      cases:

      1) We have a simple KroneckerDelta term, so we return the summation.

      2) We did not have a simple term, but we do have an expression with
         simplified KroneckerDelta terms, so we sum this expression.

    Examples
    ========

    >>> from sympy import oo, symbols
    >>> from sympy.abc import k
    >>> i, j = symbols('i, j', integer=True, finite=True)
    >>> from sympy.concrete.delta import deltasummation
    >>> from sympy import KroneckerDelta
    >>> deltasummation(KroneckerDelta(i, k), (k, -oo, oo))
    1
    >>> deltasummation(KroneckerDelta(i, k), (k, 0, oo))
    Piecewise((1, i >= 0), (0, True))
    >>> deltasummation(KroneckerDelta(i, k), (k, 1, 3))
    Piecewise((1, (i >= 1) & (i <= 3)), (0, True))
    >>> deltasummation(k*KroneckerDelta(i, j)*KroneckerDelta(j, k), (k, -oo, oo))
    j*KroneckerDelta(i, j)
    >>> deltasummation(j*KroneckerDelta(i, j), (j, -oo, oo))
    i
    >>> deltasummation(i*KroneckerDelta(i, j), (i, -oo, oo))
    j

    See Also
    ========

    deltaproduct
    sympy.functions.special.tensor_functions.KroneckerDelta
    sympy.concrete.sums.summation
    r:   r   r   Tc                    s   g | ]}t | qS r   )rF   )r   r   r@   rA   r   r   r   3  s     z"deltasummation.<locals>.<listcomp>N   )r   r2   r*   r   r   r#   r   r   r   r   r)   Zdelta_ranger   r1   r   r=   r   r   Zas_relational)rH   r@   rA   xrL   r"   r    ZdinfZdsupr4   r6   r   rM   r   rF      s:    D



(

 rF   N)F)!__doc__Zproductsr   Z
summationsr   r   Z
sympy.corer   r   r   r	   Zsympy.core.cacher
   Zsympy.core.sortingr   Zsympy.functionsr   r   r   Zsympy.polys.polytoolsr   Zsympy.sets.setsr   Zsympy.solvers.solversr   r#   r)   r   r&   r0   r9   r<   rF   r   r   r   r   <module>   s2   	

2




;