ó
~9­\c           @   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 „  Z
 e j d d „ Z e j d d „ Z e j d d	 „ Z e j d d
 „ Z e j d d „ Z e j d d „ Z d S(   sf  
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

iÿÿÿÿ(   t   sympify(   t   solveset(   t   simplify(   t   St   Symbolc         C   sW   |  j  | ƒ s t d ƒ ‚ n5 | j r0 t j n t j } t t d |  ƒ | | ƒ Sd S(   sª  
    Find singularities of a given function.

    Parameters
    ==========

    expression : Expr
        The target function in which singularities need to be found.
    symbol : Symbol
        The symbol over the values of which the singularity in
        expression in being searched for.

    Returns
    =======

    Set
        A set of values for ``symbol`` for which ``expression`` has a
        singularity. An ``EmptySet`` is returned if ``expression`` has no
        singularities for any given value of ``Symbol``.

    Raises
    ======

    NotImplementedError
        The algorithm to find singularities for irrational functions
        has not been implemented yet.

    Notes
    =====

    This function does not find non-isolated singularities
    nor does it find branch points of the expression.

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

    References
    ==========

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

    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}

    sT   Algorithms finding singularities for non-rational functions are not yet implemented.i   N(   t   is_rational_functiont   NotImplementedErrort   is_realR   t   Realst	   ComplexesR   R   (   t
   expressiont   symbolt   domain(    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   singularities   s
    ;c         C   s    t  |  ƒ }  |  j } | d k rE t | ƒ d k rE t d ƒ ‚ qE n  | pf | r] | j ƒ  n	 t d ƒ } |  j | ƒ } t | | ƒ | t	 j
 ƒ } | j | ƒ S(   sà  
    Helper function for functions checking function monotonicity.

    Parameters
    ==========

    expression : Expr
        The target function which is being checked
    predicate : function
        The property being tested for. The function takes in an integer
        and returns a boolean. The integer input is the derivative and
        the boolean result should be true if the property is being held,
        and false otherwise.
    interval : Set, optional
        The range of values in which we are testing, defaults to all reals.
    symbol : Symbol, optional
        The symbol present in expression which gets varied over the given range.

    It returns a boolean indicating whether the interval in which
    the function's derivative satisfies given predicate is a superset
    of the given interval.

    Returns
    =======

    Boolean
        True if ``predicate`` is true for all the derivatives when ``symbol``
        is varied in ``range``, False otherwise.

    i   sK   The function has not yet been implemented for all multivariate expressions.t   xN(   R    t   free_symbolst   Nonet   lenR   t   popR   t   diffR   R   R   t	   is_subset(   R
   t	   predicatet   intervalR   t   freet   variablet
   derivativet   predicate_interval(    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   monotonicity_helperb   s    	$c         C   s   t  |  d „  | | ƒ S(   s  
    Return whether the function is increasing in the given interval.

    Parameters
    ==========

    expression : Expr
        The target function which is being checked.
    interval : Set, optional
        The range of values in which we are testing (defaults to set of
        all real numbers).
    symbol : Symbol, optional
        The symbol present in expression which gets varied over the given range.

    Returns
    =======

    Boolean
        True if ``expression`` is increasing (either strictly increasing or
        constant) in the given ``interval``, False otherwise.

    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(   Ni    (    (   R   (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   <lambda>¹   t    (   R   (   R
   R   R   (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   is_increasing‘   s    (c         C   s   t  |  d „  | | ƒ S(   st  
    Return whether the function is strictly increasing in the given interval.

    Parameters
    ==========

    expression : Expr
        The target function which is being checked.
    interval : Set, optional
        The range of values in which we are testing (defaults to set of
        all real numbers).
    symbol : Symbol, optional
        The symbol present in expression which gets varied over the given range.

    Returns
    =======

    Boolean
        True if ``expression`` is strictly increasing in the given ``interval``,
        False otherwise.

    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(   Ni    (    (   R   (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyR   ä   R   (   R   (   R
   R   R   (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   is_strictly_increasing¼   s    (c         C   s   t  |  d „  | | ƒ S(   s7  
    Return whether the function is decreasing in the given interval.

    Parameters
    ==========

    expression : Expr
        The target function which is being checked.
    interval : Set, optional
        The range of values in which we are testing (defaults to set of
        all real numbers).
    symbol : Symbol, optional
        The symbol present in expression which gets varied over the given range.

    Returns
    =======

    Boolean
        True if ``expression`` is decreasing (either strictly decreasing or
        constant) in the given ``interval``, False otherwise.

    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(   Ni    (    (   R   (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyR     R   (   R   (   R
   R   R   (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   is_decreasingç   s    (c         C   s   t  |  d „  | | ƒ S(   s  
    Return whether the function is strictly decreasing in the given interval.

    Parameters
    ==========

    expression : Expr
        The target function which is being checked.
    interval : Set, optional
        The range of values in which we are testing (defaults to set of
        all real numbers).
    symbol : Symbol, optional
        The symbol present in expression which gets varied over the given range.

    Returns
    =======

    Boolean
        True if ``expression`` is strictly decreasing in the given ``interval``,
        False otherwise.

    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(   Ni    (    (   R   (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyR   8  R   (   R   (   R
   R   R   (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   is_strictly_decreasing  s    &c         C   s—   t  |  ƒ }  |  j } | d k rB t | ƒ d k rB t d ƒ ‚ n  | pc | rZ | j ƒ  n	 t d ƒ } t |  j | ƒ | | ƒ } | j	 | ƒ t
 j k S(   sk  
    Return whether the function is monotonic in the given interval.

    Parameters
    ==========

    expression : Expr
        The target function which is being checked.
    interval : Set, optional
        The range of values in which we are testing (defaults to set of
        all real numbers).
    symbol : Symbol, optional
        The symbol present in expression which gets varied over the given range.

    Returns
    =======

    Boolean
        True if ``expression`` is monotonic in the given ``interval``,
        False otherwise.

    Raises
    ======

    NotImplementedError
        Monotonicity check has not been implemented for the queried function.

    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

    i   sK   is_monotonic has not yet been implemented for all multivariate expressions.R   N(   R    R   R   R   R   R   R   R   R   t   intersectionR   t   EmptySet(   R
   R   R   R   R   t   turning_points(    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   is_monotonic;  s    .	$N(   t   __doc__t   sympy.core.sympifyR    t   sympy.solvers.solvesetR   t   sympy.simplifyR   t   sympyR   R   R   R   R   R   R   R   R    R!   R%   (    (    (    s;   lib/python2.7/site-packages/sympy/calculus/singularities.pyt   <module>   s   	J/+++)