o
    GZh                     @  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)DefinedFunction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)Zsympy.simplify.combsimpr   )selfkwargsr   exprr    r   W/var/www/auris/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" 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-         #   r0   i;  ?   i     i  i  #  r3   iS i{/  i! im  i isX iU iP
 ioik iIi/L iSi} #r4   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NZprimesprimepqZ	L_productZ	R_productr   r   r    _swingd   s.   

	

zfactorial._swingc                 C  s(   |dk rdS |  |d d | | S )Nr7   r&   )
_recursiverC   )r=   r>   r   r   r    rD      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&   1r7   )r   	is_Numberis_zeror   OneInfinity
is_Integeris_negativeComplexInfinityrA   r5   ranger<   _gmpyZfacbincountrD   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>   rB   resr?   pwmr@   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absZis_nonpositiver   Zerois_primerK   mapr9   r^   rV   )r   rB   r>   aqdisprimeZ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   )ProductrS   T)integerr&   )Zsympy.concrete.productsrp   rb   ra   r   )r   r>   r   rp   rS   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*   ra   rb   r   r   r   r    _eval_is_integer      zfactorial._eval_is_integerc                 C  rs   rt   ru   rv   r   r   r    _eval_is_positive   rx   zfactorial._eval_is_positivec                 C  (   | j d }|jr|jr|d jS d S d S )Nr   r7   ru   r   xr   r   r    _eval_is_even     

zfactorial._eval_is_evenc                 C  rz   )Nr   r-   ru   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 rt   )r*   rb   Zis_nonintegerr{   r   r   r    _eval_is_real  s   
zfactorial._eval_is_realc                 C  sD   | j d |}||d}|jrtjS |js| |S td|  )Nr   zCannot expand %s around 0)	r*   Zas_leading_termsubsrH   r   rI   is_infinitefuncr   )r   r|   logxcdirargZarg0r   r   r    _eval_as_leading_term  s   
zfactorial._eval_as_leading_termNr&   T)r"   r#   r$   r%   r,   r8   r5   __annotations__classmethodrC   rD   rU   r^   rj   ro   rr   rw   ry   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   r7   )r   rI   rd   rN   )r   r>   Zz1Zz2rS   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)rG   rK   rb   r   r   NaNrJ   )r=   r   r   r   r    rU   T  s   


zsubfactorial.evalc                 C  rs   rt   )r*   is_oddrb   rv   r   r   r    r}   ^  rx   zsubfactorial._eval_is_evenc                 C  rs   rt   ru   rv   r   r   r    rw   b  rx   zsubfactorial._eval_is_integerc                 K  s>   ddl m} td}tj| t| }t||||d|f S )Nr   )	summationrS   )Zsympy.concrete.summationsr   r   r   NegativeOner   )r   r   r   r   rS   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&   r_   )	Z&sympy.functions.elementary.exponentialr   r)   r'   r   r   r   r   r   )r   r   rn   r   r   r'   r   r   r   r    ro   l  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_uppergammar  s   z(subfactorial._eval_rewrite_as_uppergammac                 C  rs   rt   ru   rv   r   r   r    _eval_is_nonnegativev  rx   z!subfactorial._eval_is_nonnegativec                 C  rs   rt   )r*   is_evenrb   rv   r   r   r    _eval_is_oddz  rx   zsubfactorial._eval_is_oddNr   )r"   r#   r$   r%   r   r   r   rU   r}   rw   r   ro   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&   )
rG   rK   
ValueErrorrb   r   r   r   r   r   r   )r=   r   kr   r   r    rU     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*   ra   r   r   is_positiverH   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*   ra   rb   r   r   r   r   r    rw     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   rb   r   r   rH   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*   ra   rb   r   r   r   r   r   r    ry     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   	Piecewiserl   r7   r&   )	Z(sympy.functions.elementary.miscellaneousr   $sympy.functions.elementary.piecewiser   r)   r'   r   r   r   )r   r>   rn   r   r   r   r'   r   r   r    ro     s   .z!factorial2._eval_rewrite_as_gammaNr   )r"   r#   r$   r%   r   rU   r}   rw   r   ry   ro   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rrS   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   rI   r   rK   rH   r   rJ   NegativeInfinityr   
isinstancer   genslenr   r   rN   r9   rc   ra   rL   rd   r=   r|   r   r   r   r   r    rU   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   rl   Tr&   r   r   r)   r'   r   r   r   r|   r   rn   r   r   r'   r   r   r    ro   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   ra   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   ra   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   rl   	tractableT)deepr&   )r)   r'   r   r   rJ   rewriter   r   r   r|   r   limitvarr   r'   Z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*   ra   rb   rv   r   r   r    rw        
z RisingFactorial._eval_is_integerr   r   )r"   r#   r$   r%   r   rU   ro   r   r   r   r   rw   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   ra   r   rK   rH   rI   r   rJ   r   r   r   r   r   r   r   r   rN   r9   rc   r   r   r   r    rU     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    ro     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   rJ   r   r   r   r   r   r   r    r   %  s   
*
&z+FallingFactorial._eval_rewrite_as_tractablec                 C  r   r   r   rv   r   r   r    rw   /  r   z!FallingFactorial._eval_is_integerr   r   )r"   r#   r$   r%   r   rU   ro   r   r   r   r   rw   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 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&   r7   )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   r7   r&   )	rK   r9   r   rd   rO   r   ZbincoefrN   
_factorial)r   r>   r   rh   rR   rS   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   rl   )rf   r   rb   ra   rH   r   rI   rL   rd   Z	is_numberr   expandrM   r)   r'   )r=   r>   r   rh   Zn_nonnegZn_isintrX   r'   r   r   r    rU     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)ra   .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   )rK   r   r   r   r    r     s    r&   r   r7   r_   )r*   anyr   allrf   r9   rc   r   rd   re   r   rN   rV   r:   r   r   r;   )r   rB   r>   r   rg   rX   ri   r?   Krh   ZkfrS   ZdfMr@   r   ar   r   r    rj     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*   rG   r   rK   rH   r   rI   rL   rd   rN   r   )r   hintsr>   r   rR   rS   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 rk   rm   )r   r>   r   rn   r   r'   r   r   r    ro   Q  s   (zbinomial._eval_rewrite_as_gammaNc                 K  s   |  ||dS )Nr   )ro   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   )ra   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*   ra   r   r>   r   r   r   r    rw   \  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*   ra   rb   rL   r   r   r   r   r    r   c  s   

zbinomial._eval_is_nonnegativec                 C  s"   ddl m} | |j|||dS )Nr   rl   )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   rU   rj   r   r   ro   r   r   rw   r   r   r   r   r   r    r   <  s     
]

S

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   rO   Zsympy.ntheoryr   Zsympy.ntheory.residue_ntheoryr   Z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 " 