o
    oh&                     @   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 ]' |du 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   h/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/concrete/delta.py
<listcomp>#       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stdd}g }| jD ]}|du r/t||r/|}q!|	| q!|| 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   as_poly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 ]}t|tr/|	|jd |jd   q|	| q|s9| S t
|dd}t|dkrHtjS t|dkrp|d  D ]}|	t||d |  qT| j| }| |krpt|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!   eqsnewargsr)   solnskeyexpr2r   r   r   r3   z   s,   


r3   c                 C   sx   t | tr:z*t| jd | jd  dd}|r*t|dkr-tdd |d  D  W S W | S W | S  ty9   Y | S w | 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   r:   valuer   r   r   r      s    z#_simplify_delta.<locals>.<listcomp>)r%   r   r   r   r4   r   itemsNotImplementedError)r!   slnsr   r   r   _simplify_delta   s    


r@   c              	      s  d d  dk dkrt jS | tst| S | jrd g }t| jtdD ]} du r7t	|d r7| q'|
| q'| j| tddd}td trytd trytt fd	d
ttd td d D  }t|S t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y   t| Y S w 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)r:   kprime)integerc                 3   sX    | ]'}t d  d |d f d  | t d  |d d f V  qdS )r   r   rA   N)deltaproductsubs)r   ikr#   limitnewexprr   r   	<genexpr>   s    zdeltaproduct.<locals>.<genexpr>)no_piecewise)r   r   r+   r   r   r   sortedr   r   r   r(   r    r	   r%   intrD   sumrangedeltasummationrE   r3   r*   r$   r   AssertionErrorr@   )frH   r   r)   kresult_gr   rG   r   rD      sR   





(rD   Fc                    sV   d  d  dk dkrt jS | tst|  S  d }t| |}|jr5t|j fdd|j	D  S t
||\}}|dur`|jdur`|j\}} d | dkdkr` d | dkdkr`d|sgt|  S t|j	d |j	d  |}	t|	dkr}t jS t|	dkrt|  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
    rA   r   r   Tc                    s   g | ]}t | qS r   )rP   )r   r   rH   rK   r   r   r   2  r   z"deltasummation.<locals>.<listcomp>N   )r   r5   r+   r   r   r$   r   r   r    r   r*   delta_ranger   r4   r   rE   r   r   as_relational)rR   rH   rK   xrV   r#   r!   dinfdsupr9   r<   r   rW   r   rP      s:   D



(

 rP   N)F)!__doc__productsr   
summationsr   r   
sympy.corer   r   r   r	   sympy.core.cacher
   sympy.core.sortingr   sympy.functionsr   r   r   sympy.polys.polytoolsr   sympy.sets.setsr   sympy.solvers.solversr   r$   r*   r   r'   r3   r@   rD   rP   r   r   r   r   <module>   s4    	

2




: