o
    g                     @  sL  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 d d
l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)gmpy)sieve)binomial_mod)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    _/var/www/visachat/venv/lib/python3.10/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g d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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!   fdiffU   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   z	list[int]_small_factorialsc           	      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!   _swingd   s.   

	

zfactorial._swingc                 C  s(   |dk rdS |  |d d | | S )Nr8   r'   )
_recursiverG   )r>   r?   r    r    r!   rH      s   zfactorial._recursivec                 C  s   t |}|jrj|jrtjS |tju rtjS |jrl|jrtjS |j	}|dk rG| j
s<d}tddD ]}||9 }| j
| q/| j
|d  }t|S td urTt|}t|S t|d}| |d||   }t|S d S d S )N   r'   1r8   )r   	is_Numberis_zeror   OneInfinity
is_Integeris_negativeComplexInfinityrC   r6   ranger=   _gmpyfacbincountrH   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'   r8   r   )r:   r;   r   r<   pow	enumerate)r   r?   rD   resr@   pwmrB   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   r8   )r+   
is_integeris_nonnegativeabsis_nonpositiver   Zerois_primerO   mapr:   rc   r[   )r   rD   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   )ProductrX   T)integerr'   )sympy.concrete.productsrw   rg   rf   r   )r   r?   r   rw   rX   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+   rf   rg   r   r    r    r!   _eval_is_integer      zfactorial._eval_is_integerc                 C  r{   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   r8   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+   rg   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subsrL   r   rM   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-   r9   r6   __annotations__classmethodrG   rH   rZ   rc   rq   rv   rz   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] 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  sN   |st jS |dkrt jS d\}}td|d D ]}||d ||  }}q|S )Nr'   )r'   r   r8   )r   rM   rj   rR   )r   r?   z1z2rX   r    r    r!   _evalG  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)rK   rO   rg   r   r   NaNrN   )r>   r   r    r    r!   rZ   T  s   


zsubfactorial.evalc                 C  r{   r|   )r+   is_oddrg   r~   r    r    r!   r   ^  r   zsubfactorial._eval_is_evenc                 C  r{   r|   r}   r~   r    r    r!   r   b  r   zsubfactorial._eval_is_integerc                 K  s>   ddl m} td}tj| t| }t||||d|f S )Nr   )	summationrX   )sympy.concrete.summationsr   r   r   NegativeOner   )r   r   r   r   rX   fr    r    r!   _eval_rewrite_as_factorialf  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'   rd   )	&sympy.functions.elementary.exponentialr   r*   r(   r   r   r   r   r   )r   r   ru   r   r   r(   r   r    r    r!   rv   l  s   ,
z#subfactorial._eval_rewrite_as_gammac                 K  s    ddl m} ||d dtj S )Nr   )
uppergammar'   rd   )r*   r   r   Exp1)r   r   r   r   r    r    r!   _eval_rewrite_as_uppergammar  s   z(subfactorial._eval_rewrite_as_uppergammac                 C  r{   r|   r}   r~   r    r    r!   _eval_is_nonnegativev  r   z!subfactorial._eval_is_nonnegativec                 C  r{   r|   )r+   is_evenrg   r~   r    r    r!   _eval_is_oddz  r   zsubfactorial._eval_is_oddNr   )r#   r$   r%   r&   r   r   r   rZ   r   r   r   rv   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 integerr8   r'   )
rK   rO   
ValueErrorrg   r   r   r   r   r   r   )r>   r   kr    r    r!   rZ     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+   rf   r   r   is_positiverL   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+   rf   rg   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   rg   r   r   rL   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'   Tr8   )r+   rf   rg   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   	Piecewisers   r8   r'   )	(sympy.functions.elementary.miscellaneousr   $sympy.functions.elementary.piecewiser   r*   r(   r   r   r   )r   r?   ru   r   r   r   r(   r    r    r!   rv     s   .z!factorial2._eval_rewrite_as_gammaNr   )r#   r$   r%   r&   r   rZ   r   r   r   r   rv   r    r    r    r!   r     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 )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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rrX   r   r    r!   <lambda>Q     z&RisingFactorial.eval.<locals>.<lambda>c                      |  |  S r   r    r   r   r    r!   r   U      c                      |   |  S r   r   r   r   r    r!   r   d     c                      |  |  S r   r    r   r   r    r!   r   h  s   F)r   r   r   rM   r   rO   rL   r   rN   NegativeInfinityr   
isinstancer   genslenr   r   rR   r:   rh   rf   rP   rj   r>   r   r   r   r    r   r!   rZ   5  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   rs   Tr'   r   r   r*   r(   r   r   r   r   r   ru   r   r   r(   r    r    r!   rv   p  s   (*z&RisingFactorial._eval_rewrite_as_gammac                 K  s   t || d |S Nr'   )FallingFactorialr   r   r   r   r    r    r!   !_eval_rewrite_as_FallingFactorial{     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   rf   r   r   r   r   r   r   r   r   r    r    r!   r   ~  s   "$z*RisingFactorial._eval_rewrite_as_factorialc                 K  s$   |j rt|t|| d | S d S r   rf   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   rs   	tractableT)deepr'   )r*   r(   r   r   rN   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+   rf   rg   r~   r    r    r!   r        
z RisingFactorial._eval_is_integerr   r   )r#   r$   r%   r&   r   rZ   rv   r   r   r   r   r   r    r    r    r!   r     s    =

