B
    [8                 @   s  d Z 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lmZ ddlmZmZ dd	lmZ dd
lmZmZmZmZmZ ddlmZ ddlmZ ddlmZ G dd de Z!G dd de
Z"ddl#m$Z$ dd Z%dd Z&e&dZ'dd Z(e'e(dfddZ)G dd de"Z*dd  Z+d!d" Z,G d#d$ d$e-Z.d%d& Z/e&ddid'd(Z0d)a1G d*d+ d+e"Z2d,d- Z3d.d/ Z4e'djd0d1Z5G d2d3 d3e"Z6d4d5 Z7e&ddkd6d7Z8G d8d9 d9e"Z9dld:d;Z:e&ddmd<d=Z;G d>d? d?e"Z<G d@dA dAe<Z=dBdC Z>G dDdE dEe<Z?dFdG Z@ddHlAmBZBmCZCmDZDmEZE e&ddndIdJZFG dKdL dLe"ZGG dMdN dNeGZHdOdP ZIG dQdR dReGZJdSdT ZKG dUdV dVeGZLdWdX ZMG dYdZ dZeGZNd[d\ ZOe&ddod]d^ZPG d_d` d`e"ZQG dadb dbeQZRdcdd ZSG dedf dfeQZTdgdh ZUd)S )pz Integral Transforms     )print_functiondivision)S)reducerange)Function)oo)Dummy)	integrateIntegral)_dummy)to_cnf	conjuncts	disjunctsOrAnd)simplify)default_sort_key)
MatrixBasec                   s    e Zd ZdZ fddZ  ZS )IntegralTransformErroray  
    Exception raised in relation to problems computing transforms.

    This class is mostly used internally; if integrals cannot be computed
    objects representing unevaluated transforms are usually returned.

    The hint ``needeval=True`` can be used to disable returning transform
    objects, and instead raise this exception if an integral cannot be
    computed.
    c                s"   t t| d||f  || _d S )Nz'%s Transform could not be computed: %s.)superr   __init__function)selfZ	transformr   msg)	__class__ 9lib/python3.7/site-packages/sympy/integrals/transforms.pyr   "   s    
zIntegralTransformError.__init__)__name__
__module____qualname____doc__r   __classcell__r   r   )r   r   r      s   
r   c               @   st   e Zd ZdZedd Zedd Zedd Zedd	 Zd
d Z	dd Z
dd Zdd Zedd Zdd ZdS )IntegralTransforma  
    Base class for integral transforms.

    This class represents unevaluated transforms.

    To implement a concrete transform, derive from this class and implement
    the _compute_transform(f, x, s, **hints) and _as_integral(f, x, s)
    functions. If the transform cannot be computed, raise IntegralTransformError.

    Also set cls._name.

    Implement self._collapse_extra if your function returns more than just a
    number and possibly a convergence condition.
    c             C   s
   | j d S )z! The function to be transformed. r   )args)r   r   r   r   r   8   s    zIntegralTransform.functionc             C   s
   | j d S )z; The dependent variable of the function to be transformed.    )r$   )r   r   r   r   function_variable=   s    z#IntegralTransform.function_variablec             C   s
   | j d S )z% The independent transform variable.    )r$   )r   r   r   r   transform_variableB   s    z$IntegralTransform.transform_variablec             C   s   | j j| jh| jh S )zj
        This method returns the symbols that will exist when the transform
        is evaluated.
        )r   free_symbolsunionr(   r&   )r   r   r   r   r)   G   s    zIntegralTransform.free_symbolsc             K   s   t d S )N)NotImplementedError)r   fxshintsr   r   r   _compute_transformP   s    z$IntegralTransform._compute_transformc             C   s   t d S )N)r+   )r   r,   r-   r.   r   r   r   _as_integralS   s    zIntegralTransform._as_integralc             C   s$   t | }|dkr t| jjd dd S )NF )r   r   r   name)r   extracondr   r   r   _collapse_extraV   s    z!IntegralTransform._collapse_extrac                s  ddl m}m}m} ddlm}  dd}tfddj	|D  }|r~yj
jjjf S  tk
r|   Y nX j}|js||}|jrP| d<  fdd	|jD }	g }
g }xH|	D ]@}t|ts|g}||d  t|d
kr|
|d
d g7 }
qW || }	|
s|	S y|
}
t|	gt|
 S  tk
rN   Y nX |rhtjjjd|j\}}|j|| gtjd
d    S )a  
        Try to evaluate the transform in closed form.

        This general function handles linearity, but apart from that leaves
        pretty much everything to _compute_transform.

        Standard hints are the following:

        - ``simplify``: whether or not to simplify the result
        - ``noconds``: if True, don't return convergence conditions
        - ``needeval``: if True, raise IntegralTransformError instead of
                        returning IntegralTransform objects

        The default values of these hints depend on the concrete transform,
        usually the default is
        ``(simplify, noconds, needeval) = (True, False, False)``.
        r   )Add
expand_mulMul)AppliedUndefneedevalFc             3   s   | ]}|  jV  qd S )N)hasr&   ).0func)r   r   r   	<genexpr>p   s   z)IntegralTransform.doit.<locals>.<genexpr>c                s2   g | ]*}j |gtjd d   jf  qS )r%   N)r   listr$   doit)r=   r-   )r/   r   r   r   
<listcomp>   s   z*IntegralTransform.doit.<locals>.<listcomp>r%   N)sympyr7   r8   r9   sympy.core.functionr:   popanyr   atomsr0   r&   r(   r   is_Addr$   
isinstancetupleappendlenr6   r   _nameas_coeff_mulr@   )r   r/   r7   r8   r9   r:   r;   Ztry_directlyfnresr4   ressr-   coeffrestr   )r/   r   r   rA   [   sN    



zIntegralTransform.doitc             C   s   |  | j| j| jS )N)r1   r   r&   r(   )r   r   r   r   as_integral   s    zIntegralTransform.as_integralc             G   s   | j S )N)rT   )r   r$   r   r   r   _eval_rewrite_as_Integral   s    z+IntegralTransform._eval_rewrite_as_IntegralN)r   r   r    r!   propertyr   r&   r(   r)   r0   r1   r6   rA   rT   rU   r   r   r   r   r#   (   s   	Ar#   )_solve_inequalityc             C   s,   ddl m}m} |r(t||| ddS | S )Nr   )	powdenestpiecewise_foldT)Zpolar)rC   rX   rY   r   )exprrA   rX   rY   r   r   r   	_simplify   s    r[   c                s    fdd}|S )a5  
    This is a decorator generator for dropping convergence conditions.

    Suppose you define a function ``transform(*args)`` which returns a tuple of
    the form ``(result, cond1, cond2, ...)``.

    Decorating it ``@_noconds_(default)`` will add a new keyword argument
    ``noconds`` to it. If ``noconds=True``, the return value will be altered to
    be only ``result``, whereas if ``noconds=False`` the return value will not
    be altered.

    The default value of the ``noconds`` keyword will be ``default`` (i.e. the
    argument of this function).
    c                s&   ddl m} |  fdd}|S )Nr   )wrapsc                 s&   | d }| |}|r"|d S |S )Nnocondsr   )rE   )r$   kwargsr]   rP   )defaultr>   r   r   wrapper   s
    
