B
    [[,  ใ               @   sL  d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	 ddl
mZ ddlmZ ddlmZmZ d	d
 ZG dd deZdd ZG dd deZedZdd ZG dd deZdd ZG dd deZdd ZG dd deZedZdd  ZG d!d" d"eZd#d$ ZG d%d& d&eZ d'd( Z!G d)d* d*eZ"d+d, Z#G d-d. d.eZ$dS )/a#  
This module contains SymPy functions mathcin corresponding to special math functions in the
C standard library (since C99, also available in C++11).

The functions defined in this module allows the user to express functions such as ``expm1``
as a SymPy function for symbolic manipulation.

้    N)ฺS)ฺRational)ฺArgumentIndexErrorฺFunctionฺLambda)ฺPow)ฺsqrt)ฺexpฺlogc             C   s   t | tj S )N)r	   r   ฺOne)ฺxฉ r   ๚7lib/python3.7/site-packages/sympy/codegen/cfunctions.pyฺ_expm1   s    r   c               @   sN   e Zd ZdZdZdddZdd Zdd ZeZe	d	d
 Z
dd Zdd ZdS )ฺexpm1a  
    Represents the exponential function minus one.

    The benefit of using ``expm1(x)`` over ``exp(x) - 1``
    is that the latter is prone to cancellation under finite precision
    arithmetic when x is close to zero.

    Examples
    ========
    >>> from sympy.abc import x
    >>> from sympy.codegen.cfunctions import expm1
    >>> '%.0e' % expm1(1e-99).evalf()
    '1e-99'
    >>> from math import exp
    >>> exp(1e-99) - 1
    0.0
    >>> expm1(x).diff(x)
    exp(x)

    See Also
    ========

    log1p
    ้   c             C   s    |dkrt | j S t| |dS )z@
        Returns the first derivative of this function.
        r   N)r	   ฺargsr   )ฺselfฺargindexr   r   r   ฺfdiff2   s    
zexpm1.fdiffc             K   s
   t | j S )N)r   r   )r   ฺhintsr   r   r   ฺ_eval_expand_func;   s    zexpm1._eval_expand_funcc             C   s   t |tj S )N)r	   r   r   )r   ฺargr   r   r   ฺ_eval_rewrite_as_exp>   s    zexpm1._eval_rewrite_as_expc             C   s    t  |ก}|d k	r|tj S d S )N)r	   ฺevalr   r   )ฺclsr   Zexp_argr   r   r   r   C   s    
z
expm1.evalc             C   s   | j d jS )Nr   )r   Zis_real)r   r   r   r   ฺ_eval_is_realI   s    zexpm1._eval_is_realc             C   s   | j d jS )Nr   )r   ฺ	is_finite)r   r   r   r   ฺ_eval_is_finiteL   s    zexpm1._eval_is_finiteN)r   )ฺ__name__ฺ
__module__ฺ__qualname__ฺ__doc__ฺnargsr   r   r   ฺ_eval_rewrite_as_tractableฺclassmethodr   r   r   r   r   r   r   r      s   
	r   c             C   s   t | tj S )N)r
   r   r   )r   r   r   r   ฺ_log1pP   s    r&   c               @   sf   e Zd ZdZdZdddZdd Zdd ZeZe	d	d
 Z
dd Zdd Zdd Zdd Zdd ZdS )ฺlog1paS  
    Represents the natural logarithm of a number plus one.

    The benefit of using ``log1p(x)`` over ``log(x + 1)``
    is that the latter is prone to cancellation under finite precision
    arithmetic when x is close to zero.

    Examples
    ========
    >>> from sympy.abc import x
    >>> from sympy.codegen.cfunctions import log1p
    >>> from sympy.core.function import expand_log
    >>> '%.0e' % expand_log(log1p(1e-99)).evalf()
    '1e-99'
    >>> from math import log
    >>> log(1 + 1e-99)
    0.0
    >>> log1p(x).diff(x)
    1/(x + 1)

    See Also
    ========


    expm1
    r   c             C   s,   |dkrt j| jd t j  S t| |dS )z@
        Returns the first derivative of this function.
        r   r   N)r   r   r   r   )r   r   r   r   r   r   r   s    zlog1p.fdiffc             K   s
   t | j S )N)r&   r   )r   r   r   r   r   r   |   s    zlog1p._eval_expand_funcc             C   s   t |S )N)r&   )r   r   r   r   r   ฺ_eval_rewrite_as_log   s    zlog1p._eval_rewrite_as_logc             C   sF   |j rt|tj S |js*t |tj กS |jrBtt|tj S d S )N)Zis_Rationalr
   r   r   Zis_Floatr   ฺ	is_numberr   )r   r   r   r   r   r      s    z
