
    wg&                        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 y)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                 D   | j                   s| S d}t        }t        j                  g}| j                  D ]\  }|F|j
                  r:t        ||      r.d}|j                  }|j                  D cg c]
  }|d   |z   }}K|D cg c]  }||z  	 }}^  || S c c}w c c}w )zB
    Expand the first Add containing a simple KroneckerDelta.
    NTr   )is_Mulr   r	   Oneargsis_Add_has_simple_deltafunc)exprindexdeltar   termshts          Y/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/concrete/delta.py_expand_deltar!      s    
 ;;EDUUGEYY )=QXX*;Au*EE66D)*0AU1XaZ0E0"'(QQqS(E() < 1(s   -BBc                 $   t        | |      sd| fS t        | t              r| t        j                  fS | j
                  st        d      d}g }| j                  D ]$  }|t        ||      r|}|j                  |       & | | 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|$'aee};;)**EEyy =-c59ELL	
 9499e$%%    c                     | j                  t              rDt        | |      ry| j                  s| j                  r| j
                  D ]  }t        ||      s y y)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   \   sO     xxD%(;;$++yy  $S%0  r)   c                     t        | t              rT| j                  |      rC| j                  d   | j                  d   z
  j	                  |      }|r|j                         dk(  S y)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   ps      r    r%   r%   m   sT     %(UYYu-=ZZ]UZZ]*33E:88:?"r)   c                    | j                   r0 | j                  t        t        t        | j
                               S | j                  s| S g }g }| j
                  D ]R  }t        |t              r/|j                  |j
                  d   |j
                  d   z
         B|j                  |       T |s| S t        |d      }t        |      dk(  rt        j                  S t        |      dk(  rX|d   j                         D ]#  }|j                  t        ||d   |                %  | j                  | }| |k7  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    r5   r5   z   s   
 {{tyy$s#9499EFGG;;
CGyy  c>*JJsxx{SXXa[01NN3	 
 #D!E
5zQvv	Uq8==? 	?CNN>#uQx}=>	?		7#5=)%00Kr)   c           
      4   t        | t              rq	 t        | j                  d   | j                  d   z
  d      }|rBt	        |      dk(  r4t        |d   j                         D cg c]  \  }}t        ||f  c}} S | S | S c c}}w # t        $ r Y | S w xY w)zB
    Rewrite a KroneckerDelta's indices in its simplest form.
    r   r   Tr1   )r#   r   r   r   r6   r   itemsNotImplementedError)r   slnsr<   values       r    _simplify_deltarC      s    
 $'	1		!44@DD	Q.21gmmo? *U ,c5\: ? @ @ K4K	?" 	K	s$   AB
 'B
;B
 B
 
	BBc                   	 d   d   z
  dk  dk(  rt         j                  S | j                  t              st	        |       S | j
                  r_dg }t        | j                  t              D ]'  }t        |d         r||j                  |       )  | j                  | 	t        dd      }t        d   t              rft        d   t              rSt        	      t!        	fd	t#        t        d         t        d   dz               D              z   }t)        |      S t        	      t%        t        	d   d   |dz
  f      j'                  d   |      z  t        	d   |dz   d   f      z  |d   d   ft        	d         
      z   }t)        |      S t+        | d         \  }s6t-        | d         }| |k7  r	 t/        t        |            S t	        |       S t)        | j'                  d   d         t        d   d         z        t         j                  t3        t        d   d   dz
              z  z   S # t0        $ r t        |      cY S w xY w)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      K   | ]K  }t        d    d   |dz
  f      j                  d    |      z  t        d    |dz   d   f      z   M yw)r   r   rE   N)deltaproductsubs).0ikr   limitnewexprs     r    	<genexpr>zdeltaproduct.<locals>.<genexpr>   su      8HJ 9EWuUVxY^_`YacehiciNj8k

58R(9)WuQxaq&BC9D 8s   AA)no_piecewise)r	   r   r+   r   r   r   sortedr   r   r   r&   r   r
   r#   intrI   sumrangedeltasummationrJ   r5   r(   r!   r   AssertionErrorrC   )
frM   r   r'   kresult_gr   rN   s
    `      @@r    rI   rI      s    
qE!H	!d*uu55 q%  xx!&&&67 	"C}!23a!AS!		"
 !&&%.(D)eAh$E!Hc)B!'51C 8NSTWX]^_X`TacfglmngorsgsctNu8 5 F &f-- "'51NWuQxq1q5&AB

58Q'(WuQxQa&ABC E!HeAh'.waA5 F &f--aq*HE1!U1X&6.l1e455 q%  !!&&q58"<^ERSHV[\]V^=_"_`	onU1XuQx!|DEEF F	 " .#Au--.s   I   I87I8c                 p   |d   |d   z
  dk  dk(  rt         j                  S | j                  t              st	        | |      S |d   }t        | |      }|j                  r;t         |j                  |j                  D cg c]  }t        |||       c}       S t        ||      \  }}|9|j                  -|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k7  rt        | |      S |
d   }|r|j!                  ||      S t#        |j!                  ||      t%        |dd  j'                  |      ft         j                  df      S c c}w )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
    rE   r   r   T   )r	   r7   r+   r   r   r!   r   r   r   r   rU   r(   delta_ranger   r6   r   rJ   r   r   as_relational)rW   rM   rP   xr[   r   r   r   dinfdsupr;   rB   s               r    rU   rU      s   H 
qE!H	!d*vv55 E""aAaAxxAFFQVVL^Aul;LMO 	O !A&KE4 1 1 =&&
d!HtOq T)uQx$!/C.LLE""%**Q-%**Q-/3E
5zQvv	Uq1e}!HEyyE""	1e	ha
3AA%HI	
 + Ms   ?F3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%   r5   rC   rI   rU    r)   r    <module>rn      s     & ) ) $ / E E ( $ ' 	 	& 	/& 	/&d 	 	  		 		 	 	: 	 	 	7F 	7Ft 	f 	fr)   