z0_noconds_.<locals>.make_wrapper.<locals>.wrapper)Zsympy.core.decoratorsr\   )r>   r\   r`   )r_   )r>   r   make_wrapper   s    z_noconds_.<locals>.make_wrapperr   )r_   ra   r   )r_   r   	_noconds_   s    rb   Fc             C   s   t | |dtfS )Nr   )r
   r   )r,   r-   r   r   r   _default_integrator   s    rc   Tc                s  ddl mm mm tdd| ||d  |  |}|tsdt|	||t
 t
ftjfS |jsvtd| d|jd \}}|trtd| d fd	d
fddt|D }dd |D }|jfddd |std| d|d \}}	}
t|	||||	f|
fS )z0 Backend function to compute Mellin transforms. r   )reMaxMin	count_opsr.   zmellin-transformr%   Mellinzcould not compute integralzintegral in unexpected formc                sJ  t  }t }tj}tt| }tddd}x|D ]
}t }t  }g }	xt|D ]}
|
dd |}|
j	r|
j
dks|s||s|	|
g7 }	qNt||}|j	r|j
dkr|	|
g7 }	qN|j|kr܈ |j|}qN|j|}qNW |t kr||kr ||}q0|t  kr.||kr.||}q0t|t|	 }q0W |||fS )zN
        Turn ``cond`` into a strip (a, b), and auxiliary conditions.
        tT)realc             S   s   |   d S )Nr   )as_real_imag)r-   r   r   r   <lambda>   s    z:_mellin_transform.<locals>.process_conds.<locals>.<lambda>)z==z!=)r   r   truer   r   r	   r   replacesubsis_Relationalrel_opr<   rW   ltsgtsr   r   )r5   abauxcondsri   ca_b_aux_dd_soln)re   rf   rd   r.   r   r   process_conds   s>    





z(_mellin_transform.<locals>.process_condsc                s   g | ]} |qS r   r   )r=   rx   )r   r   r   rB     s    z%_mellin_transform.<locals>.<listcomp>c             S   s   g | ]}|d  dkr|qS )r'   Fr   )r=   r-   r   r   r   rB     s    c                s   | d | d   | d fS )Nr   r%   r'   r   )r-   )rg   r   r   rl     s    z#_mellin_transform.<locals>.<lambda>)keyzno convergence found)rC   rd   re   rf   rg   r   r<   r   r[   ro   r   r   rm   is_Piecewiser   r$   r   sort)r,   r-   s_Z
integratorr   Fr5   rw   rt   ru   rv   r   )re   rf   rg   r   rd   r.   r   _mellin_transform   s&    
 

&r   c               @   s,   e Zd ZdZdZdd Zdd Zdd Zd	S )
MellinTransformz
    Class representing unevaluated Mellin transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute Mellin transforms, see the :func:`mellin_transform`
    docstring.
    rh   c             K   s   t |||f|S )N)r   )r   r,   r-   r.   r/   r   r   r   r0   %  s    z"MellinTransform._compute_transformc             C   s   t |||d   |dtfS )Nr%   r   )r   r   )r   r,   r-   r.   r   r   r   r1   (  s    zMellinTransform._as_integralc             C   s   ddl m}m} g }g }g }x2|D ]*\\}}}	||g7 }||g7 }||	g7 }q"W || || ft| f}
|
d d |
d d kdks|
d dkrtdd d|
S )Nr   )re   rf   r%   TFrh   zno combined convergence.)rC   re   rf   r   r   )r   r4   re   rf   rt   ru   r5   ZsaZsbrx   rP   r   r   r   r6   +  s    

(
zMellinTransform._collapse_extraN)r   r   r    r!   rM   r0   r1   r6   r   r   r   r   r     s
   r   c             K   s   t | ||jf |S )a	  
    Compute the Mellin transform `F(s)` of `f(x)`,

    .. math :: F(s) = \int_0^\infty x^{s-1} f(x) \mathrm{d}x.

    For all "sensible" functions, this converges absolutely in a strip
      `a < \operatorname{Re}(s) < b`.

    The Mellin transform is related via change of variables to the Fourier
    transform, and also to the (bilateral) Laplace transform.

    This function returns ``(F, (a, b), cond)``
    where ``F`` is the Mellin transform of ``f``, ``(a, b)`` is the fundamental strip
    (as above), and ``cond`` are auxiliary convergence conditions.

    If the integral cannot be computed in closed form, this function returns
    an unevaluated :class:`MellinTransform` object.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`. If ``noconds=False``,
    then only `F` will be returned (i.e. not ``cond``, and also not the strip
    ``(a, b)``).

    >>> from sympy.integrals.transforms import mellin_transform
    >>> from sympy import exp
    >>> from sympy.abc import x, s
    >>> mellin_transform(exp(-x), x, s)
    (gamma(s), (0, oo), True)

    See Also
    ========

    inverse_mellin_transform, laplace_transform, fourier_transform
    hankel_transform, inverse_hankel_transform
    )r   rA   )r,   r-   r.   r/   r   r   r   mellin_transform;  s    $r   c             C   s   ddl m}m}m}m} | \}}	||| }||	| }	|| | |	 d  }