log1p.evalc             C   s   | j d tj jS )Nr   )r   r   r   ฺis_nonnegative)r   r   r   r   r      s    zlog1p._eval_is_realc             C   s"   | j d tj jrdS | j d jS )Nr   F)r   r   r   ฺis_zeror   )r   r   r   r   r      s    zlog1p._eval_is_finitec             C   s   | j d jS )Nr   )r   Zis_positive)r   r   r   r   ฺ_eval_is_positive   s    zlog1p._eval_is_positivec             C   s   | j d jS )Nr   )r   r+   )r   r   r   r   ฺ_eval_is_zero   s    zlog1p._eval_is_zeroc             C   s   | j d jS )Nr   )r   r*   )r   r   r   r   ฺ_eval_is_nonnegative   s    zlog1p._eval_is_nonnegativeN)r   )r   r    r!   r"   r#   r   r   r(   r$   r%   r   r   r   r,   r-   r.   r   r   r   r   r'   T   s   

	r'   ้   c             C   s
   t t| S )N)r   ฺ_Two)r   r   r   r   ฺ_exp2    s    r1   c               @   s>   e Zd ZdZdZdddZdd ZeZdd Ze	d	d
 Z
dS )ฺexp2aฅ  
    Represents the exponential function with base two.

    The benefit of using ``exp2(x)`` over ``2**x``
    is that the latter is not as efficient under finite precision
    arithmetic.

    Examples
    ========
    >>> from sympy.abc import x
    >>> from sympy.codegen.cfunctions import exp2
    >>> exp2(2).evalf() == 4
    True
    >>> exp2(x).diff(x)
    log(2)*exp2(x)

    See Also
    ========

    log2
    r   c             C   s"   |dkr| t t S t| |dS )z@
        Returns the first derivative of this function.
        r   N)r
   r0   r   )r   r   r   r   r   r   ผ   s    z
exp2.fdiffc             C   s   t |S )N)r1   )r   r   r   r   r   ฺ_eval_rewrite_as_Powล   s    zexp2._eval_rewrite_as_Powc             K   s
   t | j S )N)r1   r   )r   r   r   r   r   r   ส   s    zexp2._eval_expand_funcc             C   s   |j rt|S d S )N)r)   r1   )r   r   r   r   r   r   อ   s    z	exp2.evalN)r   )r   r    r!   r"   r#   r   r3   r$   r   r%   r   r   r   r   r   r2   ฃ   s   
	r2   c             C   s   t | t t S )N)r
   r0   )r   r   r   r   ฺ_log2ำ   s    r4   c               @   s>   e Zd ZdZdZdddZedd Zdd Zd	d
 Z	e	Z
dS )ฺlog2aด  
    Represents the logarithm function with base two.

    The benefit of using ``log2(x)`` over ``log(x)/log(2)``
    is that the latter is not as efficient under finite precision
    arithmetic.

    Examples
    ========
    >>> from sympy.abc import x
    >>> from sympy.codegen.cfunctions import log2
    >>> log2(4).evalf() == 2
    True
    >>> log2(x).diff(x)
    1/(x*log(2))

    See Also
    ========

    exp2
    log10
    r   c             C   s.   |dkr t jtt| jd   S t| |dS )z@
        Returns the first derivative of this function.
        r   r   N)r   r   r
   r0   r   r   )r   r   r   r   r   r   ๐   s    z
