o
    *ήc                     @   sD  d dl mZ d dlmZ d dlmZmZmZ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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lmZ m!Z!m"Z# G dd deZ$G dd de$ZG dd de$Z%G dd de$Z&G dd de$Z'G dd de$Z(G dd de$Z)e(Z*e)Z+G dd de$Z,dS )    )List)reduce)SsympifyDummyMod)cacheit)FunctionArgumentIndexError	PoleError)	fuzzy_and)IntegerpiI)Eq)HAS_GMPYgmpy)sieve)Poly)	factorialprodsqrtc                   @   s   e Zd ZdZdd ZdS )CombinatorialFunctionz(Base class for combinatorial functions. c                 K   s<   ddl m} || }|d }|||d ||  kr|S | S )Nr   )combsimpmeasureratio)sympy.simplify.combsimpr   )selfkwargsr   exprr    r    O/tmp/pip-target-vg8gfxp4/lib/python/sympy/functions/combinatorial/factorials.py_eval_simplify   s   z$CombinatorialFunction._eval_simplifyN)__name__
__module____qualname____doc__r"   r    r    r    r!   r      s    r   c                   @   s   e Zd ZdZd#ddZg dZg Zedd Zedd	 Z	ed
d Z
dd Zdd Zd$ddZdd Zdd Zdd Zdd Zdd Zdd Zd%d!d"ZdS )&r   a  Implementation of factorial function over nonnegative integers.
       By convention (consistent with the gamma function and the binomial
       coefficients), factorial of a negative integer is complex infinity.

       The factorial is very important in combinatorics where it gives
       the number of ways in which `n` objects can be permuted. It also
       arises in calculus, probability, number theory, etc.

       There is strict relation of factorial with gamma function. In
       fact `n! = gamma(n+1)` for nonnegative integers. Rewrite of this
       kind is very useful in case of combinatorial simplification.

       Computation of the factorial is done using two algorithms. For
       small arguments a precomputed look up table is used. However for bigger
       input algorithm Prime-Swing is used. It is the fastest algorithm
       known and computes `n!` via prime factorization of special class
       of numbers, called here the 'Swing Numbers'.

       Examples
       ========

       >>> from sympy import Symbol, factorial, S
       >>> n = Symbol('n', integer=True)

       >>> factorial(0)
       1

       >>> factorial(7)
       5040

       >>> factorial(-2)
       zoo

       >>> factorial(n)
       factorial(n)

       >>> factorial(2*n)
       factorial(2*n)

       >>> factorial(S(1)/2)
       factorial(1/2)

       See Also
       ========

       factorial2, RisingFactorial, FallingFactorial
       c                 C   sH   ddl m}m} |dkr|| jd d |d| jd d  S t| |)Nr   )gamma	polygammar'   )'sympy.functions.special.gamma_functionsr(   r)   argsr
   )r   argindexr(   r)   r    r    r!   fdiffT   s   &
zfactorial.fdiff)!r'   r'   r'      r.         #   r1   i;  ?   i     i  i  #  r4   iS i{/  i! im  i isX iU iP
 ioik iIi/L iSi} #r5   c           	      C   s   |dk r	| j | S tt|g }}td|d D ]&}d|}}	 || }|dkr5|d@ dkr4||9 }nnq"|dkr@|| qt|d |d d D ]}|| d@ dkr\|| qMtt|d d |d }t|}|| S )N!   r.   r'   Tr      )_small_swingint_sqrtr   
primerangeappendr   )	clsnNprimesprimepq	L_product	R_productr    r    r!   _swingc   s.   

	