||| |	 |
 |d|	 |
 ||  d|
 | fS )as  
    Re-write the sine function ``sin(m*s + n)`` as gamma functions, compatible
    with the strip (a, b).

    Return ``(gamma1, gamma2, fac)`` so that ``f == fac/(gamma1 * gamma2)``.

    >>> from sympy.integrals.transforms import _rewrite_sin
    >>> from sympy import pi, S
    >>> from sympy.abc import s
    >>> _rewrite_sin((pi, 0), s, 0, 1)
    (gamma(s), gamma(-s + 1), pi)
    >>> _rewrite_sin((pi, 0), s, 1, 0)
    (gamma(s - 1), gamma(-s + 2), -pi)
    >>> _rewrite_sin((pi, 0), s, -1, 0)
    (gamma(s + 1), gamma(-s), -pi)
    >>> _rewrite_sin((pi, pi/2), s, S(1)/2, S(3)/2)
    (gamma(s - 1/2), gamma(-s + 3/2), -pi)
    >>> _rewrite_sin((pi, pi), s, 0, 1)
    (gamma(s), gamma(-s + 1), -pi)
    >>> _rewrite_sin((2*pi, 0), s, 0, S(1)/2)
    (gamma(2*s), gamma(-2*s + 1), pi)
    >>> _rewrite_sin((2*pi, 0), s, S(1)/2, 1)
    (gamma(2*s - 1), gamma(-2*s + 2), -pi)
    r   )r8   piceilinggammar%   )rC   r8   r   r   r   rk   )Zm_nr.   rt   ru   r8   r   r   r   mnrr   r   r   _rewrite_sinb  s    "r   c               @   s   e Zd ZdZdS )MellinTransformStripErrorzF
    Exception raised by _rewrite_gamma. Mainly for internal use.
    N)r   r   r    r!   r   r   r   r   r     s   r   c       <         s  ddl m} ddlm m}m}m	m}m}m	m
}	m}
m}m}m}m}m}m}m} t||g\	fdd}g }xT|D ]F}|
sq|jd }|jr|
d }|
\}}||g7 }qW x`||||D ]L}|
sq|jd }|jr|
d }|
\}}||| g7 }qW dd |D }tdx|D ]}|jsN|P qNW fd	d|D }td
d |D sjstdddt|
dd |D td }|krt|dkr܈}nt|dd |D  }td}td} 

| || }d| }dk	r6|9 dk	rH|9 ! \}}|"|}|"|}t#t$||dt#t$||d }g }g } g }!g }"g }#fddx
|r|% \r|!|" }$}%||  }&}'n|"|! }$}%| | }&}' 
fdd}(
s|&g7 }&qj&s2t'|rj&rHj(})j}*n|d})jd }*|*j)r}+|*dk rv|+ }+||)|+fgt*|* 7 }qnL|)
s|(|*\}}sd|) })|#|)| g7 }#||)| g7 }nq+
r 
},|,, dkr^|,- d }|	|,
}-t|-|,, kr8|.|,}-|&|g7 }&|
fdd|-D 7 }q|,/ \}}.|&|g7 }&|.|  }.||.r|$td|. d fg7 }$|%td|. fg7 }%n2|&dg7 }&|$td|.d fg7 }$|%td|.fg7 }%qt'|rl|(jd \}}rZ|dkr2|| | dksR|dk rZ|| | dkrZt0d|$||fg7 }$qt'|rjd }r||| |d||  |  }/}0}1nt1|(|
\}/}0}1||/ f|0 fg7 }|&|1g7 }&nt'|r0jd }|||ddf||d | dd fg7 }nt'|rfjd }|||d | ddfg7 }nNt'|rjd }|||d | ddf||dd fg7 }nqW ||| ||   9 }g g g g f\}2}3}4}5xX|!|2|4df|"|5|3dfgD ]:\}6}7}8x(|6r6|6% \}}.|dkr|dkrt*t|},||, }9|.|, }:|j)sbt2dx(t3|,D ]};|6|9|:|;|,  fg7 }6qlW r|d| d|, d  |,|.tdd    9 }|#|,| g7 }#n<|d| d|, d  |,|.tdd     }|#|,|  g7 }#q|dkr(|74d|.  n
|84|. qW qW ||# }|2j5t6d |3j5t6d |4j5t6d |5j5t6d |2|3f|4|5f|||fS )a  
    Try to rewrite the product f(s) as a product of gamma functions,
    so that the inverse Mellin transform of f can be expressed as a meijer
    G function.

    Return (an, ap), (bm, bq), arg, exp, fac such that
    G((an, ap), (bm, bq), arg/z**exp)*fac is the inverse Mellin transform of f(s).

    Raises IntegralTransformError or MellinTransformStripError on failure.

    It is asserted that f has no poles in the fundamental strip designated by
    (a, b). One of a and b is allowed to be None. The fundamental strip is
    important, because it determines the inversion contour.

    This function can handle exponentials, linear factors, trigonometric
    functions.

    This is a helper function for inverse_mellin_transform that will not
    attempt any transformations on f.

    >>> from sympy.integrals.transforms import _rewrite_gamma
    >>> from sympy.abc import s
    >>> from sympy import oo
    >>> _rewrite_gamma(s*(s+3)*(s-1), s, -oo, oo)
    (([], [-3, 0, 1]), ([-2, 1, 2], []), 1, 1, -1)
    >>> _rewrite_gamma((s-1)**2, s, -oo, oo)
    (([], [1, 1]), ([2, 2], []), 1, 1, 1)

    Importance of the fundamental strip:

    >>> _rewrite_gamma(1/s, s, 0, oo)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, None, oo)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, 0, None)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, -oo, 0)
    (([], [1]), ([0], []), 1, 1, -1)
    >>> _rewrite_gamma(1/s, s, None, 0)
    (([], [1]), ([0], []), 1, 1, -1)
    >>> _rewrite_gamma(1/s, s, -oo, None)
    (([], [1]), ([0], []), 1, 1, -1)

    >>> _rewrite_gamma(2**(-s+3), s, -oo, oo)
    (([], []), ([], []), 1/2, 1, 8)
    r   )repeat)Polyr   r9   rd   CRootOfexpexpandrootsilcmr   sincostancotigcd	exp_polarc                s   | }  dkr t kr dS  dkr0| k S dkr@|  kS | kdkrPdS |  kdkr`dS |rhdS  jszjsz| jr~dS tddS )zU
        Decide whether pole at c lies to the left of the fundamental strip.
        NTFzPole inside critical strip?)r   r)   r   )rx   is_numer)ry   rz   r   rd   r   r   left  s     z_rewrite_gamma.<locals>.leftr%   c             S   s   g | ]}|j rt|n|qS r   )is_realabs)r=   r-   r   r   r   rB     s    z"_rewrite_gamma.<locals>.<listcomp>c                s   g | ]}|  qS r   r   )r=   r-   )common_coefficientr   r   rB     s    c             s   s   | ]}|j  V  qd S )N)is_Rational)r=   r-   r   r   r   r?     s    z!_rewrite_gamma.<locals>.<genexpr>ZGammaNzNonrational multiplierc             S   s   g | ]}t |jqS r   )r   q)r=   r-   r   r   r   rB     s   c             S   s   g | ]}t |jqS r   )r   p)r=   r-   r   r   r   rB     s    TFc                s   t d d|  S )NzInverse MellinzUnrecognised form '%s'.)r   )fact)r,   r   r   	exception(  s    z!_rewrite_gamma.<locals>.exceptionc                s8   |  s | }| dkr0| S )z7 Test if arg is of form a*s+b, raise exception if not. r%   )is_polynomialdegree
all_coeffs)argr   )r   r   r   r.   r   r   
linear_arg3  s    

z"_rewrite_gamma.<locals>.linear_argc                s   g | ]}|  fqS r   r   )r=   rx   )r   r.   r   r   rB   a  s    r   z Gammas partially over the strip.)Zevaluater'   za is not an integer)r   )7	itertoolsr   rC   r   r   r9   rd   r   r   r   r   r   r   r   r   r   r   r   r   r   rG   r<   r$   rH   Zas_independentrN   r   rF   r   r   r   rL   ro   Zas_numer_denomZ	make_argsr@   ziprE   is_PowrI   baseZ
is_Integerr   r   r   ZLTZ	all_rootsr   r+   r   	TypeErrorr   rK   r   r   )<r,   r.   rt   ru   r   r   r9   r   Zexp_r   r   r   r   r   r   r   r   r   r   Zs_multipliersgr   rR   _r-   Zs_multiplierexponentfacZnumerZdenomr$   ZfacsZdfacsZnumer_gammasZdenom_gammasZexponentialsZugammasZlgammasZufacsZlfacsr   r   r   r5   r   Zrsrx   Zgamma1Zgamma2Zfac_ZanapZbmbqZgammasZplusZminusZnewaZnewckr   )r   ry   rz   r   r   r   r,   r   r   rd   r.   r   _rewrite_gamma  sB   /H









$













  
&
 
 

,,
r   c                sv  ddl m}m}m}m}m}	m}
m}m}m	}m
}m} tdd| dd| |} x|| || || gD ]}|jr܇ fdd|jD }d	d |D }d
d |D }|| } s||||d}||t| fS y$t|d d \}}}}}W n tk
r   whY nX |||||  } r:|}ny||}W n0 tk
rv } ztd| dW dd}~X Y nX |jrt|jdkr|t| |jd jd  |t| |jd jd   }t|	|j|j|
 k g}|ttt|jt|jkd||jd kt|	|j|j|
 kg7 }t| }|dkrPtd| d|| ||fS W td| ddS )zs A helper for the real inverse_mellin_transform function, this one here
        assumes x to be real and positive. r   )r   r8   hyperexpandmeijergr   r   rd   factor	Heavisider   r7   ri   zinverse-mellin-transformT)Zpositivec          
      s    g | ]}t | d dqS )F)r]   )_inverse_mellin_transform)r=   G)