log2.fdiffc             C   s:   |j r tj|td}|jr6|S n|jr6|jtkr6|jS d S )N)ฺbase)r)   r
   r   r0   ฺis_Atomฺis_Powr6   r	   )r   r   ฺresultr   r   r   r   ๚   s    z	log2.evalc             K   s
   t | j S )N)r4   r   )r   r   r   r   r   r     s    zlog2._eval_expand_funcc             C   s   t |S )N)r4   )r   r   r   r   r   r(     s    zlog2._eval_rewrite_as_logN)r   )r   r    r!   r"   r#   r   r%   r   r   r(   r$   r   r   r   r   r5   ื   s   

	r5   c             C   s   | | | S )Nr   )r   ฺyฺzr   r   r   ฺ_fma  s    r<   c               @   s.   e Zd ZdZdZdddZdd Zdd	 Zd
S )ฺfmaan  
    Represents "fused multiply add".

    The benefit of using ``fma(x, y, z)`` over ``x*y + z``
    is that, under finite precision arithmetic, the former is
    supported by special instructions on some CPUs.

    Examples
    ========
    >>> from sympy.abc import x, y, z
    >>> from sympy.codegen.cfunctions import fma
    >>> fma(x, y, z).diff(x)
    y

    ้   r   c             C   s2   |dkr| j d|  S |dkr$tjS t| |dS )z@
        Returns the first derivative of this function.
        )r   r/   r/   r>   N)r   r   r   r   )r   r   r   r   r   r   "  s
    z	fma.fdiffc             K   s
   t | j S )N)r<   r   )r   r   r   r   r   r   .  s    zfma._eval_expand_funcc             C   s   t |S )N)r<   )r   r   r   r   r   r$   1  s    zfma._eval_rewrite_as_tractableN)r   )r   r    r!   r"   r#   r   r   r$   r   r   r   r   r=     s
   
r=   ้
   c             C   s   t | t t S )N)r
   ฺ_Ten)r   r   r   r   ฺ_log108  s    rA   c               @   s>   e Zd ZdZdZdddZedd Zdd Zd	d
 Z	e	Z
dS )ฺlog10a!  
    Represents the logarithm function with base ten.

    Examples
    ========
    >>> from sympy.abc import x
    >>> from sympy.codegen.cfunctions import log10
    >>> log10(100).evalf() == 2
    True
    >>> log10(x).diff(x)
    1/(x*log(10))

    See Also
    ========

    log2
    r   c             C   s.   |dkr t jtt| jd   S t| |dS )z@
        Returns the first derivative of this function.
        r   r   N)r   r   r
   r@   r   r   )r   r   r   r   r   r   P  s    zlog10.fdiffc             C   s:   |j r tj|td}|jr6|S n|jr6|jtkr6|jS d S )N)r6   )r)   r
   r   r@   r7   r8   r6   r	   )r   r   r9   r   r   r   r   Z  s    z
log10.evalc             K   s
   t | j S )N)rA   r   )r   r   r   r   r   r   c  s    zlog10._eval_expand_funcc             C   s   t |S )N)rA   )r   r   r   r   r   r(   f  s    zlog10._eval_rewrite_as_logN)r   )r   r    r!   r"   r#   r   r%   r   r   r(   r$   r   r   r   r   rB   <  s   

	rB   c             C   s   t | tjS )N)r   r   ฺHalf)r   r   r   r   ฺ_Sqrtl  s    rD   c               @   s2   e Zd ZdZdZd
ddZdd Zdd ZeZd	S )ฺSqrtaฬ  
    Represents the square root function.

    The reason why one would use ``Sqrt(x)`` over ``sqrt(x)``
    is that the latter is internally represented as ``Pow(x, S.Half)`` which
    may not be what one wants when doing code-generation.

    Examples
    ========
    >>> from sympy.abc import x
    >>> from sympy.codegen.cfunctions import Sqrt
    >>> Sqrt(x)
    Sqrt(x)
    >>> Sqrt(x).diff(x)
    1/(2*sqrt(x))

    See Also
    ========

    Cbrt
    r   c             C   s.   |dkr t | jd tj t S t| |dS )z@
        Returns the first derivative of this function.
        r   r   N)r   r   r   rC   r0   r   )r   r   r   r   r   r     s    z
