U
    9%e                     @  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 )    )annotations)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r8|S | S )Nr   )combsimpmeasureratio)Zsympy.simplify.combsimpr   )selfkwargsr   exprr    r   g/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/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U dZd>ddZdddddddddd	d
ddddddddddddddddddddddg!Zg Zded < 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d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd@d<d=Zd:S )Ar   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  sL   ddl m}m} |dkr>|| jd d |d| jd d  S t| |d S )Nr   )gamma	polygammar&   )'sympy.functions.special.gamma_functionsr'   r(   argsr
   )r   argindexr'   r(   r   r   r    fdiffT   s    &zfactorial.fdiff         #   i;  ?   i     i  i  i#  iS i{/  i! im  i isX iU iP
 ioik iIi/L iSi} i#z	list[int]_small_factorialsc           	      C  s   |dk r| j | S tt|g  }}td|d D ]J}d| }}|| }|dkrl|d@ dkrj||9 }qBqlqB|dkr4|| q4t|d |d d D ]}|| d@ dkr|| qtt|d d |d }t|}|| S d S )N!   r-   r&   r      )_small_swingint_sqrtr   
primerangeappendr   )	clsnNZprimesprimepqZ	L_productZ	R_productr   r   r    _swingc   s$    


zfactorial._swingc                 C  s,   |dk rdS |  |d d | | S d S )Nr5   r&   )
_recursiverA   )r;   r<   r   r   r    rB      s    zfactorial._recursivec                 C  s   t |}|jr|jrtjS |tjkr*tjS |jr|jr<tjS |j	}|dk r| j
sxd}tddD ]}||9 }| j
| q^| j
|d  }n4trt|}n$t|d}| |d||   }t|S d S )N   r&   1r5   )r   	is_Numberis_zeror   OneInfinity
is_Integeris_negativeComplexInfinityr?   r3   ranger:   r   r   ZfacbincountrB   r   )r;   r<   resultibitsr   r   r    eval   s,    
zfactorial.evalc                 C  s   dt t| }}dg| }d}td|d D ]b}|dkr`d||  }}|r`||7 }|| }qJ||k r~|| | | ||< q0|t||| | }q0t|D ]<\}	}
|	dks|
dkrq|
dkr dS |t|
|	| | }q|S )Nr&   r5   r   )r7   r8   r   r9   pow	enumerate)r   r<   r@   resr=   pwmr>   yexbsr   r   r    _facmod   s&    

zfactorial._facmodc                 C  s   | j d }|jr|jr|jrt|}|| }|jr8tjS |j}|dkrl|rRd| S |dkr|d jrtjS nv|jr|jrt	t
|||f\}}}|r|d |k r| |d |}t||d |}|d r| }n| ||}|| S d S )Nr   r&   F   r5   )r*   
is_integeris_nonnegativeabsZis_nonpositiver   Zerois_primerI   mapr7   r[   rS   )r   r@   r<   aqdisprimefcr   r   r    	_eval_Mod   s*    
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  s8   ddl m} |jr4|jr4tddd}|||d|fS d S )Nr   )ProductrP   T)integerr&   )Zsympy.concrete.productsrn   r_   r^   r   )r   r<   r   rn   rP   r   r   r    _eval_rewrite_as_Product   s    z"factorial._eval_rewrite_as_Productc                 C  s    | j d jr| j d jrdS d S Nr   Tr*   r^   r_   r   r   r   r    _eval_is_integer   s    zfactorial._eval_is_integerc                 C  s    | j d jr| j d jrdS d S rq   rr   rs   r   r   r    _eval_is_positive   s    zfactorial._eval_is_positivec                 C  s$   | j d }|jr |jr |d jS d S )Nr   r5   rr   r   xr   r   r    _eval_is_even   s    
zfactorial._eval_is_evenc                 C  s$   | j d }|jr |jr |d jS d S )Nr   r-   rr   rv   r   r   r    _eval_is_composite   s    
zfactorial._eval_is_compositec                 C  s   | j d }|js|jrdS d S rq   )r*   r_   Zis_nonintegerrv   r   r   r    _eval_is_real  s    
zfactorial._eval_is_realNr   c                 C  sH   | j d |}||d}|jr(tjS |js8| |S td|  d S )Nr   zCannot expand %s around 0)	r*   Zas_leading_termsubsrF   r   rG   is_infinitefuncr   )r   rw   logxcdirargZarg0r   r   r    _eval_as_leading_term  s    
zfactorial._eval_as_leading_term)r&   )T)Nr   )r"   r#   r$   r%   r,   r6   r3   __annotations__classmethodrA   rB   rR   r[   rh   rm   rp   rt   ru   rx   ry   rz   r   r   r   r   r    r   #   sj   
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] https://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  sR   |s
t jS |dkrt jS d\}}td|d D ]}||d ||   }}q.|S d S )Nr&   )r&   r   r5   )r   rG   ra   rL   )r   r<   Zz1Zz2rP   r   r   r    _eval>  s    zsubfactorial._evalc                 C  s@   |j r<|jr|jr| |S |tjkr,tjS |tjkr<tjS d S N)rE   rI   r_   r   r   NaNrH   )r;   r   r   r   r    rR   K  s    