as_meijergr.   stripr-   r   r   rB     s   z-_inverse_mellin_transform.<locals>.<listcomp>c             S   s   g | ]}|d  qS )r%   r   )r=   r   r   r   r   rB     s    c             S   s   g | ]}|d  qS )r   r   )r=   r   r   r   r   rB     s    )Zgensr%   zInverse MellinzCould not calculate integralN   Fzdoes not converger2   )rC   r   r8   r   r   r   r   rd   r   r   r   r7   r   ZrewriterH   r$   rG   ro   r   r   r   r+   r   rL   r   argumentZdeltar   r   r   nu)r   r.   Zx_r   r   r   r8   r   r   r   r   rd   r   r   r   r7   r   rQ   rw   rP   rt   ru   Cer   r   hZdetailr5   r   )r   r.   r   r-   r   r     sJ    4
 
$"*

r   Nc               @   sH   e Zd ZdZdZedZedZdd Ze	dd Z
d	d
 Zdd ZdS )InverseMellinTransformz
    Class representing unevaluated inverse Mellin transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute inverse Mellin transforms, see the
    :func:`inverse_mellin_transform` docstring.
    zInverse MellinNonerx   c             K   s4   |d krt j}|d krt j}tj| |||||f|S )N)r   _none_sentinelr#   __new__)clsr   r.   r-   rt   ru   optsr   r   r   r     s
    zInverseMellinTransform.__new__c             C   s:   | j d | j d  }}|tjkr$d }|tjkr2d }||fS )Nr      )r$   r   r   )r   rt   ru   r   r   r   fundamental_strip  s    

z(InverseMellinTransform.fundamental_stripc             K   s   ddl m} td krlddl m}m}m}m}	m}
m}m	}m
}m}m}m}m} t||||	|
|||||||gax:||D ].}|jrv||rv|jtkrvtd|d| qvW | j}t||||f|S )Nr   )postorder_traversal)r   r   r   r   r   r   coshsinhtanhcoth	factorialrfzInverse MellinzComponent %s not recognised.)rC   r   _allowedr   r   r   r   r   r   r   r   r   r   r   r   setZis_Functionr<   r>   r   r   r   )r   r   r.   r-   r/   r   r   r   r   r   r   r   r   r   r   r   r   r   r,   r   r   r   r   r0     s    8
z)InverseMellinTransform._compute_transformc             C   sN   ddl m} | jj}t|||   |||t  ||t  fdtj tj  S )Nr   )Ir'   )	rC   r   r   _cr   r   r   PiImaginaryUnit)r   r   r.   r-   r   rx   r   r   r   r1   )  s    z#InverseMellinTransform._as_integralN)r   r   r    r!   rM   r	   r   r   r   rV   r   r0   r1   r   r   r   r   r     s   	r   c             K   s    t | |||d |d jf |S )a  
    Compute the inverse Mellin transform of `F(s)` over the fundamental
    strip given by ``strip=(a, b)``.

    This can be defined as

    .. math:: f(x) = \frac{1}{2\pi i} \int_{c - i\infty}^{c + i\infty} x^{-s} F(s) \mathrm{d}s,

    for any `c` in the fundamental strip. Under certain regularity
    conditions on `F` and/or `f`,
    this recovers `f` from its Mellin transform `F`
    (and vice versa), for positive real `x`.

    One of `a` or `b` may be passed as ``None``; a suitable `c` will be
    inferred.

    If the integral cannot be computed in closed form, this function returns
    an unevaluated :class:`InverseMellinTransform` object.

    Note that this function will assume x to be positive and real, regardless
    of the sympy assumptions!

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.

    >>> from sympy.integrals.transforms import inverse_mellin_transform
    >>> from sympy import oo, gamma
    >>> from sympy.abc import x, s
    >>> inverse_mellin_transform(gamma(s), s, x, (0, oo))
    exp(-x)

    The fundamental strip matters:

    >>> f = 1/(s**2 - 1)
    >>> inverse_mellin_transform(f, s, x, (-oo, -1))
    (x/2 - 1/(2*x))*Heaviside(x - 1)
    >>> inverse_mellin_transform(f, s, x, (-1, 1))
    -x*Heaviside(-x + 1)/2 - Heaviside(x - 1)/(2*x)
    >>> inverse_mellin_transform(f, s, x, (1, oo))
    (-x/2 + 1/(2*x))*Heaviside(-x + 1)

    See Also
    ========

    mellin_transform
    hankel_transform, inverse_hankel_transform
    r   r%   )r   rA   )r   r.   r-   r   r/   r   r   r   inverse_mellin_transform/  s    0r   c                s   ddl m}m}m ddlm  fdd fdd fdd	fd
d}dd }|| |} || |fdd} || |} t| S )a  
    Naively simplify some conditions occurring in ``expr``, given that `\operatorname{Re}(s) > a`.

    >>> from sympy.integrals.transforms import _simplifyconds as simp
    >>> from sympy.abc import x
    >>> from sympy import sympify as S
    >>> simp(abs(x**2) < 1, x, 1)
    False
    >>> simp(abs(x**2) < 1, x, 2)
    False
    >>> simp(abs(x**2) < 1, x, 0)
    Abs(x**2) < 1
    >>> simp(abs(1/x**2) < 1, x, 1)
    True
    >>> simp(S(1) < abs(x), x, 1)
    True
    >>> simp(S(1) < abs(1/x), x, 1)
    False

    >>> from sympy import Ne
    >>> simp(Ne(1, x**3), x, 1)
    True
    >>> simp(Ne(1, x**3), x, 2)
    True
    >>> simp(Ne(1, x**3), x, 0)
    Ne(1, x**3)
    r   )StrictGreaterThanStrictLessThan
Unequality)Absc                s&   |  krdS | j r"| j kr"| jS d S )Nr%   )r   r   r   )ex)r.   r   r   power  s
    z_simplifyconds.<locals>.powerc                s   |  r| rdS t|  r,| jd } t| r@|jd }|  r\d| d|  S |}|dkrpdS yL|dkrt| t| kdkrdS |dk rt| t| kdkrdS W n tk
r   Y nX dS )z_ Return True only if |ex1| > |ex2|, False only if |ex1| < |ex2|.
            Else return None. Nr   r%   TF)r<   rI   r$   r   r   )Zex1Zex2r   )r   rt   biggerr   r.   r   r   r     s$    




  z_simplifyconds.<locals>.biggerc                sH   | j st|  r |j s(t| s(| |k S | |}|dk	r@| S | |k S )z simplify x < y N)is_positiverI   )r-   yr   )r   r   r   r   replie  s    
z_simplifyconds.<locals>.repliec                s(   | |}|dks|dkrdS  | |S )NTFr   )r-   r   ru   )r   r   r   r   replue  s    
z_simplifyconds.<locals>.repluec             W   s"   | dks| dkrt | S | j| S )NTF)boolrn   )r   r$   r   r   r   repl  s    z_simplifyconds.<locals>.replc                s
    || S )Nr   )r-   r   )r   r   r   rl     s    z _simplifyconds.<locals>.<lambda>)Zsympy.core.relationalr   r   r   rC   r   r   )rZ   r.   rt   r   r   r   r   r   )r   r   rt   r   r   r   r.   r   _simplifycondsf  s    
r   c                s  ddl mm m}mmmmmm	m
m	 tdt|   dtf}|tst||t tjfS |jstdd|jd \}}|trtdd 	fdd

fd	d
t|D }dd
 |D }|sdd
 |D }|}dd |jfddd |sDtdd|d \}	}
fdd}|r|t||	}t|
|	}
t||||	||
fS )z. The backend function for Laplace transforms. r   )rd   re   r   r   rf   periodic_argumentr   r   Wildsymbols
polar_liftr.   Laplacezcould not compute integralzintegral in unexpected formc          
      sp  t  }tj}tt| } tddd}dgd\}}}}}}	}