zfactorial._swingc                 C   s(   |dk rdS |  |d d | | S )Nr7   r'   )
_recursiverF   )r=   r>   r    r    r!   rG      s   zfactorial._recursivec                 C   s   t |}|jrh|jrtjS |tju rtjS |jrj|jrtjS |j	}|dk rG| j
s<d}tddD ]}||9 }| j
| q/| j
|d  }t|S trRt|}t|S t|d}| |d||   }t|S d S d S )N   r'   1r7   )r   	is_Numberis_zeror   OneInfinity
is_Integeris_negativeComplexInfinityrB   _small_factorialsranger<   r   r   facbincountrG   r   )r=   r>   resultibitsr    r    r!   eval   s4   


zfactorial.evalc                 C   s   dt t|}}dg| }d}td|d D ]2}|dkr1d|| }}|r1||7 }|| }|s'||k r@|| | | ||< q|t||| | }qt|D ]\}	}
|	dks[|
dkr\qO|
dkrc dS |t|
|	| | }qO|S )Nr'   r7   r   )r9   r:   r   r;   pow	enumerate)r   r>   rC   resr?   pwmrA   yexbsr    r    r!   _facmod   s(   
zfactorial._facmodc                 C   s  | j d }|jrw|jry|jr{t|}|| }|jrtjS |j}|dkr9|r)d| S |du r5|d jr7tjS d S d S |jr}|jrt	t
|||f\}}}|rm|d |k rm| |d |}t||d |}|d ri| }|| S | ||}|| S d S d S d S d S d S )Nr   r'   F   r7   )r+   
is_integeris_nonnegativeabsis_nonpositiver   Zerois_primerN   mapr9   rb   rZ   )r   rC   r>   aqdisprimefcr    r    r!   	_eval_Mod   s2   
zfactorial._eval_ModTc                 K   s   ddl m} ||d S Nr   r(   r'   r*   r(   )r   r>   	piecewiser   r(   r    r    r!   _eval_rewrite_as_gamma   s   z factorial._eval_rewrite_as_gammac                 K   s<   ddl m} |jr|jrtddd}|||d|fS d S d S )Nr   )ProductrW   T)integerr'   )sympy.concrete.productsrv   rf   re   r   )r   r>   r   rv   rW   r    r    r!   _eval_rewrite_as_Product   s
   z"factorial._eval_rewrite_as_Productc                 C   $   | j d jr| j d jrdS d S d S Nr   Tr+   re   rf   r   r    r    r!   _eval_is_integer      zfactorial._eval_is_integerc                 C   rz   r{   r|   r}   r    r    r!   _eval_is_positive   r   zfactorial._eval_is_positivec                 C   (   | j d }|jr|jr|d jS d S d S )Nr   r7   r|   r   xr    r    r!   _eval_is_even      

zfactorial._eval_is_evenc                 C   r   )Nr   r.   r|   r   r    r    r!   _eval_is_composite   r   zfactorial._eval_is_compositec                 C   s   | j d }|js|jrdS d S r{   )r+   rf   is_nonintegerr   r    r    r!   _eval_is_real  s   
zfactorial._eval_is_realNr   c                 C   sD   | j d |}||d}|jrtjS |js| |S td|  )Nr   zCannot expand %s around 0)	r+   as_leading_termsubsrK   r   rL   is_infinitefuncr   )r   r   logxcdirargarg0r    r    r!   _eval_as_leading_term  s   
zfactorial._eval_as_leading_termr'   TNr   )r#   r$   r%   r&   r-   r8   rQ   classmethodrF   rG   rY   rb   rp   ru   ry   r~   r   r   r   r   r   r    r    r    r!   r   #   s*    
0


 
r   c                   @   s   e Zd ZdS )MultiFactorialN)r#   r$   r%   r    r    r    r!   r     s    r   c                   @   sf   e Zd ZdZeedd Zedd Zdd Zdd	 Z	d
d Z
dddZdd Zdd Zdd ZdS )subfactoriala  The subfactorial counts the derangements of $n$ items and is
    defined for non-negative integers as:

    .. math:: !n = \begin{cases} 1 & n = 0 \\ 0 & n = 1 \\
                    (n-1)(!(n-1) + !(n-2)) & n > 1 \end{cases}

    It can also be written as ``int(round(n!/exp(1)))`` but the
    recursive definition with caching is implemented for this function.

    An interesting analytic expression is the following [2]_

    .. math:: !x = \Gamma(x + 1, -1)/e

    which is valid for non-negative integers `x`. The above formula
    is not very useful in case of non-integers. `\Gamma(x + 1, -1)` is
    single-valued only for integral arguments `x`, elsewhere on the positive
    real axis it has an infinite number of branches none of which are real.

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Subfactorial
    .. [2] http://mathworld.wolfram.com/Subfactorial.html

    Examples
    ========

    >>> from sympy import subfactorial
    >>> from sympy.abc import n
    >>> subfactorial(n + 1)
    subfactorial(n + 1)
    >>> subfactorial(5)
    44

    See Also
    ========

    factorial, uppergamma,
    sympy.utilities.iterables.generate_derangements
    c                 C   sN   |st jS |dkrt jS d\}}td|d D ]}||d ||  }}q|S )Nr'   )r'   r   r7   )r   rL   ri   rR   )r   r>   z1z2rW   r    r    r!   _eval>  s   zsubfactorial._evalc                 C   sD   |j r|jr|jr| |S |tju rtjS |tju r tjS d S d S N)rJ   rN   rf   r   r   NaNrM   )r=   r   r    r    r!   rY   K  s   


