B
    ˜‘[P  ã               @   s¤   d 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„ Z
ejdfd	d
„Zejdfdd„Zejdfdd„Zejdfdd„Zejdfdd„Zejdfdd„ZdS )af  
Singularities
=============

This module implements algorithms for finding singularities for a function
and identifying types of functions.

The differential calculus methods in this module include methods to identify
the following function types in the given ``Interval``:
- Increasing
- Strictly Increasing
- Decreasing
- Strictly Decreasing
- Monotonic

é    )Úsympify)Úsolveset)Úsimplify)ÚSÚSymbolc             C   s>   |   |¡stdƒ‚n&|jr tjntj}ttd|  ƒ||ƒS dS )a&  
    Find singularities of a given function.

    Currently supported functions are:
    - univariate rational (real or complex) functions

    Examples
    ========

    >>> from sympy.calculus.singularities import singularities
    >>> from sympy import Symbol
    >>> x = Symbol('x', real=True)
    >>> y = Symbol('y', real=False)
    >>> singularities(x**2 + x + 1, x)
    EmptySet()
    >>> singularities(1/(x + 1), x)
    {-1}
    >>> singularities(1/(y**2 + 1), y)
    {-I, I}
    >>> singularities(1/(y**3 + 1), y)
    {-1, 1/2 - sqrt(3)*I/2, 1/2 + sqrt(3)*I/2}

    Notes
    =====

    This function does not find nonisolated singularities
    nor does it find branch points of the expression.

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Mathematical_singularity

    zTAlgorithms finding singularities for non-rational functions are not yet implemented.é   N)Zis_rational_functionÚNotImplementedErrorZis_realr   ÚRealsZ	Complexesr   r   )Ú
expressionÚsymbolZdomain© r   ú;lib/python3.7/site-packages/sympy/calculus/singularities.pyÚsingularities   s
    #
r   Nc             C   sh   t | ƒ} | j}|dkr*t|ƒdkr*tdƒ‚|p@|r:| ¡ ntdƒ}|  |¡}t||ƒ|tj	ƒ}| 
|¡S )zë
    Helper function for functions checking function monotonicity.

    It returns a boolean indicating whether the interval in which
    the function's derivative satisfies given predicate is a superset
    of the given interval.
    Nr   zKThe function has not yet been implemented for all multivariate expressions.Úx)r   Úfree_symbolsÚlenr   Úpopr   Údiffr   r   r	   Z	is_subset)r
   Z	predicateÚintervalr   Úfreer   Z