|t| |  |k |t| |  |kt| | | ||k t| | | ||kt	| | | ||k t	| | | ||kf}xr| D ]h}t }g }x4t|D ]&}|jr6|j	j
kr6|j}x |D ]}||  r<P q<W  r | jr |  |  d kr
 |  dk}||t|
  | t| |	  | dk  s|t| |
 || t| |	  | dk  sZ|t	| |
 || t| |	  | dk  rt fdd	||||	|
gD r
 | k}|
d
d 
}|jr|jdks|s|s||g7 }qt|}|jr|jdkr||g7 }q|jkr.tddn|j|}qW |t krV||}qt|t| }qW ||fS )z7 Turn ``conds`` into a strip and auxiliary conditions. uT)rj   zp q w1 w2 w3 w4 w5)r   Zexcluder'   r   c             3   s   | ]} | j V  qd S )N)r   )r=   Zwild)r   r   r   r?     s    z<_laplace_transform.<locals>.process_conds.<locals>.<genexpr>c             S   s   |    d S )Nr   )r   rk   )r-   r   r   r   rl     s    z;_laplace_transform.<locals>.process_conds.<locals>.<lambda>)z==z!=r   zconvergence not in half-plane?)r   r   rm   r   r   r	   r   r   rp   Zrhsr)   reversedmatchr   allrn   ro   rq   r<   rW   rr   r   r   r   )rw   rt   rv   r   r   r   Zw1Zw2Zw3Zw4Zw5Zpatternsrx   ry   r{   r|   Zpatr}   r~   )re   rf   r   r   arg_r   r,   r   r   rd   r.   r   ri   )r   r   r     sn     $

&:8 (



z)_laplace_transform.<locals>.process_condsc                s   g | ]} |qS r   r   )r=   rx   )r   r   r   rB     s    z&_laplace_transform.<locals>.<listcomp>c             S   s*   g | ]"}|d  dkr|d t  kr|qS )r%   Fr   )r   )r=   r-   r   r   r   rB     s    c             S   s   g | ]}|d  dkr|qS )r%   Fr   )r=   r-   r   r   r   rB     s    c             S   s   | dks| dkrdS |   S )NTFr   )rg   )rZ   r   r   r   cnt  s    z_laplace_transform.<locals>.cntc                s   | d   | d fS )Nr   r%   r   )r-   )r   r   r   rl     s    z$_laplace_transform.<locals>.<lambda>)r   zno convergence foundc                s   |   S )N)ro   )rZ   )r.   r   r   r   sbs  s    z_laplace_transform.<locals>.sbs)rC   rd   re   r   r   rf   r   r   r   r   r   r   r	   r
   r   r<   r   r[   ro   r   rm   r   r   r$   r   r   r   )r,   ri   r   r   r   r   r5   rw   Zconds2rt   rv   r   r   )re   rf   r   r   r   r   r   r,   r   r   r   rd   r.   r   r   ri   r   _laplace_transform  s8    4



$=r   c               @   s,   e Zd ZdZdZdd Zdd Zdd Zd	S )
LaplaceTransformz
    Class representing unevaluated Laplace transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute Laplace transforms, see the :func:`laplace_transform`
    docstring.
    r   c             K   s   t |||f|S )N)r   )r   r,   ri   r.   r/   r   r   r   r0   2  s    z#LaplaceTransform._compute_transformc             C   s*   ddl m} t||| |  |dtfS )Nr   )r   )rC   r   r   r   )r   r,   ri   r.   r   r   r   r   r1   5  s    zLaplaceTransform._as_integralc             C   sf   ddl m} g }g }x$|D ]\}}|| || qW t| }|| }|dkr^tdd d||fS )Nr   )re   Fr   zNo combined convergence.)rC   re   rK   r   r   )r   r4   re   rw   Zplanesplaner5   r   r   r   r6   9  s    