zsubfactorial.evalc                 C   rz   r{   )r+   is_oddrf   r}   r    r    r!   r   U  r   zsubfactorial._eval_is_evenc                 C   rz   r{   r|   r}   r    r    r!   r~   Y  r   zsubfactorial._eval_is_integerc                 K   s>   ddl m} td}tj| t| }t||||d|f S )Nr   )	summationrW   )sympy.concrete.summationsr   r   r   NegativeOner   )r   r   r   r   rW   fr    r    r!   _eval_rewrite_as_factorial]  s   z'subfactorial._eval_rewrite_as_factorialTc                 K   s^   ddl m} ddlm}m} tj|d  |t t |  ||d d ||d  |d S )Nr   )exp)r(   
lowergammar'   rc   )	&sympy.functions.elementary.exponentialr   r*   r(   r   r   r   r   r   )r   r   rt   r   r   r(   r   r    r    r!   ru   c  s   ,
z#subfactorial._eval_rewrite_as_gammac                 K   s    ddl m} ||d dtj S )Nr   )
uppergammar'   rc   )r*   r   r   Exp1)r   r   r   r   r    r    r!   _eval_rewrite_as_uppergammai  s   z(subfactorial._eval_rewrite_as_uppergammac                 C   rz   r{   r|   r}   r    r    r!   _eval_is_nonnegativem  r   z!subfactorial._eval_is_nonnegativec                 C   rz   r{   )r+   is_evenrf   r}   r    r    r!   _eval_is_oddq  r   zsubfactorial._eval_is_oddNr   )r#   r$   r%   r&   r   r   r   rY   r   r~   r   ru   r   r   r   r    r    r    r!   r     s    )
	
r   c                   @   sF   e Zd ZdZedd Zdd Zdd Zdd	 Zd
d Z	dddZ
dS )
factorial2aA  The double factorial `n!!`, not to be confused with `(n!)!`

    The double factorial is defined for nonnegative integers and for odd
    negative integers as:

    .. math:: n!! = \begin{cases} 1 & n = 0 \\
                    n(n-2)(n-4) \cdots 1 & n\ \text{positive odd} \\
                    n(n-2)(n-4) \cdots 2 & n\ \text{positive even} \\
                    (n+2)!!/(n+2) & n\ \text{negative odd} \end{cases}

    References
    ==========

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

    Examples
    ========

    >>> from sympy import factorial2, var
    >>> n = var('n')
    >>> n
    n
    >>> factorial2(n + 1)
    factorial2(n + 1)
    >>> factorial2(5)
    15
    >>> factorial2(-1)
    1
    >>> factorial2(-5)
    1/3

    See Also
    ========

    factorial, RisingFactorial, FallingFactorial
    c                 C   s~   |j r=|js
