o
    *ήc0                     @   s   d dl mZ d dlmZmZmZ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 d dlmZmZm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dZ dd Z!G dd deZ"dS )    )AccumBounds)SSymbolAddsympifyExpr	PoleErrorMul)factor_terms)Float_illegal)	factorial)Abssignarg)explog)gamma)PolynomialErrorfactor)Order   )gruntz+c                 C   s   t | |||jddS )aQ  Computes the limit of ``e(z)`` at the point ``z0``.

    Parameters
    ==========

    e : expression, the limit of which is to be taken

    z : symbol representing the variable in the limit.
        Other symbols are treated as constants. Multivariate limits
        are not supported.

    z0 : the value toward which ``z`` tends. Can be any expression,
        including ``oo`` and ``-oo``.

    dir : string, optional (default: "+")
        The limit is bi-directional if ``dir="+-"``, from the right
        (z->z0+) if ``dir="+"``, and from the left (z->z0-) if
        ``dir="-"``. For infinite ``z0`` (``oo`` or ``-oo``), the ``dir``
        argument is determined from the direction of the infinity
        (i.e., ``dir="-"`` for ``oo``).

    Examples
    ========

    >>> from sympy import limit, sin, oo
    >>> from sympy.abc import x
    >>> limit(sin(x)/x, x, 0)
    1
    >>> limit(1/x, x, 0) # default dir='+'
    oo
    >>> limit(1/x, x, 0, dir="-")
    -oo
    >>> limit(1/x, x, 0, dir='+-')
    zoo
    >>> limit(1/x, x, oo)
    0

    Notes
    =====

    First we try some heuristics for easy and frequent cases like "x", "1/x",
    "x**2" and similar, so that it's fast. For all other cases, we use the
    Gruntz algorithm (see the gruntz() function).

    See Also
    ========

     limit_seq : returns the limit of a sequence.
    F)deep)Limitdoit)ezz0dir r!   :/tmp/pip-target-vg8gfxp4/lib/python/sympy/series/limits.pylimit   s   3r#   c                 C   s<  d}t |tju r't| |d| |tj|tju rdnd}t|tr%dS |S | js4| j	s4| j
s4| jrg }ddlm} | jD ]X}t||||}|tjr|jdu rt| trt| }	t|	tse||	}	t|	tsnt| }	t|	tr|t|	|||  S  dS  dS t|tr dS |tju r dS || q?|r| j| }|tju r| jrtdd |D rg }
g }t|D ]\}}t|tr|
| q|| j|  qt|dkrt|  }t||||}|t|
  }|tju rzdd	lm} || }W n t y   Y dS w |tju s|| krdS t||||S |S )
a+  Computes the limit of an expression term-wise.
    Parameters are the same as for the ``limit`` function.
    Works with the arguments of expression ``e`` one by one, computing
    the limit of each and then combining the results. This approach
    works only for simple limits, but it is fast.
    Nr   r   -r   )togetherc                 s   s    | ]}t |tV  qd S N)
isinstancer   ).0rrr!   r!   r"   	<genexpr>h   s    zheuristics.<locals>.<genexpr>)ratsimp)!absr   Infinityr#   subsZeror'   r   is_Mulis_Addis_Powis_Functionsympy.simplify.simplifyr%   argshas	is_finiter   r
   r	   r   
heuristicsNaNappendfuncany	enumerater   lensimplifysympy.simplify.ratsimpr+   r   )r   r   r   r    rvrr%   almr2e2iirvale3r+   rat_er!   r!   r"   r8   C   sf   *
0







"
r8   c                   @   s6   e Zd ZdZdddZedd Zdd Zd	d
 ZdS )r   zRepresents an unevaluated limit.

    Examples
    ========

    >>> from sympy import Limit, sin
    >>> from sympy.abc import x
    >>> Limit(sin(x)/x, x, 0)
    Limit(sin(x)/x, x, 0)
    >>> Limit(1/x, x, 0, dir="-")
    Limit(1/x, x, 0, dir='-')

    r   c                 C   s   t |}t |}t |}|tjtjtj fv rd}n|tjtjtj fv r'd}||r4td||f t|tr>t	|}nt|t	sKt
dt| t|dvrWtd| t| }||||f|_|S )Nr$   r   z@Limits approaching a variable point are not supported (%s -> %s)z6direction must be of type basestring or Symbol, not %s)r   r$   +-z1direction must be one of '+', '-' or '+-', not %s)r   r   r-   ImaginaryUnitNegativeInfinityr6   NotImplementedErrorr'   strr   	TypeErrortype
ValueErrorr   __new___args)clsr   r   r   r    objr!   r!   r"   rT      s0   




