
    Ed&                     @   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             Zed             Zed             Zed             Zed             Zed             Zed             Zedd            Z dS )z
This module implements sums and products containing the Kronecker Delta function.

References
==========

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

   )product)Sum	summation    )AddMulSDummy)cacheit)default_sort_key)KroneckerDelta	Piecewisepiecewise_fold)factor)Interval)solvec                     | j         s| S d}t          }t          j        g| j        D ]F|4j        r-t          |          rd}j        }fdj        D             8fdD             G | S )zB
    Expand the first Add containing a simple KroneckerDelta.
    NTc                 &    g | ]}d          |z  S )r    ).0ttermss     4lib/python3.11/site-packages/sympy/concrete/delta.py
<listcomp>z!_expand_delta.<locals>.<listcomp>#   s!    000AU1XaZ000    c                     g | ]}|z  S r   r   )r   r   hs     r   r   z!_expand_delta.<locals>.<listcomp>%   s    (((QQqS(((r   )is_Mulr   r	   Oneargsis_Add_has_simple_deltafunc)exprindexdeltar#   r   r   s       @@r   _expand_deltar'      s    
 ; EDUGEY ) ) 	)QX 	)*;Au*E*E 	)E6D0000000EE((((%(((EE4<r   c                 $   t          | |          sd| fS t          | t                    r| t          j        fS | j        st          d          d}g }| j        D ],}|t          ||          r|}|	                    |           -| | 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   args        r   _extract_deltar.   )   s    D T5)) d|$'' ae}; +)***EEy   	-c599 	EELL949e$%%r   c                     |                      t                    r=t          | |          rdS | j        s| j        r| j        D ]}t          ||          r dS 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-   s      r   r"   r"   \   sv     xx  D%(( 	4; 	 $+ 	 y    $S%00  44 5r   c                     t          | t                    r]|                     |          rH| j        d         | j        d         z
                      |          }|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   r0   r    as_polydegree)r&   r%   ps      r   r+   r+   m   sl     %(( #UYYu-=-= #Z]UZ]*33E:: 	#88::?"5r   c                    | j         r/ | j        t          t          t          | j                             S | j        s| S g }g }| j        D ][}t          |t                    r/|	                    |j        d         |j        d         z
             F|	                    |           \|s| S t          |d          }t          |          dk    rt          j        S t          |          dk    rk|d                                         D ]1}|	                    t          ||d         |                              2 | j        | }| |k    rt	          |          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expr2s          r   r:   r:   z   sc   
 { Hty$s#949EEFFGG; 
CGy    c>** 	 JJsx{SXa[01111NN3 #D!!!E
5zzQ 1v	Uq 18==?? 	? 	?CNN>#uQx}==>>>>	7#5= 	1)%000Kr   c                 (   t          | t                    r|	 t          | j        d         | j        d         z
  d          }|r>t	          |          dk    r+t          d |d                                         D              S n# t          $ r Y nw xY w| S )zB
    Rewrite a KroneckerDelta's indices in its simplest form.
    r   r   Tr6   c                 *    g | ]\  }}t          ||f S r   )r   )r   rA   values      r   r   z#_simplify_delta.<locals>.<listcomp>   s5     ? ? ? *U ,c5\: ? ? ?r   )r)   r   r   r    r;   r   itemsNotImplementedError)r$   slnss     r   _simplify_deltarI      s    
 $'' 	1	!44@@@D @D		Q @ ? ?.21gmmoo? ? ? @ @" 	 	 	D	Ks   A)B 
BBc                 H  	 d         d         z
  dk     dk    rt           j        S |                     t                    st	          |           S | j        rdg }t          | j        t                    D ]2}t          |d                   r||
                    |           3 | j        | 	t          dd          }t          d         t                    rt          d         t                    rft          	          t!          	fd	t#          t          d                   t          d         dz                       D                       z   }nt          	          t%          t          	d         d         |dz
  f                              d         |          z  t          	d         |dz   d         f          z  |d         d         ft          	d                   
          z   }t)          |          S t+          | d                   \  }sjt-          | d                   }| |k    r>	 t/          t          |                    S # t0          $ r t          |          cY S w xY wt	          |           S t)          |                     d         d                   t          d         d                   z            t           j        t3          t          d         d         dz
                      z  z   S )z
    Handle products containing a KroneckerDelta.

    See Also
    ========

    deltasummation
    sympy.functions.special.tensor_functions.KroneckerDelta
    sympy.concrete.products.product
       r   r   TN)rA   kprime)integerc           
          g | ]d}t          d          d         |dz
  f                              d          |          z  t          d          |dz   d         f          z  eS )r   r   rK   )deltaproductsubs)r   ikr&   limitnewexprs     r   r   z deltaproduct.<locals>.<listcomp>   s     9w 9w 9w IK WuQxq26&BCC

58R(()WuQxaq&BCCD9w 9w 9wr   )no_piecewise)r	   r   r0   r   r   r!   sortedr    r   r"   r,   r#   r
   r)   intrO   sumrangedeltasummationrP   r:   r.   r'   r   AssertionErrorrI   )
frR   r   r-   kresult_gr&   rS   s
    `      @@r   rO   rO      s_    
qE!H	!d* u55   !q%   x .!&&6777 	" 	"C "!23a!A!A "S!!!!!&%.(D)))eAh$$ 	E!Hc)B)B 	!'511C 9w 9w 9w 9w 9w 9w OTTWX]^_X`TaTacfglmngorsgsctctNuNu9w 9w 9w 5 5 FF "'511NWuQxq1q5&ABB

58Q''(WuQxQa&ABBC E!HeAh'.waAA5 5 5 F &f---aq**HE1 !!U1X&&6 	..l1e44555! . . .#Au-----.q%   !!&&q58"<"<^ERSHV[\]V^=_=_"_``	onU1XuQx!|DDEEEF Fs   I. .J
JFc                    d         d         z
  dk     dk    rt           j        S |                     t                    st	          |           S d         }t          | |          }|j        r)t           |j        fd|j	        D                        S t          ||          \  }}|9|j        2|j        \  }}d         |z
  dk    dk    rd         |z
  dk    dk    rd|st	          |           S t          |j	        d         |j	        d         z
  |          }	t          |	          dk    rt           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
    rK   r   r   Tc                 2    g | ]}t          |          S r   )rY   )r   r   rR   rT   s     r   r   z"deltasummation.<locals>.<listcomp>3  s%    LLL^Aul;;LLLr   N   )r	   r<   r0   r   r   r'   r!   r   r#   r    r.   delta_ranger   r;   r   rP   r   r   as_relational)r[   rR   rT   xr_   r&   r$   dinfdsupr@   rE   s    ``        r   rY   rY      s   H 
qE!H	!d* v55   #E"""aAaAx OAFLLLLLQVLLLMO O 	O !A&&KE4   1  &
d!HtOq T) 	 uQx$!/C.L 	 L #E"""%*Q-%*Q-/33E
5zzQ v	Uq 1e}}!HE #yyE"""	1e		hac
3AA%HHI	
  r   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+   r:   rI   rO   rY   r   r   r   <module>rr      s          & & & & & & & & ) ) ) ) ) ) ) ) ) ) ) ) $ $ $ $ $ $ / / / / / / E E E E E E E E E E ( ( ( ( ( ( $ $ $ $ $ $ ' ' ' ' ' ' 	  	& 	/& /& 	/&d 	  	  		 	 		 	  	: 	  	 	8F 8F 	8Fv 	f f f 	f f fr   