B
    ˜‘[ø  ã               @   sX   d dl mZmZ d dlmZ d dlmZmZ d dlm	Z	 d dl
mZ dd„ Zdd	„ Zd
S )é    )Úprint_functionÚdivision)ÚMul)Ú
DiracDeltaÚ	Heaviside)Údefault_sort_key)ÚSc       	   	   C   s<  g }d}|   ¡ \}}t|td}| |¡ xj|D ]b}|jrft|jtƒrf| | 	|j|j
d ¡¡ |j}|dkrˆt|tƒrˆ| |¡rˆ|}q0| |¡ q0W |s0g }xj|D ]b}t|tƒrÊ| |jd|d¡ q¦|jrþt|jtƒrþ| | 	|jjd|d|j
¡¡ q¦| |¡ q¦W ||kr$t|Ž  ¡ }nd}d|fS |t|Ž fS )a  change_mul(node, x)

       Rearranges the operands of a product, bringing to front any simple
       DiracDelta expression.

       If no simple DiracDelta expression was found, then all the DiracDelta
       expressions are simplified (using DiracDelta.expand(diracdelta=True, wrt=x)).

       Return: (dirac, new node)
       Where:
         o dirac is either a simple DiracDelta expression or None (if no simple
           expression was found);
         o new node is either a simplified DiracDelta expressions or None (if it
           could not be simplified).

       Examples
       ========

       >>> from sympy import DiracDelta, cos
       >>> from sympy.integrals.deltafunctions import change_mul
       >>> from sympy.abc import x, y
       >>> change_mul(x*y*DiracDelta(x)*cos(x), x)
       (DiracDelta(x), x*y*cos(x))
       >>> change_mul(x*y*DiracDelta(x**2 - 1)*cos(x), x)
       (None, x*y*cos(x)*DiracDelta(x - 1)/2 + x*y*cos(x)*DiracDelta(x + 1)/2)
       >>> change_mul(x*y*DiracDelta(cos(x))*cos(x), x)
       (None, None)

       See Also
       ========

       sympy.functions.special.delta_functions.DiracDelta
       deltaintegrate
    N)Úkeyé   T)Ú
diracdeltaÚwrt)Zargs_cncÚsortedr   ÚextendÚis_PowÚ
isinstanceÚbaser   ÚappendÚfuncZexpÚ	is_simpleÚexpandr   )	ZnodeÚxZnew_argsZdiracÚcZncZsorted_argsÚargZnnode© r   ú=lib/python3.7/site-packages/sympy/integrals/deltafunctions.pyÚ
change_mul	   s2    $



"
r   c             C   s  |   t¡sdS ddlm}m} ddlm} | jtkr¾| jd|d}|| kr¬|  	|¡rºt
| jƒdksp| jd dkr~t| jd ƒS t| jd | jd d ƒ| jd  ¡  ¡  S n|||ƒ}|S nR| jsÌ| jr|  ¡ }| |kr|||ƒ}|dk	rt||ƒs|S n
t| |ƒ\}}	|s0|	r||	|ƒ}|S nà|jd|d}|jr\t||ƒ\}}
|	|
 }	||jd |ƒd }t
|jƒdkr„dn|jd }d}xv|dkrd| |	 ||¡ ||¡ }|tjkrØ|d8 }|d7 }n,|dkrò|t|| ƒ S |t||d ƒ S q”W tjS dS )	aÉ  
    deltaintegrate(f, x)

    The idea for integration is the following:

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

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

      If we couldn't simplify it, there are two cases:

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

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

    - If the node is a multiplication node having a DiracDelta term:

      First we expand it.

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

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

      1) We have a simple DiracDelta term, so we return the integral.

      2) We didn't have a simple term, but we do have an expression with
         simplified DiracDelta terms, so we integrate this expression.

    Examples
    ========

        >>> from sympy.abc import x, y, z
        >>> from sympy.integrals.deltafunctions import deltaintegrate
        >>> from sympy import sin, cos, DiracDelta, Heaviside
        >>> deltaintegrate(x*sin(x)*cos(x)*DiracDelta(x - 1), x)
        sin(1)*cos(1)*Heaviside(x - 1)
        >>> deltaintegrate(y**2*DiracDelta(x - z)*DiracDelta(y - z), y)
        z**2*DiracDelta(x - z)*Heaviside(y - z)

    See Also
    ========

    sympy.functions.special.delta_functions.DiracDelta
    sympy.integrals.integrals.Integral
    Nr   )ÚIntegralÚ	integrate)ÚsolveT)r   r   r
   éÿÿÿÿ)Zhasr   Zsympy.integralsr   r   Zsympy.solversr   r   r   r   ÚlenÚargsr   Zas_polyZLCZis_Mulr   r   r   ZdiffZsubsr   ZZero)Úfr   r   r   r   ÚhZfhÚgZ	deltatermZ	rest_multZrest_mult_2ZpointÚnÚmÚrr   r   r   ÚdeltaintegrateO   sT    5








r(   N)Z
__future__r   r   Z
sympy.corer   Zsympy.functionsr   r   Zsympy.core.compatibilityr   Zsympy.core.singletonr   r   r(   r   r   r   r   Ú<module>   s   F