td|jr&|jr|d }d| t| S t|t|d  S |jr9|tj	d| d   t|  S tdd S )Nz<argument must be nonnegative integer or negative odd integerr7   r'   )
rJ   rN   
ValueErrorrf   r   r   r   r   r   r   )r=   r   kr    r    r!   rY     s    zfactorial2.evalc                 C   s@   | j d }|jr|jrdS |jr|jrdS |jrdS d S d S d S )Nr   FT)r+   re   r   r   is_positiverK   r   r>   r    r    r!   r     s   
zfactorial2._eval_is_evenc                 C   s6   | j d }|jr|d jrdS |jr|d jS d S d S )Nr   r'   Tr.   )r+   re   rf   r   r   r    r    r!   r~     s   


zfactorial2._eval_is_integerc                 C   s<   | j d }|jr|d jS |jr|jrdS |jrdS d S d S )Nr   r.   FT)r+   r   rf   r   r   rK   r   r    r    r!   r     s   

zfactorial2._eval_is_oddc                 C   s:   | j d }|jr|d jrdS |jr|d d jS d S d S )Nr   r'   Tr7   )r+   re   rf   r   r   r   r    r    r!   r     s   

zfactorial2._eval_is_positiveTc                 K   sr   ddl m} ddlm} ddlm} d|d  ||d d  |dtt|ddf|dt tt|ddf S )Nr   )r   	Piecewiserr   r7   r'   )	(sympy.functions.elementary.miscellaneousr   $sympy.functions.elementary.piecewiser   r*   r(   r   r   r   )r   r>   rt   r   r   r   r(   r    r    r!   ru     s   .z!factorial2._eval_rewrite_as_gammaNr   )r#   r$   r%   r&   r   rY   r   r~   r   r   ru   r    r    r    r!   r   v  s    %

r   c                   @   P   e Zd ZdZedd ZdddZdd Zd	d
 Zdd Z	dddZ
dd ZdS )RisingFactorialao  
    Rising factorial (also called Pochhammer symbol [1]_) is a double valued
    function arising in concrete mathematics, hypergeometric functions
    and series expansions. It is defined by:

    .. math:: \texttt{rf(y, k)} = (x)^k = x \cdot (x+1) \cdots (x+k-1)

    where `x` can be arbitrary expression and `k` is an integer. For
    more information check "Concrete mathematics" by Graham, pp. 66
    or visit http://mathworld.wolfram.com/RisingFactorial.html page.

    When `x` is a `~.Poly` instance of degree $\ge 1$ with a single variable,
    `(x)^k = x(y) \cdot x(y+1) \cdots x(y+k-1)`, where `y` is the
    variable of `x`. This is as described in [2]_.

    Examples
    ========

    >>> from sympy import rf, Poly
    >>> from sympy.abc import x
    >>> rf(x, 0)
    1
    >>> rf(1, 5)
    120
    >>> rf(x, 5) == x*(1 + x)*(2 + x)*(3 + x)*(4 + x)
    True
    >>> rf(Poly(x**3, x), 2)
    Poly(x**6 + 3*x**5 + 3*x**4 + x**3, x, domain='ZZ')

    Rewriting is complicated unless the relationship between
    the arguments is known, but rising factorial can
    be rewritten in terms of gamma, factorial, binomial,
    and falling factorial.

    >>> from sympy import Symbol, factorial, ff, binomial, gamma
    >>> n = Symbol('n', integer=True, positive=True)
    >>> R = rf(n, n + 2)
    >>> for i in (rf, ff, factorial, binomial, gamma):
    ...  R.rewrite(i)
    ...
    RisingFactorial(n, n + 2)
    FallingFactorial(2*n + 1, n + 2)
    factorial(2*n + 1)/factorial(n - 1)
    binomial(2*n + 1, n + 2)*factorial(n + 2)
    gamma(2*n + 2)/gamma(n)

    See Also
    ========

    factorial, factorial2, FallingFactorial

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Pochhammer_symbol
    .. [2] Peter Paule, "Greatest Factorial Factorization and Symbolic
           Summation", Journal of Symbolic Computation, vol. 20, pp. 235-268,
           1995.

    c                    s  t   t |} tju s|tju rtjS  tju rt|S |jr|jr'tjS |jrn tju r2tjS  tj	u r@|j