Sqrt.fdiffc             K   s
   t | j S )N)rD   r   )r   r   r   r   r   r     s    zSqrt._eval_expand_funcc             C   s   t |S )N)rD   )r   r   r   r   r   r3     s    zSqrt._eval_rewrite_as_PowN)r   )	r   r    r!   r"   r#   r   r   r3   r$   r   r   r   r   rE   p  s   
	rE   c             C   s   t | tddS )Nr   r>   )r   r   )r   r   r   r   ฺ_Cbrt  s    rF   c               @   s2   e Zd ZdZdZd
ddZdd Zdd ZeZd	S )ฺCbrtaิ  
    Represents the cube root function.

    The reason why one would use ``Cbrt(x)`` over ``cbrt(x)``
    is that the latter is internally represented as ``Pow(x, Rational(1, 3))`` which
    may not be what one wants when doing code-generation.

    Examples
    ========

    >>> from sympy.abc import x
    >>> from sympy.codegen.cfunctions import Cbrt
    >>> Cbrt(x)
    Cbrt(x)
    >>> Cbrt(x).diff(x)
    1/(3*x**(2/3))

    See Also
    ========

    Sqrt
    r   c             C   s4   |dkr&t | jd tt d d S t| |dS )z@
        Returns the first derivative of this function.
        r   r   r>   N)r   r   r   r0   r   )r   r   r   r   r   r   ท  s    z
Cbrt.fdiffc             K   s
   t | j S )N)rF   r   )r   r   r   r   r   r   ม  s    zCbrt._eval_expand_funcc             C   s   t |S )N)rF   )r   r   r   r   r   r3   ฤ  s    zCbrt._eval_rewrite_as_PowN)r   )	r   r    r!   r"   r#   r   r   r3   r$   r   r   r   r   rG     s   

rG   c             C   s   t t| dt|d S )Nr/   )r   r   )r   r:   r   r   r   ฺ_hypotส  s    rH   c               @   s2   e Zd ZdZdZdddZdd Zdd	 ZeZd
S )ฺhypotaั  
    Represents the hypotenuse function.

    The hypotenuse function is provided by e.g. the math library
    in the C99 standard, hence one may want to represent the function
    symbolically when doing code-generation.

    Examples
    ========

    >>> from sympy.abc import x, y
    >>> from sympy.codegen.cfunctions import hypot
    >>> hypot(3, 4).evalf() == 5
    True
    >>> hypot(x, y)
    hypot(x, y)
    >>> hypot(x, y).diff(x)
    x/hypot(x, y)

    r/   r   c             C   s8   |dkr*d| j |d   t| j| j    S t| |dS )z@
        Returns the first derivative of this function.
        )r   r/   r/   r   N)r   r0   ฺfuncr   )r   r   r   r   r   r   ๅ  s    "zhypot.fdiffc             K   s
   t | j S )N)rH   r   )r   r   r   r   r   r   ๏  s    zhypot._eval_expand_funcc             C   s   t |S )N)rH   )r   r   r   r   r   r3   ๒  s    zhypot._eval_rewrite_as_PowN)r   )	r   r    r!   r"   r#   r   r   r3   r$   r   r   r   r   rI   ฮ  s   

rI   )%r"   ZmathZsympy.core.singletonr   Zsympy.core.numbersr   Zsympy.core.functionr   r   r   Zsympy.core.powerr   Z(sympy.functions.elementary.miscellaneousr   Z&sympy.functions.elementary.exponentialr	   r
   r   r   r&   r'   r0   r1   r2   r4   r5   r<   r=   r@   rA   rB   rD   rE   rF   rG   rH   rI   r   r   r   r   ฺ<module>   s6   9J05%0*,