zLimit.__new__c                 C   s8   | j d }|j}|| j d j || j d j |S )Nr   r      )r5   free_symbolsdifference_updateupdate)selfr   isymsr!   r!   r"   rY      s
   
zLimit.free_symbolsc           
      C   s   | j \}}}}|j|j}}||s!t|t| ||}t|S t|||}t|||}	|	tju rH|tjtj	fv rHt||d  ||}t|S |	tj	u rU|tju rWtj
S d S d S )Nr   )r5   baser   r6   r#   r   r   Oner-   rN   ComplexInfinity)
r\   r   _r   r   b1e1resex_limbase_limr!   r!   r"   pow_heuristics   s   

zLimit.pow_heuristicsc              
      sX  | j \} tju rtd|ddr.|jdi |}jdi |jdi ||kr4S |s;|S tju rCtjS |jt rJ| S |j	r_t
t|jg|j dd R  S d}t dkrjd}nt dkrrd	} fd
d|trddlm} ||}|}|rttju r|d }| }n| }z|j|d\}}W n	 ty   Y n-w |dkrtjS |dkr|S |dkst|d@ stjt| S |d	krtjt| S tjS ttju r|jrt|}|d }| }n| }z|j|d\}}W n) tttfyG   ddlm} ||}|j rE| !|}	|	durE|	 Y S Y nyw t"|t#rV|tjkrV|S |tjtjtjtjre| S |s|j$rrtjS |dkry|S |j%r|j&r|dks|j'rtjt| S |d	krtjt| S tjS |dkrtjt| S |d	krtjt| tj(|  S tjS j)r|*t+t,}d}
z<t dkrt-|d}	t-|d}
|
|	krtd|
|	f nt-| }	|	tju s|
tju rt W |	S  ttfy+   |
dur t.| }	|	du r(|  Y S Y |	S w )aP  Evaluates the limit.

        Parameters
        ==========

        deep : bool, optional (default: True)
            Invoke the ``doit`` method of the expressions involved before
            taking the limit.

        hints : optional keyword arguments
            To be passed to ``doit`` methods; only used if deep is True.
        z.Limits at complex infinity are not implementedr   Tr   Nr   r   r$   c                    s   | j s| S tfdd| j D }|| j kr| j| } t| t}t| t}t| t}|s0|s0|rwt| j d  }|jrItd| j d   }|j	rw|dk dkrb|rZ| j d  S |r_t
jS t
jS |dkdkrw|ro| j d S |rtt
jS t
jS | S )Nc                 3   s    | ]} |V  qd S r&   r!   )r(   r   )	set_signsr!   r"   r*      s    z0Limit.doit.<locals>.set_signs.<locals>.<genexpr>r   r   T)r5   tupler;   r'   r   r   r   r#   is_zerois_extended_realr   NegativeOnePir_   r/   )exprnewargsabs_flagarg_flag	sign_flagsigr    ri   r   r   r!   r"   ri      s4   




zLimit.doit.<locals>.set_signs)	nsimplify)cdir)powsimprL   zMThe limit does not exist since left hand limit = %s and right hand limit = %sr!   )/r5   r   r`   rO   getr   r6   r9   r   is_Orderr   r#   ro   rP   r   r4   rv   is_meromorphicr,   r-   r.   leadtermrS   r/   intr   rN   r0   r
   r   sympy.simplify.powsimprx   r2   rg   r'   r   is_positiveis_negative
is_integeris_evenrm   is_extended_positiverewriter   r   r   r8   )r\   hintsr   rw   rv   newecoeffexrx   rB   rD   r!   ru   r"   r      s   



$


	




	

z
Limit.doitNr   )	__name__
__module____qualname____doc__rT   propertyrY   rg   r   r!   r!   r!   r"   r      s    

r   Nr   )#!sympy.calculus.accumulationboundsr   
sympy.corer   r   r   r   r   r   r	   sympy.core.exprtoolsr
   sympy.core.numbersr   r   (sympy.functions.combinatorial.factorialsr   $sympy.functions.elementary.complexesr   r   r   &sympy.functions.elementary.exponentialr   r   'sympy.functions.special.gamma_functionsr   sympy.polysr   r   sympy.series.orderr   r   r#   r8   r   r!   r!   r!   r"   <module>   s    $
6?