zsubfactorial.evalc                 C  s    | j d jr| j d jrdS d S rq   )r*   is_oddr_   rs   r   r   r    rx   U  s    zsubfactorial._eval_is_evenc                 C  s    | j d jr| j d jrdS d S rq   rr   rs   r   r   r    rt   Y  s    zsubfactorial._eval_is_integerc                 K  s>   ddl m} td}tj| t| }t||||d|f S )Nr   )	summationrP   )Zsympy.concrete.summationsr   r   r   NegativeOner   )r   r   r   r   rP   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&   r\   )	Z&sympy.functions.elementary.exponentialr   r)   r'   r   r   r   r   r   )r   r   rl   r   r   r'   r   r   r   r    rm   c  s    ,
z#subfactorial._eval_rewrite_as_gammac                 K  s    ddl m} ||d dtj S )Nr   )
uppergammar&   r\   )r)   r   r   ZExp1)r   r   r   r   r   r   r    _eval_rewrite_as_uppergammai  s    z(subfactorial._eval_rewrite_as_uppergammac                 C  s    | j d jr| j d jrdS d S rq   rr   rs   r   r   r    _eval_is_nonnegativem  s    z!subfactorial._eval_is_nonnegativec                 C  s    | j d jr| j d jrdS d S rq   )r*   is_evenr_   rs   r   r   r    _eval_is_oddq  s    zsubfactorial._eval_is_oddN)T)r"   r#   r$   r%   r   r   r   rR   rx   rt   r   rm   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 rz|jstd|jrL|jr8|d }d| t| S t|t|d  S |jrr|tj	d| d   t|  S tdd S )Nz<argument must be nonnegative integer or negative odd integerr5   r&   )
rE   rI   
ValueErrorr_   r   r   r   r   r   r   )r;   r   kr   r   r    rR     s     zfactorial2.evalc                 C  s8   | j d }|jr4|jrdS |jr4|jr*dS |jr4dS d S )Nr   FT)r*   r^   r   r   is_positiverF   r   r<   r   r   r    rx     s    
zfactorial2._eval_is_evenc                 C  s2   | j d }|jr.|d jrdS |jr.|d jS d S )Nr   r&   Tr-   )r*   r^   r_   r   r   r   r   r    rt     s    

zfactorial2._eval_is_integerc                 C  s8   | j d }|jr|d jS |jr4|jr*dS |jr4dS d S )Nr   r-   FT)r*   r   r_   r   r   rF   r   r   r   r    r     s    

zfactorial2._eval_is_oddc                 C  s6   | j d }|jr2|d jrdS |jr2|d d jS d S )Nr   r&   Tr5   )r*   r^   r_   r   r   r   r   r   r    ru     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   	Piecewiserj   r5   r&   )	Z(sympy.functions.elementary.miscellaneousr   $sympy.functions.elementary.piecewiser   r)   r'   r   r   r   )r   r<   rl   r   r   r   r'   r   r   r    rm     s    .z!factorial2._eval_rewrite_as_gammaN)T)r"   r#   r$   r%   r   rR   rx   rt   r   ru   rm   r   r   r   r    r   v  s   %

r   c                   @  sP   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 )RisingFactorialap  
    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 https://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ks$|tjkr*tjS  tjkr<t|S |jr|jrPtjS |jr tjkrftjS  tj	kr|j