r=tj	S tjS t tr` j}t|dkrRtdt fddtt|dS t fddtt|dS  tju rvtjS  tj	u r~tjS t tr j}t|dkrtddt fddtdtt|d d S dt fddtdtt|d d S |jdkrȈ jrʈ jrtjS d S d S d S )	Nr'   0rf only defined for polynomials on one generatorc                       |   | S r   shiftrrW   r   r    r!   <lambda>H     z&RisingFactorial.eval.<locals>.<lambda>c                       |  |  S r   r    r   r   r    r!   r   L      c                       |   |  S r   r   r   r   r    r!   r   [     c                       |  |  S r   r    r   r   r    r!   r   _  s   F)r   r   r   rL   r   rN   rK   r   rM   NegativeInfinityr   
isinstancer   genslenr   r   rR   r9   rg   re   rO   ri   r=   r   r   r   r    r   r!   rY   ,  sZ   







zRisingFactorial.evalTc                 K   s   ddl m} ddlm} |s2|dkdkr(tj| |d|  || | d  S ||| || S |||| || |dkftj| |d|  || | d  dfS Nr   r   rr   Tr'   r   r   r*   r(   r   r   r   r   r   rt   r   r   r(   r    r    r!   ru   g  s   (*z&RisingFactorial._eval_rewrite_as_gammac                 K   s   t || d |S Nr'   )FallingFactorialr   r   r   r   r    r    r!   !_eval_rewrite_as_FallingFactorialr     z1RisingFactorial._eval_rewrite_as_FallingFactorialc                 K   sl   ddl m} |jr2|jr4|t|| d t|d  |dkftj| t|  t| |  dfS d S d S Nr   r   r'   Tr   r   re   r   r   r   r   r   r   r   r   r    r    r!   r   u  s   "$z*RisingFactorial._eval_rewrite_as_factorialc                 K   s$   |j rt|t|| d | S d S r   re   r   binomialr   r    r    r!   _eval_rewrite_as_binomial|  s   z)RisingFactorial._eval_rewrite_as_binomialNc                 K   s   ddl m} |rA||tj}|tju r#||| jddd|| S |tju rAtj| |d|  || | d jddd S | |jdddS Nr   rr   	tractableT)deepr'   )r*   r(   r   r   rM   rewriter   r   r   r   r   limitvarr   r(   k_limr    r    r!   _eval_rewrite_as_tractable  s   

2z*RisingFactorial._eval_rewrite_as_tractablec                 C   &   t | jd j| jd j| jd jfS Nr   r'   r   r+   re   rf   r}   r    r    r!   r~        
z RisingFactorial._eval_is_integerr   r   )r#   r$   r%   r&   r   rY   ru   r   r   r   r   r~   r    r    r    r!   r     s    =

:

r   c                   @   r   )r   a/  
    Falling factorial (related to rising factorial) is a double valued
    function arising in concrete mathematics, hypergeometric functions
    and series expansions. It is defined by

    .. math:: \texttt{ff(x, k)} = (x)_k = x \cdot (x-1) \cdots (x-k+1)

    where `x` can be arbitrary expression and `k` is an integer. For
    more information check "Concrete mathematics" by Graham, pp. 66
    or [1]_.

    When `x` is a `~.Poly` instance of degree $\ge 1$ with single variable,
    `(x)_k = x(y) \cdot x(y-1) \cdots x(y-k+1)`, where `y` is the
    variable of `x`. This is as described in

    >>> from sympy import ff, Poly, Symbol
    >>> from sympy.abc import x
    >>> n = Symbol('n', integer=True)

    >>> ff(x, 0)
    1
    >>> ff(5, 5)
    120
    >>> ff(x, 5) == x*(x - 1)*(x - 2)*(x - 3)*(x - 4)
    True
    >>> ff(Poly(x**2, x), 2)
    Poly(x**4 - 2*x**3 + x**2, x, domain='ZZ')
    >>> ff(n, n)
    factorial(n)

    Rewriting is complicated unless the relationship between
    the arguments is known, but falling factorial can
    be rewritten in terms of gamma, factorial and binomial
    and rising factorial.

    >>> from sympy import factorial, rf, gamma, binomial, Symbol
    >>> n = Symbol('n', integer=True, positive=True)
    >>> F = ff(n, n - 2)
    >>> for i in (rf, ff, factorial, binomial, gamma):
    ...  F.rewrite(i)
    ...
    RisingFactorial(3, n - 2)
    FallingFactorial(n, n - 2)
    factorial(n)/2
    binomial(n, n - 2)*factorial(n - 2)
    gamma(n + 1)/2

    See Also
    ========

    factorial, factorial2, RisingFactorial

    References
    ==========

    .. [1] http://mathworld.wolfram.com/FallingFactorial.html
    .. [2] Peter Paule, "Greatest Factorial Factorization and Symbolic
           Summation", Journal of Symbolic Computation, vol. 20, pp. 235-268,
           1995.

    c                    s|  t   t |} tju s|tju rtjS |jr  |kr t S |jr|jr)tjS |jrp tj	u r4tj	S  tj
u rB|jr?tj
S tj	S t trb j}t|dkrTtdt fddtt|dS t fddtt|dS  tj	u rxtj	S  tj
u rtj	S t tr j}t|dkrtddt fddtdtt|d d S dt fddtdtt|d d S d S )	Nr'   z0ff only defined for polynomials on one generatorc                    r   r   r   r   r   r    r!   r     r   z'FallingFactorial.eval.<locals>.<lambda>c                    r   r   r    r   r   r    r!   r     r   r   c                    r   r   r   r   r   r    r!   r     r   c                    r   r   r    r   r   r    r!   r      r   )r   r   r   re   r   rN   rK   rL   r   rM   r   r   r   r   r   r   r   r   rR   r9   rg   r   r    r   r!   rY     sR   





zFallingFactorial.evalTc                 K   s   ddl m} ddlm} |s2|dk dkr$tj| |||  ||  S ||d ||| d  S |||d ||| d  |dkftj| |||  ||  dfS r   r   r   r    r    r!   ru     s    ""z'FallingFactorial._eval_rewrite_as_gammac                 K   s   t || d |S r   )rfr   r    r    r!    _eval_rewrite_as_RisingFactorial  r   z1FallingFactorial._eval_rewrite_as_RisingFactorialc                 K   s   |j rt|t|| S d S r   r   r   r    r    r!   r        z*FallingFactorial._eval_rewrite_as_binomialc                 K   sl   ddl m} |jr2|jr4|t|t| |  |dkftj| t|| d  t| d  dfS d S d S r   r   r   r    r    r!   r     s   *z+FallingFactorial._eval_rewrite_as_factorialNc                 K   s   ddl m} |rA||tj}|tju r)tj| ||| jddd ||  S |tju rA||d ||| d jddd S | |jdddS r   )r*   r(   r   r   rM   r   r   r   r   r    r    r!   r     s   
*
&z+FallingFactorial._eval_rewrite_as_tractablec                 C   r   r   r   r}   r    r    r!   r~   &  r   z!FallingFactorial._eval_is_integerr   r   )r#   r$   r%   r&   r   rY   ru   r   r   r   r   r~   r    r    r    r!   r     s    >

4

r   c                   @   s   e Zd ZdZdddZedd Zedd Zd	d
 Zdd Z	dd Z
dddZd ddZdd Zdd Zdd Zd!ddZdS )"r   a1  Implementation of the binomial coefficient. It can be defined
    in two ways depending on its desired interpretation:

    .. math:: \binom{n}{k} = \frac{n!}{k!(n-k)!}\ \text{or}\
                \binom{n}{k} = \frac{(n)_k}{k!}

    First, in a strict combinatorial sense it defines the
    number of ways we can choose `k` elements from a set of
    `n` elements. In this case both arguments are nonnegative
    integers and binomial is computed using an efficient
    algorithm based on prime factorization.

    The other definition is generalization for arbitrary `n`,
    however `k` must also be nonnegative. This case is very
    useful when evaluating summations.

    For the sake of convenience, for negative integer `k` this function
    will return zero no matter the other argument.

    To expand the binomial when `n` is a symbol, use either
    ``expand_func()`` or ``expand(func=True)``. The former will keep
    the polynomial in factored form while the latter will expand the
    polynomial itself. See examples for details.

    Examples
    ========

    >>> from sympy import Symbol, Rational, binomial, expand_func
    >>> n = Symbol('n', integer=True, positive=True)

    >>> binomial(15, 8)
    6435

    >>> binomial(n, -1)
    0

    Rows of Pascal's triangle can be generated with the binomial function:

    >>> for N in range(8):
    ...     print([binomial(N, i) for i in range(N + 1)])
    ...
    [1]
    [1, 1]
    [1, 2, 1]
    [1, 3, 3, 1]
    [1, 4, 6, 4, 1]
    [1, 5, 10, 10, 5, 1]
    [1, 6, 15, 20, 15, 6, 1]
    [1, 7, 21, 35, 35, 21, 7, 1]

    As can a given diagonal, e.g. the 4th diagonal:

    >>> N = -4
    >>> [binomial(N, i) for i in range(1 - N)]
    [1, -4, 10, -20, 35]

    >>> binomial(Rational(5, 4), 3)
    -5/128
    >>> binomial(Rational(-5, 4), 3)
    -195/128

    >>> binomial(n, 3)
    binomial(n, 3)

    >>> binomial(n, 3).expand(func=True)
    n**3/6 - n**2/2 + n/3

    >>> expand_func(binomial(n, 3))
    n*(n - 2)*(n - 1)/6

    References
    ==========

    .. [1] https://www.johndcook.com/blog/binomial_coefficients/

    r'   c                 C   s   ddl m} |dkr$| j\}}t|||d|d |d|| d   S |dkrB| j\}}t|||d|| d |d|d   S t| |)Nr   )r)   r'   r7   )r*   r)   r+   r   r
   )r   r,   r)   r>   r   r    r    r!   r-     s   


zbinomial.fdiffc                 C   s   |j rl|j rM|dkrMt|t|}}||krtjS ||d kr$|| }tr.tt||S || d}}td|d D ]}|d7 }|| | }q<t|S || d}}td|d D ]
}|d7 }||9 }q[|t	| S d S )Nr   r7   r'   )
rN   r9   r   ri   r   r   r   bincoefrR   
_factorial)r   r>   r   rm   rV   rW   r    r    r!   r     s(   
zbinomial._evalc                 C   s  t t||f\}}|| }|j|j}}|js |s|du r#|jr#tjS |d js3|s.|du r5|d jr5|S |jrZ|jsB|rE|rE|jrEtjS |j	rX| 
||}|rV|jddS |S d S |du rc|rctjS |j	rddlm} ||d ||d ||| d   S d S )NFr'   T)basicr   rr   )rk   r   rf   re   rK   r   rL   rO   ri   	is_numberr   expandrP   r*   r(   )r=   r>   r   rm   n_nonnegn_isintr\   r(   r    r    r!   rY     s0   (zbinomial.evalc                 C   s  | j \}}tdd |||fD rtdtdd |||fD r^tt||f\}}t|d}}|dk r9tjS |dk rL| | d }|d rJdnd}||krStjS |j	}t|}|r||k r||}}|si|r|t
|| ||  | }|| || }}|si|sin|| }	||	kr|	|}}	d}
td|d D ]}|
| | }
q|
}t|d |	d D ]}|| | }q||9 }t|	d |d D ]}|| | }q|t|
| | |d |9 }||; }nxtt|}td|d D ]i}||| kr|| | }q||d krq||kr|| || k r|| | }q||}}d }}|dkrFt|| || | k }|| || }}||7 }|dks(|dkrW|t|||9 }||; }qt|| S d S )	Nc                 s   s    | ]}|j d u V  qdS )FN)re   .0r   r    r    r!   	<genexpr>  s    z%binomial._eval_Mod.<locals>.<genexpr>z"Integers expected for binomial Modc                 s   s    | ]}|j V  qd S r   )rN   r   r    r    r!   r     s    r'   r   r7   rc   )r+   anyr   allrk   r9   rg   r   ri   rj   r   rR   rZ   r:   r   r;   )r   rC   r>   r   rl   r\   rn   r?   Krm   kfrW   dfMrA   r   ar    r    r!   rp     sx   



	




zbinomial._eval_Modc                 K   s   | j d }|jrt| j  S | j d }|| jr|| }|jrJ|jr$tjS |jr*tjS | j d d}}t	d|d D ]
}||| | 9 }q9|t
| S t| j  S )z
        Function to expand binomial(n, k) when m is positive integer
        Also,
        n is self.args[0] and k is self.args[1] while using binomial(n, k)
        r   r'   )r+   rJ   r   rN   rK   r   rL   rO   ri   rR   r   )r   hintsr>   r   rV   rW   r    r    r!   _eval_expand_func  s    




zbinomial._eval_expand_funcc                 K   s   t |t |t ||   S r   )r   r   r>   r   r   r    r    r!   r   /  s   z#binomial._eval_rewrite_as_factorialTc                 K   s4   ddl m} ||d ||d ||| d   S rq   rs   )r   r>   r   rt   r   r(   r    r    r!   ru   2  s   (zbinomial._eval_rewrite_as_gammaNc                 K   s   |  ||dS )Nr   )ru   r   )r   r>   r   r   r   r    r    r!   r   6  r   z#binomial._eval_rewrite_as_tractablec                 K   s   |j rt||t| S d S r   )re   ffr   r   r    r    r!   r   9  r   z*binomial._eval_rewrite_as_FallingFactorialc                 C   s,   | j \}}|jr|jrdS |jdu rdS d S NTF)r+   re   r   r>   r   r    r    r!   r~   =  s   

zbinomial._eval_is_integerc                 C   sF   | j \}}|jr|jr|js|js|jrdS |jdu r!dS d S d S d S r   )r+   re   rf   rO   r   r   r    r    r!   r   D  s   

zbinomial._eval_is_nonnegativer   c                 C   s"   ddl m} | |j|||dS )Nr   rr   )r   r   )r*   r(   r   r   )r   r   r   r   r(   r    r    r!   r   L  s   zbinomial._eval_as_leading_termr   r   r   r   )r#   r$   r%   r&   r-   r   r   rY   rp   r   r   ru   r   r   r~   r   r   r    r    r    r!   r   3  s     
M

P

r   N)-typingr   	functoolsr   
sympy.corer   r   r   r   sympy.core.cacher   sympy.core.functionr	   r
   r   sympy.core.logicr   sympy.core.numbersr   r   r   sympy.core.relationalr   sympy.external.gmpyr   r   sympy.ntheoryr   sympy.polys.polytoolsr   mathr   r   r   r   r:   r   r   r   r   r   r   r   r   r   r    r    r    r!   <module>   s2     nbx " 