o
    8Va,                     @   s   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 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 dddZdd ZG dd deZdS )    )SSymbolAddsympifyExpr	PoleErrorMul)factor_terms)	factorial)gamma)PolynomialErrorfactor)Order)ratsimp)together   )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   5/usr/lib/python3/dist-packages/sympy/series/limits.pylimit   s   3r   c                    s<  ddl m  d}t|tju r-t| |d| |tj|tju r!dnd}t|t	r+dS |S | j
s:| js:| js:| jrg }| jD ]X}t||||}|tjr|jdu rt| trt| }t|tset|}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 fdd|D rg }	g }
tt|D ]}t||  r|	||  q|
| j|  qt|
dkrt|
  }t||||}|t|	  }|tju rzt| }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.
    r   AccumBoundsNr   r   -c                 3   s    | ]}t | V  qd S N)
isinstance).0Zrrr   r   r   	<genexpr>f   s    zheuristics.<locals>.<genexpr>) Zsympy.calculus.utilr   absr   Infinityr   subsZeror"   r   is_MulZis_Addis_PowZis_FunctionargshasZ	is_finiter   r	   r   r   r   
heuristicsNaNappendfuncanyrangelenZsimplifyr   r   )r   r   r   r   ZrvralmZr2Ze2iiZe3Zrat_er   r   r   r-   A   sd   *
.







&r-   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u rd}n|tju rd}||r(td||f t|tr2t|}nt|ts?t	dt
| t|dvrKt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&   NegativeInfinityr,   NotImplementedErrorr"   strr   	TypeErrortype
ValueErrorr   __new__Z_args)clsr   r   r   r   objr   r   r   r@      s0   






zLimit.__new__c                 C   s8   | j d }|j}|| j d j || j d j |S )Nr   r      )r+   free_symbolsdifference_updateupdate)selfr   Zisymsr   r   r   rD      s
   
zLimit.free_symbolsc                 C   s   ddl m}m} | j\}}}}|j|j}}||s)t||| ||}	||	S t|||}
t|||}|tju rP|
tj	tj
fv rPt||d  ||}	||	S |tj
u r]|
tj	u r_tjS d S d S )Nr   )explogr   )sympyrH   rI   r+   baser,   r   r   Oner&   r:   ComplexInfinity)rG   rH   rI   exprr   r   _br   resZex_limZbase_limr   r   r   pow_heuristics   s   

zLimit.pow_heuristicsc           	   
      s@  ddl m m | j\}tju rtd|ddr6|jdi |}jdi |jdi ||kr<S |	sC|S tj
u rKtj
S |	tjtjtjtj
rY| S |jrntt|jg|jdd R  S d}tdkryd}ntd	krd
} fdd|}|rttju r|d
 }n| }z|j|d\}}W n	 ty   Y n1w |dkrtjS |dkr|S tdkst|d@ stj| S td	krtj| S tjS ttju r|jrt|}|d }| }n| }z|j|d\}}W n tttfy@   |jr>|  }|dur>| Y S Y ntw |	tjtjtjrN| S |	s|jr[tjS |dkrb|S |jr|j rtd	ksu|j!r|tj| S tdkrtj| S tjS tdkrtj| S td	krtj| tj"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 rt 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.
        r   )Abssignz.Limits at complex infinity are not implementedr   Tr   Nr   r    c                    s   | j s| S tfdd| j D }|| j kr| j| } t|  }t| }|s)|rft| j d }|jrBtd| j d  }|jrf|dk dkrV|rS| j d  S tjS |dkdkrf|rc| j d S tj	S | S )Nc                 3   s    | ]} |V  qd S r!   r   )r#   arg)	set_signsr   r   r$      s    z0Limit.doit.<locals>.set_signs.<locals>.<genexpr>r   r   T)
r+   tupler0   r"   r   Zis_zeroZis_extended_realr   NegativeOnerL   )rN   ZnewargsZabs_flagZ	sign_flagZsigrS   r   rW   rT   r   r   r   r   rW      s"   



zLimit.doit.<locals>.set_signs)cdirr9   zMThe limit does not exist since left hand limit = %s and right hand limit = %sr   )*rJ   rS   rT   r+   r   rM   r;   getr   r,   r.   r&   r:   Zis_Orderr   r   rN   r<   Zis_meromorphicr%   r'   Zleadtermr?   r(   intr)   r	   r   r*   rR   Zis_positiveZis_negative
is_integerZis_evenrY   rL   Zis_extended_positiveZrewriter
   r   r   r-   )	rG   Zhintsr   r[   ZneweZcoeffexr4   r6   r   rZ   r   r      s   


$


	

z
Limit.doitNr   )	__name__
__module____qualname____doc__r@   propertyrD   rR   r   r   r   r   r   r      s    

r   Nr`   )Z
sympy.corer   r   r   r   r   r   r   Zsympy.core.exprtoolsr	   Z(sympy.functions.combinatorial.factorialsr
   Z'sympy.functions.special.gamma_functionsr   Zsympy.polysr   r   Zsympy.series.orderr   Zsympy.simplify.ratsimpr   Zsympy.simplify.simplifyr   r   r   r-   r   r   r   r   r   <module>   s   $ 
6>