r|tj	S tjS n`t trȈ j}t|dkrtdqt fddtt|dS nt fddtt|dS n tjk rtjS  tj	kr
tjS t tr` j}t|dkr4tdn*dt fddtdtt|d d S n*dt fddtdtt|d d S |jdkr jr jrtjS d S )	Nr&   0rf only defined for polynomials on one generatorc                   s   |   | S r   shiftrrP   rw   r   r    <lambda>H  s    z&RisingFactorial.eval.<locals>.<lambda>c                   s   |  |  S r   r   r   r   r   r    r   L      c                   s   |   |  S r   r   r   r   r   r    r   [  s    c                   s   |  |  S r   r   r   r   r   r    r   _  s    F)r   r   r   rG   r   rI   rF   r   rH   NegativeInfinityr   
isinstancer   genslenr   r   rL   r7   r`   r^   rJ   ra   r;   rw   r   r   r   r   r    rR   ,  s^    





 
 
  zRisingFactorial.evalTc                 K  s   ddl m} ddlm} |sd|dkdkrPtj| |d|  || | d  S ||| || S |||| || |dkftj| |d|  || | d  dfS Nr   r   rj   Tr&   r   r   r)   r'   r   r   r   rw   r   rl   r   r   r'   r   r   r    rm   g  s    (*z&RisingFactorial._eval_rewrite_as_gammac                 K  s   t || d |S Nr&   )FallingFactorialr   rw   r   r   r   r   r    !_eval_rewrite_as_FallingFactorialr  s    z1RisingFactorial._eval_rewrite_as_FallingFactorialc                 K  sh   ddl m} |jrd|jrd|t|| d t|d  |dkftj| t|  t| |  dfS d S Nr   r   r&   Tr   r   r^   r   r   r   r   rw   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   r^   r   binomialr   r   r   r    _eval_rewrite_as_binomial|  s    z)RisingFactorial._eval_rewrite_as_binomialNc                 K  s   ddl m} |r||tj}|tjkrF||| jddd|| S |tjkrtj| |d|  || | d jddd S | |jdddS Nr   rj   	tractableT)deepr&   )r)   r'   r{   r   rH   rewriter   r   r   rw   r   limitvarr   r'   Zk_limr   r   r    _eval_rewrite_as_tractable  s    

2z*RisingFactorial._eval_rewrite_as_tractablec                 C  s&   t | jd j| jd j| jd jfS Nr   r&   r   r*   r^   r_   rs   r   r   r    rt     s    
z RisingFactorial._eval_is_integer)T)N)r"   r#   r$   r%   r   rR   rm   r   r   r   r   rt   r   r   r   r    r     s   =
:


r   c                   @  sP   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 )r   a0  
    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] https://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ks$|tjkr*tjS |jr@ |kr@t S |jr|jrTtjS |jr tj	krjtj	S  tj
kr|jrtj
S tj	S n`t tr̈ j}t|dkrtdqt fddtt|dS nt fddtt|dS n tj	k rtj	S  tj
krtj	S t trd j}t|dkr8tdn*dt fddtdtt|d d S n*dt fddtdtt|d d S d S )	Nr&   z0ff only defined for polynomials on one generatorc                   s   |   |  S r   r   r   r   r   r    r     s    z'FallingFactorial.eval.<locals>.<lambda>c                   s   |  |  S r   r   r   r   r   r    r     r   r   c                   s   |   | S r   r   r   r   r   r    r     s    c                   s   |  |  S r   r   r   r   r   r    r      r   )r   r   r   r^   r   rI   rF   rG   r   rH   r   r   r   r   r   r   r   r   rL   r7   r`   r   r   r   r    rR     sX    




 
 
  zFallingFactorial.evalTc                 K  s   ddl m} ddlm} |sd|dk dkrHtj| |||  ||  S ||d ||| d  S |||d ||| d  |dkftj| |||  ||  dfS r   r   r   r   r   r    rm     s     ""z'FallingFactorial._eval_rewrite_as_gammac                 K  s   t || d |S r   )rfr   r   r   r     _eval_rewrite_as_RisingFactorial  s    z1FallingFactorial._eval_rewrite_as_RisingFactorialc                 K  s   |j rt|t|| S d S r   r   r   r   r   r    r     s    z*FallingFactorial._eval_rewrite_as_binomialc                 K  sh   ddl m} |jrd|jrd|t|t| |  |dkftj| t|| d  t| d  dfS d S r   r   r   r   r   r    r     s    *z+FallingFactorial._eval_rewrite_as_factorialNc                 K  s   ddl m} |r||tj}|tjkrRtj| ||| jddd ||  S |tjkr||d ||| d jddd S | |jdddS r   )r)   r'   r{   r   rH   r   r   r   r   r   r   r    r     s    
*
&z+FallingFactorial._eval_rewrite_as_tractablec                 C  s&   t | jd j| jd j| jd jfS r   r   rs   r   r   r    rt   &  s    
z!FallingFactorial._eval_is_integer)T)N)r"   r#   r$   r%   r   rR   rm   r   r   r   r   rt   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rH| j\}}t|||d|d |d|| d   S |dkr| j\}}t|||d|| d |d|d   S t| |d S )Nr   )r(   r&   r5   )r)   r(   r*   r   r
   )r   r+   r(   r<   r   r   r   r    r,     s    

zbinomial.fdiffc                 C  s   |j r|j r|dkrt|t| }}||kr4tjS ||d krH|| }tr\tt||S || d }}td|d D ]}|d7 }|| | }qxt|S || d }}td|d D ]}|d7 }||9 }q|t	| S d S )Nr   r5   r&   )
rI   r7   r   ra   r   r   r   ZbincoefrL   
_factorial)r   r<   r   re   rO   rP   r   r   r    r     s&    
zbinomial._evalc                 C  s  t t||f\}}|| }|j|j }}|js@|s:|dkrF|jrFtjS |d jsf|s\|dkrj|d jrj|S |jr|js|r|r|jrtjS |j	r| 
||}|r|jddS |S nN|dkr|rtjS |j	r ddlm} ||d ||d ||| d   S d S )NFr&   T)basicr   rj   )rc   r   r_   r^   rF   r   rG   rJ   ra   Z	is_numberr   expandrK   r)   r'   )r;   r<   r   re   Zn_nonnegZn_isintrU   r'   r   r   r    rR     s,    zbinomial.evalc                 C  s  | j \}}tdd |||fD r*tdtdd |||fD rtt||f\}}t|d }}|dk rrtjS |dk r| | d }|d rdnd}||krtjS |j	}t|}|r||k r|| }}|s|r|t
|| ||  | }|| ||  }}qn|| }	||	kr$|	| }}	d}
td|d D ]}|
| | }
q6|
}t|d |	d D ]}|| | }q`||9 }t|	d |d D ]}|| | }q|t|
| | |d |9 }||; }ntt|}td|d D ]}||| kr|| | }n||d krqn||krB|| || k r|| | }nt|| }}d }}|dkrt|| || | k }|| ||  }}||7 }qT|dkr|t|||9 }||; }qt|| S d S )	Nc                 s  s   | ]}|j d kV  qdS )FN)r^   .0rw   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   )rI   r   r   r   r    r     s     r&   r   r5   r\   )r*   anyr   allrc   r7   r`   r   ra   rb   r   rL   rS   r8   r   r9   )r   r@   r<   r   rd   rU   rf   r=   Kre   ZkfrP   ZdfMr>   r   ar   r   r    rh     sl    






	



