ó
¡¼™\c           @  s  d  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 m Z d d l m Z m Z 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
 e d „ ƒ Z d S(   sŸ   
This module implements sums and products containing the Kronecker Delta function.

References
==========

- http://mathworld.wolfram.com/KroneckerDelta.html

iÿÿÿÿ(   t   print_functiont   division(   t   Addt   Mult   St   Dummy(   t   cacheit(   t   default_sort_keyt   range(   t   KroneckerDeltat	   Piecewiset   piecewise_fold(   t   Intervalc         C  s½   |  j  s |  Sd } t } t d ƒ g } xˆ |  j D]} } | d k r’ | j r’ t | | ƒ r’ t } | j } g  | j D] } | d | ^ qu } q2 g  | D] } | | ^ q™ } q2 W| | Œ  S(   sB   
    Expand the first Add containing a simple KroneckerDelta.
    i   i    N(	   t   is_Mult   NoneR   R   t   argst   is_Addt   _has_simple_deltat   Truet   func(   t   exprt   indext   deltaR   t   termst   ht   t(    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyt   _expand_delta   s    	$	'!c         C  s´   t  |  | ƒ s d |  f St |  t ƒ r8 |  t d ƒ f S|  j sP t d ƒ ‚ n  d } g  } xB |  j D]7 } | d k r t | | ƒ r | } qf | j	 | ƒ qf W| |  j
 | Œ  f S(   ss  
    Extract a simple KroneckerDelta from the expression.

    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
    i   s   Incorrect exprN(   R   R   t
   isinstanceR	   R   R   t
   ValueErrorR   t   _is_simple_deltat   appendR   (   R   R   R   R   t   arg(    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyt   _extract_delta&   s    
		c         C  se   |  j  t ƒ ra t |  | ƒ r" t S|  j s4 |  j ra x' |  j D] } t | | ƒ r> t Sq> Wqa n  t S(   sØ   
    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``.
    (	   t   hasR	   R   R   R   R   R   R   t   False(   R   R   R   (    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyR   V   s    c         C  s\   t  |  t ƒ rX |  j | ƒ rX |  j d |  j d j | ƒ } | rX | j ƒ  d k Sn  t S(   su   
    Returns True if ``delta`` is a KroneckerDelta and is nonzero for a single
    value of the index ``index``.
    i    i   (   R   R	   R!   R   t   as_polyt   degreeR"   (   R   R   t   p(    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyR   g   s
    !c         C  sO  d d l  m } |  j r8 |  j t t t |  j ƒ ƒ Œ  S|  j sE |  Sg  } g  } xO |  j D]D } t	 | t
 ƒ r’ | j | j d | j d ƒ q[ | j | ƒ q[ W| s­ |  S| | d t ƒ} t | ƒ d k rØ t j St | ƒ d k rKx6 | d j ƒ  D]$ } | j t
 | | d | ƒ ƒ qû W|  j | Œ  } |  | k rKt | ƒ Sn  |  S(   s0   
    Evaluate products of KroneckerDelta's.
    iÿÿÿÿ(   t   solvei    i   t   dict(   t   sympy.solversR&   R   R   t   listt   mapt   _remove_multiple_deltaR   R   R   R	   R   R   t   lenR   t   Zerot   keys(   R   R&   t   eqst   newargsR   t   solnst   keyt   expr2(    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyR+   t   s.    		""c         C  s³   d d l  m } t |  t ƒ r¯ yy | |  j d |  j d d t ƒ} | r— t | ƒ d k r— t g  | d j ƒ  D] \ } } t | | f Œ  ^ qr Œ  SWq¯ t	 k
 r« q¯ Xn  |  S(   sB   
    Rewrite a KroneckerDelta's indices in its simplest form.
    iÿÿÿÿ(   R&   i    i   R'   (
   R(   R&   R   R	   R   R   R,   R   t   itemst   NotImplementedError(   R   R&   t   slnsR2   t   value(    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyt   _simplify_delta“   s    $7c         C  s[  d d l  m } | d | d d k  t k r5 t j S|  j t ƒ sQ | |  | ƒ S|  j rDd } g  } xR t	 |  j
 d t ƒD]; } | d k rª t | | d ƒ rª | } q| | j | ƒ q| W|  j | Œ  } t d d t ƒ} t | d t ƒ r¦t | d t ƒ r¦t | | ƒ t g  t t | d ƒ t | d d ƒ ƒ D]` } t | | d | d | d f ƒ | j | d | ƒ t | | d | d | d f ƒ ^ q9ƒ }	 n” t | | ƒ t t | | d | d | d f ƒ | j | d | ƒ t | | d | d | d f ƒ | | d | d f d	 t | | d ƒ ƒ}	 t |	 ƒ St |  | d ƒ \ } }
 | s×t |  | d ƒ } |  | k rÊd d
 l m } y | t | | ƒ ƒ SWqÊt k
 rÆt | | ƒ SXn  | |  | ƒ Sd d l m } | | d | d d ƒ } t |  j | d | d ƒ t | d | d ƒ ƒ t j t t | d | d d ƒ ƒ S(   sÅ   
    Handle products containing a KroneckerDelta.

    See Also
    ========

    deltasummation
    sympy.functions.special.tensor_functions.KroneckerDelta
    sympy.concrete.products.product
    iÿÿÿÿ(   t   producti   i   i    R2   t   kprimet   integert   no_piecewise(   t   factor(   t   EqN(   t   sympy.concrete.productsR9   R   R   t   OneR!   R	   R   R   t   sortedR   R   R   R   R   R   R   t   intt   deltaproductt   sumR   t   subst   deltasummationR+   R    R   t   sympyR=   t   AssertionErrorR>   R8   (   t   ft   limitR9   R   R   R   t   newexprt   kt   ikt   resultt   _t   gR=   R>   t   c(    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyRC   ¤   sL    		&’5"
2c         C  s§  d d l  m } d d l m } | d | d d k  t k rE t j S|  j t ƒ sa | |  | ƒ S| d } t	 |  | ƒ } | j
 r¸ t | j g  | j D] } t | | | ƒ ^ q– Œ  ƒ St | | ƒ \ } }	 | sà | |  | ƒ S| | j d | j d | ƒ }
 t |
 ƒ d k rt j St |
 ƒ d k rId d l  m } | |  | ƒ S|
 d } | ri|	 j | | ƒ St |	 j | | ƒ t | d d !Œ  j | ƒ f t j t f ƒ S(	   s_  
    Handle summations containing a KroneckerDelta.

    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 couldn't 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 didn't 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, Piecewise
    >>> 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
    iÿÿÿÿ(   t	   summation(   R&   i   i   i    (   t   Sumi   (   t   sympy.concrete.summationsRR   R(   R&   R   R   R-   R!   R	   R   R   R   R   R   RF   R    R,   RS   RE   R
   R   t   as_relational(   RI   RJ   R<   RR   R&   t   xRP   R   R   R   R1   RS   R7   (    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyRF   å   s4    A
	2!
+N(   t   __doc__t
   __future__R    R   t
   sympy.coreR   R   R   R   t   sympy.core.cacheR   t   sympy.core.compatibilityR   R   t   sympy.functionsR	   R
   R   t
   sympy.setsR   R   R    R   R   R+   R8   RC   R"   RF   (    (    (    s3   lib/python2.7/site-packages/sympy/concrete/delta.pyt   <module>	   s   "0A