z LaplaceTransform._collapse_extraN)r   r   r    r!   rM   r0   r1   r6   r   r   r   r   r   &  s
   r   c                s>   t | tr*t| dr*|  fddS t| jf  S )ab  
    Compute the Laplace Transform `F(s)` of `f(t)`,

    .. math :: F(s) = \int_0^\infty e^{-st} f(t) \mathrm{d}t.

    For all "sensible" functions, this converges absolutely in a
    half plane  `a < \operatorname{Re}(s)`.

    This function returns ``(F, a, cond)``
    where ``F`` is the Laplace transform of ``f``, `\operatorname{Re}(s) > a` is the half-plane
    of convergence, and ``cond`` are auxiliary convergence conditions.

    If the integral cannot be computed in closed form, this function returns
    an unevaluated :class:`LaplaceTransform` object.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`. If ``noconds=True``,
    only `F` will be returned (i.e. not ``cond``, and also not the plane ``a``).

    >>> from sympy.integrals import laplace_transform
    >>> from sympy.abc import t, s, a
    >>> laplace_transform(t**a, t, s)
    (s**(-a)*gamma(a + 1)/s, 0, -re(a) < 1)

    See Also
    ========

    inverse_laplace_transform, mellin_transform, fourier_transform
    hankel_transform, inverse_hankel_transform
    	applyfuncc                s   t | f S )N)laplace_transform)Zfij)r/   r.   ri   r   r   rl   h  s    z#laplace_transform.<locals>.<lambda>)rI   r   hasattrr   r   rA   )r,   ri   r.   r/   r   )r/   r.   ri   r   r   H  s    r   c                sd  ddl mm mmm}m ddlm}m	 t
ddd fdd}y&t| | d	tfdd
d\}}	W n tk
r   d	}Y nX |d	kr|| |}|d	krtd|d|jr|jd \}}	||rtd|dntj}	||}|jr|||	fS t
d fdd}
| |
}fdd}||}t||||	fS )z6 The backend function for inverse Laplace transforms. r   )r   r   logexpand_complexr   	Piecewise)meijerint_inversion_get_coeff_expri   T)rj   c                 s   t | dkr|  S | d jd j}|\}}| d jd }| d jd } dt| |  |  | dt|  |  S )z3 Simplify a piecewise expression from hyperexpand. r   r'   r   r%   )rL   r$   r   r   )r$   r   rR   r   Ze1Ze2)r   r   r  ri   r   r   pw_simpw  s    z+_inverse_laplace_transform.<locals>.pw_simpNF)r;   r]   zInverse Laplacer2   z(inversion integral of unrecognised form.r   c                sn   |   }|r$ | S t|dk}|jkrR|j} | S |j} |  S d S )Nr   )ro   r<   rW   rr   rs   )r   rt   Zrelr   )r   r   r   ri   r   r   r   simp_heaviside  s    



z2_inverse_laplace_transform.<locals>.simp_heavisidec                s    | S )Nr   )r   )r   r   r   r   simp_exp  s    z,_inverse_laplace_transform.<locals>.simp_exp)rC   r   r   r   r   r   r   sympy.integrals.meijerintr  r  r	   r   r   r   r   r$   r<   r   rm   rn   ro   r[   )r   r.   Zt_r   r   r   r  r  r,   r5   r  r  r   )r   r   r  r   r   r   ri   r   r   _inverse_laplace_transforml  s8     

r  c               @   sH   e Zd ZdZdZedZedZdd Ze	dd Z
d	d
 Zdd ZdS )InverseLaplaceTransformz
    Class representing unevaluated inverse Laplace transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute inverse Laplace transforms, see the
    :func:`inverse_laplace_transform` docstring.
    zInverse Laplacer   rx   c             K   s$   |d krt j}tj| ||||f|S )N)r  r   r#   r   )r   r   r.   r-   r   r   r   r   r   r     s    zInverseLaplaceTransform.__new__c             C   s   | j d }|tjkrd }|S )Nr   )r$   r  r   )r   r   r   r   r   fundamental_plane  s    

z)InverseLaplaceTransform.fundamental_planec             K   s   t |||| jf|S )N)r  r	  )r   r   r.   ri   r/   r   r   r   r0     s    z*InverseLaplaceTransform._compute_transformc             C   sT   ddl m}m} | jj}t||| | |||t  ||t  fdtj tj	  S )Nr   )r   r   r'   )
rC   r   r   r   r   r   r   r   r   r   )r   r   r.   ri   r   r   rx   r   r   r   r1     s    z$InverseLaplaceTransform._as_integralN)r   r   r    r!   rM   r	   r   r   r   rV   r	  r0   r1   r   r   r   r   r    s   r  c                sB   t | tr,t| dr,|  fddS t| jf  S )a  
    Compute the inverse Laplace transform of `F(s)`, defined as

    .. math :: f(t) = \frac{1}{2\pi i} \int_{c-i\infty}^{c+i\infty} e^{st} F(s) \mathrm{d}s,

    for `c` so large that `F(s)` has no singularites in the
    half-plane `\operatorname{Re}(s) > c-\epsilon`.

    The plane can be specified by
    argument ``plane``, but will be inferred if passed as None.

    Under certain regularity conditions, this recovers `f(t)` from its
    Laplace Transform `F(s)`, for non-negative `t`, and vice
    versa.

    If the integral cannot be computed in closed form, this function returns
    an unevaluated :class:`InverseLaplaceTransform` object.

    Note that this function will always assume `t` to be real,
    regardless of the sympy assumption on `t`.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.

    >>> from sympy.integrals.transforms import inverse_laplace_transform
    >>> from sympy import exp, Symbol
    >>> from sympy.abc import s, t
    >>> a = Symbol('a', positive=True)
    >>> inverse_laplace_transform(exp(-a*s)/s, s, t)
    Heaviside(-a + t)

    See Also
    ========

    laplace_transform
    hankel_transform, inverse_hankel_transform
    r   c                s   t | f S )N)inverse_laplace_transform)ZFij)r/   r   r.   ri   r   r   rl     s    z+inverse_laplace_transform.<locals>.<lambda>)rI   r   r   r   r  rA   )r   r.   ri   r   r/   r   )r/   r   r.   ri   r   r
    s    &r
  c             C   s   ddl m}m} t||  ||| | |  |t tf}	|	tsTt|	|tj	fS t| |t tf}
|
t ttj
fks|
trt|| d|	jst|| d|	jd \}	}|	trt|| dt|	||fS )z
    Compute a general Fourier-type transform
        F(k) = a int_-oo^oo exp(b*I*x*k) f(x) dx.

    For suitable choice of a and b, this reduces to the standard Fourier
    and inverse Fourier transforms.
    r   )r   r   z$function not integrable on real axiszcould not compute integralzintegral in unexpected form)rC   r   r   r
   r   r<   r   r[   r   rm   ZNaNr   r   r$   )r,   r-   r   rt   ru   r3   r   r   r   r   Z
integral_fr5   r   r   r   _fourier_transform  s    	*

r  c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )FourierTypeTransformz# Base class for Fourier transforms.c             C   s   t d| j d S )Nz,Class %s must implement a(self) but does not)r+   r   )r   r   r   r   rt   %  s    zFourierTypeTransform.ac             C   s   t d| j d S )Nz,Class %s must implement b(self) but does not)r+   r   )r   r   r   r   ru   )  s    zFourierTypeTransform.bc             K   s"   t ||||  |  | jjf|S )N)r  rt   ru   r   rM   )r   r,   r-   r   r/   r   r   r   r0   -  s    z'FourierTypeTransform._compute_transformc             C   sJ   ddl m}m} |  }|  }t|| ||| | |  |t tfS )Nr   )r   r   )rC   r   r   rt   ru   r   r   )r   r,   r-   r   r   r   rt   ru   r   r   r   r1   2  s    z!FourierTypeTransform._as_integralN)r   r   r    r!   rt   ru   r0   r1   r   r   r   r   r  "  s
   r  c               @   s$   e Zd ZdZdZdd Zdd ZdS )FourierTransformz
    Class representing unevaluated Fourier transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute Fourier transforms, see the :func:`fourier_transform`
    docstring.
    ZFourierc             C   s   dS )Nr%   r   )r   r   r   r   rt   E  s    zFourierTransform.ac             C   s
   dt j S )N)r   r   )r   r   r   r   ru   H  s    zFourierTransform.bN)r   r   r    r!   rM   rt   ru   r   r   r   r   r  9  s   r  c             K   s   t | ||jf |S )aT  
    Compute the unitary, ordinary-frequency Fourier transform of `f`, defined
    as

    .. math:: F(k) = \int_{-\infty}^\infty f(x) e^{-2\pi i x k} \mathrm{d} x.

    If the transform cannot be computed in closed form, this
    function returns an unevaluated :class:`FourierTransform` object.

    For other Fourier transform conventions, see the function
    :func:`sympy.integrals.transforms._fourier_transform`.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.
    Note that for this transform, by default ``noconds=True``.

    >>> from sympy import fourier_transform, exp
    >>> from sympy.abc import x, k
    >>> fourier_transform(exp(-x**2), x, k)
    sqrt(pi)*exp(-pi**2*k**2)
    >>> fourier_transform(exp(-x**2), x, k, noconds=False)
    (sqrt(pi)*exp(-pi**2*k**2), True)

    See Also
    ========

    inverse_fourier_transform
    sine_transform, inverse_sine_transform
    cosine_transform, inverse_cosine_transform
    hankel_transform, inverse_hankel_transform
    mellin_transform, laplace_transform
    )r  rA   )r,   r-   r   r/   r   r   r   fourier_transformL  s    !r  c               @   s$   e Zd ZdZdZdd Zdd ZdS )InverseFourierTransformz
    Class representing unevaluated inverse Fourier transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute inverse Fourier transforms, see the
    :func:`inverse_fourier_transform` docstring.
    zInverse Fourierc             C   s   dS )Nr%   r   )r   r   r   r   rt   |  s    zInverseFourierTransform.ac             C   s
   dt j S )Nr'   )r   r   )r   r   r   r   ru     s    zInverseFourierTransform.bN)r   r   r    r!   rM   rt   ru   r   r   r   r   r  p  s   r  c             K   s   t | ||jf |S )az  
    Compute the unitary, ordinary-frequency inverse Fourier transform of `F`,
    defined as

    .. math:: f(x) = \int_{-\infty}^\infty F(k) e^{2\pi i x k} \mathrm{d} k.

    If the transform cannot be computed in closed form, this
    function returns an unevaluated :class:`InverseFourierTransform` object.

    For other Fourier transform conventions, see the function
    :func:`sympy.integrals.transforms._fourier_transform`.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.
    Note that for this transform, by default ``noconds=True``.

    >>> from sympy import inverse_fourier_transform, exp, sqrt, pi
    >>> from sympy.abc import x, k
    >>> inverse_fourier_transform(sqrt(pi)*exp(-(pi*k)**2), k, x)
    exp(-x**2)
    >>> inverse_fourier_transform(sqrt(pi)*exp(-(pi*k)**2), k, x, noconds=False)
    (exp(-x**2), True)

    See Also
    ========

    fourier_transform
    sine_transform, inverse_sine_transform
    cosine_transform, inverse_cosine_transform
    hankel_transform, inverse_hankel_transform
    mellin_transform, laplace_transform
    )r  rA   )r   r   r-   r/   r   r   r   inverse_fourier_transform  s    !r  )r   r   sqrtr   c       
      C   s   t ||  ||| |  |dtf}|ts>t||tjfS |jsPt|| d|j	d \}}	|trtt|| dt|||	fS )a  
    Compute a general sine or cosine-type transform
        F(k) = a int_0^oo b*sin(x*k) f(x) dx.
        F(k) = a int_0^oo b*cos(x*k) f(x) dx.

    For suitable choice of a and b, this reduces to the standard sine/cosine
    and inverse sine/cosine transforms.
    r   zcould not compute integralzintegral in unexpected form)
r
   r   r<   r   r[   r   rm   r   r   r$   )
r,   r-   r   rt   ru   Kr3   r   r   r5   r   r   r   _sine_cosine_transform  s    
$

r  c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )SineCosineTypeTransformzK
    Base class for sine and cosine transforms.
    Specify cls._kern.
    c             C   s   t d| j d S )Nz,Class %s must implement a(self) but does not)r+   r   )r   r   r   r   rt     s    zSineCosineTypeTransform.ac             C   s   t d| j d S )Nz,Class %s must implement b(self) but does not)r+   r   )r   r   r   r   ru     s    zSineCosineTypeTransform.bc             K   s(   t ||||  |  | jj| jjf|S )N)r  rt   ru   r   _kernrM   )r   r,   r-   r   r/   r   r   r   r0     s    z*SineCosineTypeTransform._compute_transformc             C   s<   |   }|  }| jj}t|| ||| |  |dtfS )Nr   )rt   ru   r   r  r   r   )r   r,   r-   r   rt   ru   r  r   r   r   r1     s    z$SineCosineTypeTransform._as_integralN)r   r   r    r!   rt   ru   r0   r1   r   r   r   r   r    s
   r  c               @   s(   e Zd ZdZdZeZdd Zdd ZdS )SineTransformz
    Class representing unevaluated sine transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute sine transforms, see the :func:`sine_transform`
    docstring.
    ZSinec             C   s   t dt t S )Nr'   )r  r   )r   r   r   r   rt     s    zSineTransform.ac             C   s   dS )Nr%   r   )r   r   r   r   ru     s    zSineTransform.bN)	r   r   r    r!   rM   r   r  rt   ru   r   r   r   r   r    s
   r  c             K   s   t | ||jf |S )a  
    Compute the unitary, ordinary-frequency sine transform of `f`, defined
    as

    .. math:: F(k) = \sqrt{\frac{2}{\pi}} \int_{0}^\infty f(x) \sin(2\pi x k) \mathrm{d} x.

    If the transform cannot be computed in closed form, this
    function returns an unevaluated :class:`SineTransform` object.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.
    Note that for this transform, by default ``noconds=True``.

    >>> from sympy import sine_transform, exp
    >>> from sympy.abc import x, k, a
    >>> sine_transform(x*exp(-a*x**2), x, k)
    sqrt(2)*k*exp(-k**2/(4*a))/(4*a**(3/2))
    >>> sine_transform(x**(-a), x, k)
    2**(-a + 1/2)*k**(a - 1)*gamma(-a/2 + 1)/gamma(a/2 + 1/2)

    See Also
    ========

    fourier_transform, inverse_fourier_transform
    inverse_sine_transform
    cosine_transform, inverse_cosine_transform
    hankel_transform, inverse_hankel_transform
    mellin_transform, laplace_transform
    )r  rA   )r,   r-   r   r/   r   r   r   sine_transform  s    r  c               @   s(   e Zd ZdZdZeZdd Zdd ZdS )InverseSineTransformz
    Class representing unevaluated inverse sine transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute inverse sine transforms, see the
    :func:`inverse_sine_transform` docstring.
    zInverse Sinec             C   s   t dt t S )Nr'   )r  r   )r   r   r   r   rt   %  s    zInverseSineTransform.ac             C   s   dS )Nr%   r   )r   r   r   r   ru   (  s    zInverseSineTransform.bN)	r   r   r    r!   rM   r   r  rt   ru   r   r   r   r   r    s
   r  c             K   s   t | ||jf |S )a5  
    Compute the unitary, ordinary-frequency inverse sine transform of `F`,
    defined as

    .. math:: f(x) = \sqrt{\frac{2}{\pi}} \int_{0}^\infty F(k) \sin(2\pi x k) \mathrm{d} k.

    If the transform cannot be computed in closed form, this
    function returns an unevaluated :class:`InverseSineTransform` object.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.
    Note that for this transform, by default ``noconds=True``.

    >>> from sympy import inverse_sine_transform, exp, sqrt, gamma, pi
    >>> from sympy.abc import x, k, a
    >>> inverse_sine_transform(2**((1-2*a)/2)*k**(a - 1)*
    ...     gamma(-a/2 + 1)/gamma((a+1)/2), k, x)
    x**(-a)
    >>> inverse_sine_transform(sqrt(2)*k*exp(-k**2/(4*a))/(4*sqrt(a)**3), k, x)
    x*exp(-a*x**2)

    See Also
    ========

    fourier_transform, inverse_fourier_transform
    sine_transform
    cosine_transform, inverse_cosine_transform
    hankel_transform, inverse_hankel_transform
    mellin_transform, laplace_transform
    )r  rA   )r   r   r-   r/   r   r   r   inverse_sine_transform,  s    r  c               @   s(   e Zd ZdZdZeZdd Zdd ZdS )CosineTransformz
    Class representing unevaluated cosine transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute cosine transforms, see the :func:`cosine_transform`
    docstring.
    ZCosinec             C   s   t dt t S )Nr'   )r  r   )r   r   r   r   rt   [  s    zCosineTransform.ac             C   s   dS )Nr%   r   )r   r   r   r   ru   ^  s    zCosineTransform.bN)	r   r   r    r!   rM   r   r  rt   ru   r   r   r   r   r  N  s
   r  c             K   s   t | ||jf |S )a  
    Compute the unitary, ordinary-frequency cosine transform of `f`, defined
    as

    .. math:: F(k) = \sqrt{\frac{2}{\pi}} \int_{0}^\infty f(x) \cos(2\pi x k) \mathrm{d} x.

    If the transform cannot be computed in closed form, this
    function returns an unevaluated :class:`CosineTransform` object.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.
    Note that for this transform, by default ``noconds=True``.

    >>> from sympy import cosine_transform, exp, sqrt, cos
    >>> from sympy.abc import x, k, a
    >>> cosine_transform(exp(-a*x), x, k)
    sqrt(2)*a/(sqrt(pi)*(a**2 + k**2))
    >>> cosine_transform(exp(-a*sqrt(x))*cos(a*sqrt(x)), x, k)
    a*exp(-a**2/(2*k))/(2*k**(3/2))

    See Also
    ========

    fourier_transform, inverse_fourier_transform,
    sine_transform, inverse_sine_transform
    inverse_cosine_transform
    hankel_transform, inverse_hankel_transform
    mellin_transform, laplace_transform
    )r  rA   )r,   r-   r   r/   r   r   r   cosine_transformb  s    r  c               @   s(   e Zd ZdZdZeZdd Zdd ZdS )InverseCosineTransformz
    Class representing unevaluated inverse cosine transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute inverse cosine transforms, see the
    :func:`inverse_cosine_transform` docstring.
    zInverse Cosinec             C   s   t dt t S )Nr'   )r  r   )r   r   r   r   rt     s    zInverseCosineTransform.ac             C   s   dS )Nr%   r   )r   r   r   r   ru     s    zInverseCosineTransform.bN)	r   r   r    r!   rM   r   r  rt   ru   r   r   r   r   r    s
   r  c             K   s   t | ||jf |S )a  
    Compute the unitary, ordinary-frequency inverse cosine transform of `F`,
    defined as

    .. math:: f(x) = \sqrt{\frac{2}{\pi}} \int_{0}^\infty F(k) \cos(2\pi x k) \mathrm{d} k.

    If the transform cannot be computed in closed form, this
    function returns an unevaluated :class:`InverseCosineTransform` object.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.
    Note that for this transform, by default ``noconds=True``.

    >>> from sympy import inverse_cosine_transform, exp, sqrt, pi
    >>> from sympy.abc import x, k, a
    >>> inverse_cosine_transform(sqrt(2)*a/(sqrt(pi)*(a**2 + k**2)), k, x)
    exp(-a*x)
    >>> inverse_cosine_transform(1/sqrt(k), k, x)
    1/sqrt(x)

    See Also
    ========

    fourier_transform, inverse_fourier_transform,
    sine_transform, inverse_sine_transform
    cosine_transform
    hankel_transform, inverse_hankel_transform
    mellin_transform, laplace_transform
    )r  rA   )r   r   r-   r/   r   r   r   inverse_cosine_transform  s    r  c       	      C   s   ddl m} t| ||||  | |dtf}|tsHt||tjfS |j	sZt
|| d|jd \}}|tr~t
|| dt|||fS )zv
    Compute a general Hankel transform

    .. math:: F_\nu(k) = \int_{0}^\infty f(r) J_\nu(k r) r \mathrm{d} r.
    r   )besseljzcould not compute integralzintegral in unexpected form)rC   r  r
   r   r<   r   r[   r   rm   r   r   r$   )	r,   r   r   r   r3   r   r  r   r5   r   r   r   _hankel_transform  s    "

r   c               @   s4   e Zd ZdZdd Zdd Zdd Zedd	 Zd
S )HankelTypeTransformz+
    Base class for Hankel transforms.
    c             K   s    | j | j| j| j| jd f|S )Nr   )r0   r   r&   r(   r$   )r   r/   r   r   r   rA     s
    
zHankelTypeTransform.doitc             K   s   t ||||| jf|S )N)r   rM   )r   r,   r   r   r   r/   r   r   r   r0     s    z&HankelTypeTransform._compute_transformc             C   s.   ddl m} t|||||  | |dtfS )Nr   )r  )rC   r  r   r   )r   r,   r   r   r   r  r   r   r   r1     s    z HankelTypeTransform._as_integralc             C   s   |  | j| j| j| jd S )Nr   )r1   r   r&   r(   r$   )r   r   r   r   rT     s    zHankelTypeTransform.as_integralN)	r   r   r    r!   rA   r0   r1   rV   rT   r   r   r   r   r!    s
   r!  c               @   s   e Zd ZdZdZdS )HankelTransformz
    Class representing unevaluated Hankel transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute Hankel transforms, see the :func:`hankel_transform`
    docstring.
    ZHankelN)r   r   r    r!   rM   r   r   r   r   r"    s   r"  c             K   s   t | |||jf |S )a  
    Compute the Hankel transform of `f`, defined as

    .. math:: F_\nu(k) = \int_{0}^\infty f(r) J_\nu(k r) r \mathrm{d} r.

    If the transform cannot be computed in closed form, this
    function returns an unevaluated :class:`HankelTransform` object.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.
    Note that for this transform, by default ``noconds=True``.

    >>> from sympy import hankel_transform, inverse_hankel_transform
    >>> from sympy import gamma, exp, sinh, cosh
    >>> from sympy.abc import r, k, m, nu, a

    >>> ht = hankel_transform(1/r**m, r, k, nu)
    >>> ht
    2*2**(-m)*k**(m - 2)*gamma(-m/2 + nu/2 + 1)/gamma(m/2 + nu/2)

    >>> inverse_hankel_transform(ht, k, r, nu)
    r**(-m)

    >>> ht = hankel_transform(exp(-a*r), r, k, 0)
    >>> ht
    a/(k**3*(a**2/k**2 + 1)**(3/2))

    >>> inverse_hankel_transform(ht, k, r, 0)
    exp(-a*r)

    See Also
    ========

    fourier_transform, inverse_fourier_transform
    sine_transform, inverse_sine_transform
    cosine_transform, inverse_cosine_transform
    inverse_hankel_transform
    mellin_transform, laplace_transform
    )r"  rA   )r,   r   r   r   r/   r   r   r   hankel_transform  s    (r#  c               @   s   e Zd ZdZdZdS )InverseHankelTransformz
    Class representing unevaluated inverse Hankel transforms.

    For usage of this class, see the :class:`IntegralTransform` docstring.

    For how to compute inverse Hankel transforms, see the
    :func:`inverse_hankel_transform` docstring.
    zInverse HankelN)r   r   r    r!   rM   r   r   r   r   r$  &  s   r$  c             K   s   t | |||jf |S )a  
    Compute the inverse Hankel transform of `F` defined as

    .. math:: f(r) = \int_{0}^\infty F_\nu(k) J_\nu(k r) k \mathrm{d} k.

    If the transform cannot be computed in closed form, this
    function returns an unevaluated :class:`InverseHankelTransform` object.

    For a description of possible hints, refer to the docstring of
    :func:`sympy.integrals.transforms.IntegralTransform.doit`.
    Note that for this transform, by default ``noconds=True``.

    >>> from sympy import hankel_transform, inverse_hankel_transform, gamma
    >>> from sympy import gamma, exp, sinh, cosh
    >>> from sympy.abc import r, k, m, nu, a

    >>> ht = hankel_transform(1/r**m, r, k, nu)
    >>> ht
    2*2**(-m)*k**(m - 2)*gamma(-m/2 + nu/2 + 1)/gamma(m/2 + nu/2)

    >>> inverse_hankel_transform(ht, k, r, nu)
    r**(-m)

    >>> ht = hankel_transform(exp(-a*r), r, k, 0)
    >>> ht
    a/(k**3*(a**2/k**2 + 1)**(3/2))

    >>> inverse_hankel_transform(ht, k, r, 0)
    exp(-a*r)

    See Also
    ========

    fourier_transform, inverse_fourier_transform
    sine_transform, inverse_sine_transform
    cosine_transform, inverse_cosine_transform
    hankel_transform
    mellin_transform, laplace_transform
    )r$  rA   )r   r   r   r   r/   r   r   r   inverse_hankel_transform3  s    (r%  )F)T)T)N)T)T)T)Vr!   Z
__future__r   r   Z
sympy.corer   Zsympy.core.compatibilityr   r   rD   r   Zsympy.core.numbersr   Zsympy.core.symbolr	   Zsympy.integralsr
   r   r  r   Zsympy.logic.boolalgr   r   r   r   r   Zsympy.simplifyr   Zsympy.utilitiesr   Zsympy.matrices.matricesr   r+   r   r#   Zsympy.solvers.inequalitiesrW   r[   rb   Z_nocondsrc   r   r   r   r   
ValueErrorr   r   r   r   r   r   r   r   r   r   r  r  r
  r  r  r  r  r  r  rC   r   r   r  r   r  r  r  r  r  r  r  r  r  r  r   r!  r"  r#  r$  r%  r   r   r   r   <module>   s   |D"'+  ,857Wh"$F#
/$(!"!%+