derivativeZpredicate_intervalr   r   r   Úmonotonicity_helperJ   s    
r   c             C   s   t | dd„ ||ƒS )a  
    Return whether the function is increasing in the given interval.

    Examples
    ========

    >>> from sympy import is_increasing
    >>> from sympy.abc import x, y
    >>> from sympy import S, Interval, oo
    >>> is_increasing(x**3 - 3*x**2 + 4*x, S.Reals)
    True
    >>> is_increasing(-x**2, Interval(-oo, 0))
    True
    >>> is_increasing(-x**2, Interval(0, oo))
    False
    >>> is_increasing(4*x**3 - 6*x**2 - 72*x + 30, Interval(-2, 3))
    False
    >>> is_increasing(x**2 + y, Interval(1, 2), x)
    True

    c             S   s   | dkS )Nr   r   )r   r   r   r   Ú<lambda>x   s    zis_increasing.<locals>.<lambda>)r   )r
   r   r   r   r   r   Úis_increasingb   s    r   c             C   s   t | dd„ ||ƒS )a‹  
    Return whether the function is strictly increasing in the given interval.

    Examples
    ========

    >>> from sympy import is_strictly_increasing
    >>> from sympy.abc import x, y
    >>> from sympy import Interval, oo
    >>> is_strictly_increasing(4*x**3 - 6*x**2 - 72*x + 30, Interval.Ropen(-oo, -2))
    True
    >>> is_strictly_increasing(4*x**3 - 6*x**2 - 72*x + 30, Interval.Lopen(3, oo))
    True
    >>> is_strictly_increasing(4*x**3 - 6*x**2 - 72*x + 30, Interval.open(-2, 3))
    False
    >>> is_strictly_increasing(-x**2, Interval(0, oo))
    False
    >>> is_strictly_increasing(-x**2 + y, Interval(-oo, 0), x)
    False

    c             S   s   | dkS )Nr   r   )r   r   r   r   r   ‘   s    z(is_strictly_increasing.<locals>.<lambda>)r   )r
   r   r   r   r   r   Úis_strictly_increasing{   s    r   c             C   s   t | dd„ ||ƒS )a.  
    Return whether the function is decreasing in the given interval.

    Examples
    ========

    >>> from sympy import is_decreasing
    >>> from sympy.abc import x, y
    >>> from sympy import S, Interval, oo
    >>> is_decreasing(1/(x**2 - 3*x), Interval.open(1.5, 3))
    True
    >>> is_decreasing(1/(x**2 - 3*x), Interval.Lopen(3, oo))
    True
    >>> is_decreasing(1/(x**2 - 3*x), Interval.Ropen(-oo, S(3)/2))
    False
    >>> is_decreasing(-x**2, Interval(-oo, 0))
    False
    >>> is_decreasing(-x**2 + y, Interval(-oo, 0), x)
    False

    c             S   s   | dkS )Nr   r   )r   r   r   r   r   ª   s    zis_decreasing.<locals>.<lambda>)r   )r
   r   r   r   r   r   Úis_decreasing”   s    r   c             C   s   t | dd„ ||ƒS )a  
    Return whether the function is strictly decreasing in the given interval.

    Examples
    ========

    >>> from sympy import is_strictly_decreasing
    >>> from sympy.abc import x, y
    >>> from sympy import S, Interval, oo
    >>> is_strictly_decreasing(1/(x**2 - 3*x), Interval.Lopen(3, oo))
    True
    >>> is_strictly_decreasing(1/(x**2 - 3*x), Interval.Ropen(-oo, S(3)/2))
    False
    >>> is_strictly_decreasing(-x**2, Interval(-oo, 0))
    False
    >>> is_strictly_decreasing(-x**2 + y, Interval(-oo, 0), x)
    False

    c             S   s   | dk S )Nr   r   )r   r   r   r   r   Á   s    z(is_strictly_decreasing.<locals>.<lambda>)r   )r
   r   r   r   r   r   Úis_strictly_decreasing­   s    r   c             C   sd   t | ƒ} | j}|dkr*t|ƒdkr*tdƒ‚|p@|r:| ¡ ntdƒ}t|  |¡||ƒ}| |¡t	j
kS )a  
    Return whether the function is monotonic in the given interval.

    Examples
    ========

    >>> from sympy import is_monotonic
    >>> from sympy.abc import x, y
    >>> from sympy import S, Interval, oo
    >>> is_monotonic(1/(x**2 - 3*x), Interval.open(1.5, 3))
    True
    >>> is_monotonic(1/(x**2 - 3*x), Interval.Lopen(3, oo))
    True
    >>> is_monotonic(x**3 - 3*x**2 + 4*x, S.Reals)
    True
    >>> is_monotonic(-x**2, S.Reals)
    False
    >>> is_monotonic(x**2 + y + 1, Interval(1, 2), x)
    True

    Nr   zKis_monotonic has not yet been implemented for all multivariate expressions.r   )r   r   r   r   r   r   r   r   Úintersectionr   ZEmptySet)r
   r   r   r   r   Zturning_pointsr   r   r   Úis_monotonicÄ   s    r   )Ú__doc__Zsympy.core.sympifyr   Zsympy.solvers.solvesetr   Zsympy.simplifyr   Zsympyr   r   r   r	   r   r   r   r   r   r   r   r   r   r   Ú<module>   s   2