zbinomial._eval_Modc                 K  s   | j d }|jrt| j  S | j d }|| jr6|| }|jr|jrHtjS |jrTtjS | j d d }}t	d|d D ]}||| | 9 }qr|t
| S n
t| j  S d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&   N)r*   rE   r   rI   rF   r   rG   rJ   ra   rL   r   )r   hintsr<   r   rO   rP   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 ri   rk   )r   r<   r   rl   r   r'   r   r   r    rm   2  s    zbinomial._eval_rewrite_as_gammaNc                 K  s   |  ||dS )Nr   )rm   r   )r   r<   r   r   r   r   r   r    r   6  s    z#binomial._eval_rewrite_as_tractablec                 K  s   |j rt||t| S d S r   )r^   ffr   r   r   r   r    r   9  s    z*binomial._eval_rewrite_as_FallingFactorialc                 C  s,   | j \}}|jr|jrdS |jdkr(dS d S NTF)r*   r^   r   r<   r   r   r   r    rt   =  s
    

zbinomial._eval_is_integerc                 C  s>   | j \}}|jr:|jr:|js(|js(|jr,dS |jdkr:dS d S r   )r*   r^   r_   rJ   r   r   r   r   r    r   D  s    

zbinomial._eval_is_nonnegativer   c                 C  s"   ddl m} | |j|||dS )Nr   rj   )r~   r   )r)   r'   r   r   )r   rw   r~   r   r'   r   r   r    r   L  s    zbinomial._eval_as_leading_term)r&   )T)N)Nr   )r"   r#   r$   r%   r,   r   r   rR   rh   r   r   rm   r   r   rt   r   r   r   r   r   r    r   3  s   M


P

r   N)-
__future__r   	functoolsr   Z
sympy.corer   r   r   r   Zsympy.core.cacher   Zsympy.core.functionr	   r
   r   Zsympy.core.logicr   Zsympy.core.numbersr   r   r   Zsympy.core.relationalr   Zsympy.external.gmpyr   r   Zsympy.ntheoryr   Zsympy.polys.polytoolsr   mathr   r   r   r   r8   r   r   r   r   r   r   r   r   r   r   r   r   r    <module>   s0    nbx " 