:

r   c                   @  r   )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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   rf   r   rO   rL   rM   r   rN   r   r   r   r   r   r   r   r   rR   r:   rh   r   r    r   r!   rZ     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!   rv     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   rN   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   rZ   rv   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   a  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

    In many cases, we can also compute binomial coefficients modulo a
    prime p quickly using Lucas' Theorem [2]_, though we need to include
    `evaluate=False` to postpone evaluation:

    >>> from sympy import Mod
    >>> Mod(binomial(156675, 4433, evaluate=False), 10**5 + 3)
    28625

    Using a generalisation of Lucas's Theorem given by Granville [3]_,
    we can extend this to arbitrary n:

    >>> Mod(binomial(10**18, 10**12, evaluate=False), (10**5 + 3)**2)
    3744312326

    References
    ==========

    .. [1] https://www.johndcook.com/blog/binomial_coefficients/
    .. [2] https://en.wikipedia.org/wiki/Lucas%27s_theorem
    .. [3] Binomial coefficients modulo prime powers, Andrew Granville,
        Available: https://web.archive.org/web/20170202003812/http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf
    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'   r8   )r*   r)   r+   r   r
   )r   r,   r)   r?   r   r    r    r!   r-     s   


zbinomial.fdiffc                 C  s   |j rn|j rO|dkrOt|t|}}||krtjS ||d kr$|| }td ur0t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   r8   r'   )	rO   r:   r   rj   rS   r   bincoefrR   
_factorial)r   r?   r   rn   rW   rX   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   rs   )rl   r   rg   rf   rL   r   rM   rP   rj   	is_numberr   expandrQ   r*   r(   )r>   r?   r   rn   n_nonnegn_isintr]   r(   r    r    r!   rZ     s0   (zbinomial.evalc                 C  s  | j \}}tdd |||fD rtdtdd |||fD rpt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 }||; }nt||k r|dkrt|||}nytt|}td|d D ]j}||| kr|| | }q||d krq||kr,|| || k r+|| | }q||}}d }}|dkrXt|| || | k }|| || }}||7 }|dks:|dkri|t|||9 }||; }qt|| S d S )	Nc                 s  s    | ]}|j d u V  qdS )FN)rf   .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   )rO   r   r    r    r!   r     s    r'   r   r8   rd   )r+   anyr   allrl   r:   rh   r   rj   rk   r   rR   r[   r;   r   r   r<   )r   rD   r?   r   rm   r]   ro   r@   Krn   kfrX   dfMrB   r   ar    r    r!   rq     s|   



	




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+   rK   r   rO   rL   r   rM   rP   rj   rR   r   )r   hintsr?   r   rW   rX   r    r    r!   _eval_expand_func3  s    




zbinomial._eval_expand_funcc                 K  s   t |t |t ||   S r   )r   r   r?   r   r   r    r    r!   r   N  s   z#binomial._eval_rewrite_as_factorialTc                 K  s4   ddl m} ||d ||d ||| d   S rr   rt   )r   r?   r   ru   r   r(   r    r    r!   rv   Q  s   (zbinomial._eval_rewrite_as_gammaNc                 K  s   |  ||dS )Nr   )rv   r   )r   r?   r   r   r   r    r    r!   r   U  r   z#binomial._eval_rewrite_as_tractablec                 K  s   |j rt||t| S d S r   )rf   ffr   r   r    r    r!   r   X  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+   rf   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+   rf   rg   rP   r   r   r    r    r!   r   c  s   

zbinomial._eval_is_nonnegativer   c                 C  s"   ddl m} | |j|||dS )Nr   rs   )r   r   )r*   r(   r   r   )r   r   r   r   r(   r    r    r!   r   k  s   zbinomial._eval_as_leading_termr   r   r   r   )r#   r$   r%   r&   r-   r   r   rZ   rq   r   r   rv   r   r   r   r   r   r    r    r    r!   r   <  s     
]

S

r   N)/
__future__r   	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   rS   sympy.ntheoryr   sympy.ntheory.residue_ntheoryr   sympy.polys.polytoolsr   mathr   r   r   r   r;   r   r   r   r   r   r   r   r   r   r    r    r    r!   <module>   s4     vbx " 