
    \h                    |   S SK Jr  S SKJr  S SKJrJrJrJr  S SK	J
r
  S SKJrJrJr  S SKJr  S SKJrJrJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJr  S SK J!r"J#r#J$r%   " S S\5      r& " S S\&5      r! " S S\&5      r' " S S\&5      r( " S S\&5      r) " S S\&5      r* " S S\&5      r+\*r,\+r- " S S\&5      r.g)    )annotations)reduce)SsympifyDummyMod)cacheit)DefinedFunctionArgumentIndexError	PoleError)	fuzzy_and)IntegerpiI)Eq)gmpy)sieve)binomial_mod)Poly)	factorialprodsqrtc                      \ rS rSrSrS rSrg)CombinatorialFunction   z(Base class for combinatorial functions. c                `    SSK Jn  U" U 5      nUS   nU" U5      US   U" U 5      -  ::  a  U$ U $ )Nr   )combsimpmeasureratio)sympy.simplify.combsimpr   )selfkwargsr   exprr   s        `/var/www/auris/envauris/lib/python3.13/site-packages/sympy/functions/combinatorial/factorials.py_eval_simplify$CombinatorialFunction._eval_simplify   s=    4 ~#4=F7OGDM99K     N)__name__
__module____qualname____firstlineno____doc__r%   __static_attributes__r(   r'   r$   r   r      s
    2r'   r   c                      \ rS rSr% SrSS jr/ SQr/ rS\S'   \	S 5       r
\	S 5       r\	S	 5       rS
 rS rSS jrS rS rS rS rS rS rS rSrg)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                    SSK JnJn  US:X  a2  U" U R                  S   S-   5      U" SU R                  S   S-   5      -  $ [	        X5      e)Nr   )gamma	polygamma   )'sympy.functions.special.gamma_functionsr2   r3   argsr   )r!   argindexr2   r3   s       r$   fdifffactorial.fdiffU   sH    Nq=1)*9Q		!q8H+III$T44r'   )!r4   r4   r4      r:         #   r=   i;  ?   i     i  i  #  r@   iS i{/  i! im  i isX iU iP
 ioik iIi/L iSi} #rA   z	list[int]_small_factorialsc                   US:  a  U R                   U   $ [        [        U5      5      / p2[        R                  " SUS-   5       H;  nSUpe Xd-  nUS:  a  US-  S:X  a  XT-  nOOM  US:  d  M*  UR                  U5        M=     [        R                  " US-   US-  S-   5       H!  nX-  S-  S:X  d  M  UR                  U5        M#     [        [        R                  " US-  S-   US-   5      5      n[        U5      nXx-  $ )N!   r:   r4   r      )_small_swingint_sqrtr   
primerangeappendr   )	clsnNprimesprimepq	L_product	R_products	            r$   _swingfactorial._swingd   s   r6##A&&E!Hrv))!QU3!1KA1uq5A:JA  q5MM!$ 4 ))!a%A:J!#q(MM%( ; U--adQhA>?IVI&&r'   c                b    US:  a  gU R                  US-  5      S-  U R                  U5      -  $ )NrE   r4   )
_recursiverT   )rK   rL   s     r$   rW   factorial._recursive   s1    q5NN1a4(!+SZZ]::r'   c                   [        U5      nUR                  (       Ga=  UR                  (       a  [        R                  $ U[        R
                  L a  [        R
                  $ UR                  (       a  UR                  (       a  [        R                  $ UR                  nUS:  aX  U R                  (       d4  Sn[        SS5       H"  nX#-  nU R                  R                  U5        M$     U R                  US-
     nOQ[        b  [        R                  " U5      nO3[        U5      R!                  S5      nU R#                  U5      SX-
  -  -  n[%        U5      $ g g )N   r4   1rE   )r   	is_Numberis_zeror   OneInfinity
is_Integeris_negativeComplexInfinityrP   rB   rangerJ   _gmpyfacbincountrW   r   )rK   rL   resultibitss        r$   evalfactorial.eval   s   AJ;;;yyuuajjzz!==,,,A2v"44%&F%*1b\ & # 5 5 < <V D &2 "%!6!6qs!; *!&1  #1v||C0!$!21qx=!@"6?*=  r'   c                   S[        [        U5      5      pCS/U-  nSn[        R                  " SUS-   5       HK  nUS:  a  SX-  pU(       a  Xh-  nX-  nU(       a  M  Xd:  a  XV   U-  U-  XV'   M9  U[	        XvU5      -  U-  nMM     [        U5       H-  u  pU	S:X  d  U
S:X  a  M  U
S:X  a    gU[	        XU5      -  U-  nM/     U$ )Nr4   rE   r   )rG   rH   r   rI   pow	enumerate)r!   rL   rQ   resrM   pwmrO   yexbss              r$   _facmodfactorial._facmod   s    CaMQ SU%%aQ/E1u!*1FAKA a uea#e**Q. 0  mFBQw"'Qwc"!n$q(C $ 
r'   c                   U R                   S   nUR                  (       Ga2  UR                  (       Ga  UR                  (       Ga  [        U5      nX2-
  nUR                  (       a  [
        R                  $ UR                  nUS:X  a7  U(       a  SU-  $ USL a%  US-
  R                  (       a  [
        R                  $ g g UR                  (       a  UR                  (       ao  [        [        X$U45      u  p$nU(       a>  US-
  U:  a5  U R                  US-
  U5      n[        XcS-
  U5      nUS-  (       a  U* nXa-  $ U R                  X#5      nXa-  $ g g g g g )Nr   r4   F   rE   )r6   
is_integeris_nonnegativeabsis_nonpositiver   Zerois_primer`   maprG   rv   rn   )r!   rQ   rL   aqdisprimefcs          r$   	_eval_Modfactorial._eval_Mod   s"   IIaL<<<A,,,QBAvv++6
 !Av E)rAv.E.E vv /F)\\all"3r
3HA"AEAI!\\!a%4 !VR0Q3"$B 6M "\\!06M '3\! 2>,<r'   c                $    SSK Jn  U" US-   5      $ Nr   r2   r4   r5   r2   )r!   rL   	piecewiser"   r2   s        r$   _eval_rewrite_as_gamma factorial._eval_rewrite_as_gamma   s    AQU|r'   c                    SSK Jn  UR                  (       a'  UR                  (       a  [	        SSS9nU" XDSU45      $ g g )Nr   )Productri   T)integerr4   )sympy.concrete.productsr   r|   r{   r   )r!   rL   r"   r   ri   s        r$   _eval_rewrite_as_Product"factorial._eval_rewrite_as_Product   s9    3c4(A1!Qi(( !-r'   c                    U R                   S   R                  (       a   U R                   S   R                  (       a  gg g Nr   Tr6   r{   r|   r!   s    r$   _eval_is_integerfactorial._eval_is_integer   /    99Q<""tyy|'B'B (C"r'   c                    U R                   S   R                  (       a   U R                   S   R                  (       a  gg g r   r   r   s    r$   _eval_is_positivefactorial._eval_is_positive   r   r'   c                    U R                   S   nUR                  (       a!  UR                  (       a  US-
  R                  $ g g )Nr   rE   r   r!   xs     r$   _eval_is_evenfactorial._eval_is_even  5    IIaL<<A,,E))) -<r'   c                    U R                   S   nUR                  (       a!  UR                  (       a  US-
  R                  $ g g )Nr   r:   r   r   s     r$   _eval_is_compositefactorial._eval_is_composite  r   r'   c                h    U R                   S   nUR                  (       d  UR                  (       a  gg r   )r6   r|   is_nonintegerr   s     r$   _eval_is_realfactorial._eval_is_real  s&    IIaLq  /r'   c                   U R                   S   R                  U5      nUR                  US5      nUR                  (       a  [        R
                  $ UR                  (       d  U R                  U5      $ [        SU -  5      e)Nr   zCannot expand %s around 0)	r6   as_leading_termsubsr]   r   r^   is_infinitefuncr   )r!   r   logxcdirargarg0s         r$   _eval_as_leading_termfactorial._eval_as_leading_term  sa    iil**1-xx1~<<55L!!99S>!3t<==r'   r(   Nr4   T)r)   r*   r+   r,   r-   r8   rF   rB   __annotations__classmethodrT   rW   rk   rv   r   r   r   r   r   r   r   r   r   r.   r(   r'   r$   r   r   $   s    .`5L $&y%' '< ; ; &+ &+P<"<)*
*

>r'   r   c                      \ rS rSrSrg)MultiFactoriali  r(   N)r)   r*   r+   r,   r.   r(   r'   r$   r   r     s    r'   r   c                  p    \ rS rSrSr\\S 5       5       r\S 5       rS r	S r
S rSS jrS	 rS
 rS rSrg)subfactoriali  a<  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                    U(       d  [         R                  $ US:X  a  [         R                  $ Su  p#[        SUS-   5       H  nX4S-
  X2-   -  p2M     U$ )Nr4   )r4   r   rE   )r   r^   r   rc   )r!   rL   z1z2ri   s        r$   _evalsubfactorial._evalG  sP     55L!V66MFB1a!e_!ebg.B %Ir'   c                   UR                   (       az  UR                  (       a"  UR                  (       a  U R                  U5      $ U[        R
                  L a  [        R
                  $ U[        R                  L a  [        R                  $ g g N)r\   r`   r|   r   r   NaNr_   )rK   r   s     r$   rk   subfactorial.evalT  sZ    ==~~#"4"4yy~%uu

"zz! # r'   c                    U R                   S   R                  (       a   U R                   S   R                  (       a  gg g r   )r6   is_oddr|   r   s    r$   r   subfactorial._eval_is_even^  s.    99Q<499Q<#>#> $?r'   c                    U R                   S   R                  (       a   U R                   S   R                  (       a  gg g r   r   r   s    r$   r   subfactorial._eval_is_integerb  r   r'   c                    SSK Jn  [        S5      n[        R                  U-  [        U5      -  n[        U5      U" XTSU45      -  $ )Nr   )	summationri   )sympy.concrete.summationsr   r   r   NegativeOner   )r!   r   r"   r   ri   fs         r$   _eval_rewrite_as_factorial'subfactorial._eval_rewrite_as_factorialf  s?    7#JMM1y|+~	!C[ 999r'   c                    SSK Jn  SSKJnJn  [
        R                  US-   -  U" [        * [        -  U-  5      -  U" US-   S5      -  U" US-   5      -   U" S5      -  $ )Nr   )exp)r2   
lowergammar4   ry   )	&sympy.functions.elementary.exponentialr   r5   r2   r   r   r   r   r   )r!   r   r   r"   r   r2   r   s          r$   r   #subfactorial._eval_rewrite_as_gammal  s\    >Oa(aRU3Y7
37B8OOa.!"%b'* 	*r'   c                H    SSK Jn  U" US-   S5      [        R                  -  $ )Nr   )
uppergammar4   ry   )r5   r   r   Exp1)r!   r   r"   r   s       r$   _eval_rewrite_as_uppergamma(subfactorial._eval_rewrite_as_uppergammar  s    F#'2&qvv--r'   c                    U R                   S   R                  (       a   U R                   S   R                  (       a  gg g r   r   r   s    r$   _eval_is_nonnegative!subfactorial._eval_is_nonnegativev  r   r'   c                    U R                   S   R                  (       a   U R                   S   R                  (       a  gg g r   )r6   is_evenr|   r   s    r$   _eval_is_oddsubfactorial._eval_is_oddz  s/    99Q<DIIaL$?$? %@r'   r(   Nr   )r)   r*   r+   r,   r-   r   r	   r   rk   r   r   r   r   r   r   r   r.   r(   r'   r$   r   r     s[    'R 	  	 " ":*.r'   r   c                  J    \ rS rSrSr\S 5       rS rS rS r	S r
SS jrS	rg
)
factorial2i  a  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                   UR                   (       a  UR                  (       d  [        S5      eUR                  (       aA  UR                  (       a  US-  nSU-  [        U5      -  $ [        U5      [        US-
  5      -  $ UR                  (       a)  U[        R                  SU-
  S-  -  -  [        U* 5      -  $ [        S5      eg )Nz<argument must be nonnegative integer or negative odd integerrE   r4   )
r\   r`   
ValueErrorr|   r   r   r   r   r   r   )rK   r   ks      r$   rk   factorial2.eval  s     ==>>  "> ? ?
 !!;;aAa4)A,.. ~
37(;;; zzAMMa#gq[99Jt<LLL : ; ;! r'   c                    U R                   S   nUR                  (       aI  UR                  (       a  gUR                  (       a%  UR                  (       a  gUR
                  (       a  gg g g )Nr   FT)r6   r{   r   r   is_positiver]   r!   rL   s     r$   r   factorial2._eval_is_even  sJ    IIaL<<xxyy==99    r'   c                    U R                   S   nUR                  (       a6  US-   R                  (       a  gUR                  (       a  US-   R                  $ g g )Nr   r4   Tr:   )r6   r{   r|   r   r   s     r$   r   factorial2._eval_is_integer  sI     IIaL<<A%%xxA---  r'   c                    U R                   S   nUR                  (       a  US-   R                  $ UR                  (       a%  UR                  (       a  gUR
                  (       a  gg g )Nr   r:   FT)r6   r   r|   r   r   r]   r   s     r$   r   factorial2._eval_is_odd  sM     IIaL88E)))99}}yy  r'   c                    U R                   S   nUR                  (       a9  US-   R                  (       a  gUR                  (       a  US-   S-  R                  $ g g )Nr   r4   TrE   )r6   r{   r|   r   r   r   s     r$   r   factorial2._eval_is_positive  sM     IIaL<<A%%xxQ!,,,  r'   c                    SSK Jn  SSKJn  SSKJn  SUS-  -  U" US-  S-   5      -  U" S[        [        US5      S5      4U" S[        -  5      [        [        US5      S5      45      -  $ )Nr   )r   	Piecewiser   rE   r4   )	(sympy.functions.elementary.miscellaneousr   $sympy.functions.elementary.piecewiser   r5   r2   r   r   r   )r!   rL   r   r"   r   r   r2   s          r$   r   !factorial2._eval_rewrite_as_gamma  si    ABA1Q3xacAg&Ar#a)Q7G3HadRAq	1-.*0 0 	0r'   r(   Nr   )r)   r*   r+   r,   r-   r   rk   r   r   r   r   r   r.   r(   r'   r$   r   r     s5    #J ; ;.
!.
	-0r'   r   c                  T    \ rS rSrSr\S 5       rSS jrS rS r	S r
SS	 jrS
 rSrg)RisingFactoriali  a  
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                  ^ [        T5      m[        U5      nT[        R                  L d  U[        R                  L a  [        R                  $ T[        R                  L a  [	        U5      $ UR
                  (       Ga  UR                  (       a  [        R                  $ UR                  (       a  T[        R                  L a  [        R                  $ T[        R                  L a1  UR                  (       a  [        R                  $ [        R                  $ [        T[        5      (       aI  TR                  n[        U5      S:w  a  [        S5      e[!        U4S j[#        [%        U5      5      S5      $ [!        U4S j[#        [%        U5      5      S5      $ T[        R                  L a  [        R                  $ T[        R                  L a  [        R                  $ [        T[        5      (       aY  TR                  n[        U5      S:w  a  [        S5      eS[!        U4S j[#        S['        [%        U5      5      S-   5      S5      -  $ S[!        U4S j[#        S['        [%        U5      5      S-   5      S5      -  $ UR(                  S:X  a4  TR(                  (       a"  TR*                  (       a  [        R,                  $ g g g )Nr4   0rf only defined for polynomials on one generatorc                ,   > U TR                  U5      -  $ r   shiftrri   r   s     r$   <lambda>&RisingFactorial.eval.<locals>.<lambda>Q  s    ./nr'   c                   > U TU-   -  $ r   r(   r  s     r$   r  r  U      q!a%yr'   c                .   > U TR                  U* 5      -  $ r   r   r  s     r$   r  r  d  s    01177A2;r'   c                   > U TU-
  -  $ r   r(   r  s     r$   r  r  h  s    ,-q1uIr'   F)r   r   r   r^   r   r`   r]   r   r_   NegativeInfinityr   
isinstancer   genslenr   r   rc   rG   r}   r{   ra   r   rK   r   r   r  s    `  r$   rk   RisingFactorial.eval5  s"   AJAJ:aee55L!%%ZQ<\\\yyuu==AJJ zz)a00088#$#5#55#$::-%a..#$66D"4y1}&0 2K 'L !L (. /=.3CFmQ(@ !@ $**@*/A-$< < AJJ zz)a000 zz)%a..#$66D"4y1}&0 2K 'L !L () 1@05aSVq0I1*N (N !N $%V -6,1!SQ[1_,Eq&J $J J <<5 ||vv !.| !r'   c                Z   SSK Jn  SSKJn  U(       dK  US:*  S:X  a/  [        R
                  U-  U" SU-
  5      -  U" U* U-
  S-   5      -  $ U" X-   5      U" U5      -  $ U" U" X-   5      U" U5      -  US:  4[        R
                  U-  U" SU-
  5      -  U" U* U-
  S-   5      -  S45      $ Nr   r   r   Tr4   r   r   r5   r2   r   r   r!   r   r   r   r"   r   r2   s          r$   r   &RisingFactorial._eval_rewrite_as_gammap  s    BAQ4}}a'a!e4uaR!VaZ7HHH<%(**15\E!H$a!e,]]AeAEl*UA26A:->>EG 	Gr'   c                $    [        X-   S-
  U5      $ Nr4   )FallingFactorialr!   r   r   r"   s       r$   !_eval_rewrite_as_FallingFactorial1RisingFactorial._eval_rewrite_as_FallingFactorial{  s    	1--r'   c                   SSK Jn  UR                  (       am  UR                  (       a[  U" [        X!-   S-
  5      [        US-
  5      -  US:  4[        R
                  U-  [        U* 5      -  [        U* U-
  5      -  S45      $ g g Nr   r   r4   Tr   r   r{   r   r   r   r!   r   r   r"   r   s        r$   r   *RisingFactorial._eval_rewrite_as_factorial~  sy    B<<ALL1519%iA&66A>!)QB-/	1"q&0AA4HJ J )<r'   c                `    UR                   (       a  [        U5      [        X-   S-
  U5      -  $ g r  r{   r   binomialr  s       r$   _eval_rewrite_as_binomial)RisingFactorial._eval_rewrite_as_binomial  s*    <<Q<(1519a"888 r'   Nc                   SSK Jn  U(       a  UR                  U[        R                  5      nU[        R                  L a!  U" X-   5      R                  SSS9U" U5      -  $ U[        R                  L a=  [        R                  U-  U" SU-
  5      -  U" U* U-
  S-   5      R                  SSS9-  $ U R                  U5      R                  SSS9$ Nr   r   	tractableT)deepr4   )r5   r2   r   r   r_   rewriter
  r   r!   r   r   limitvarr"   r2   k_lims          r$   _eval_rewrite_as_tractable*RisingFactorial._eval_rewrite_as_tractable  s    AFF8QZZ0E

"ae,,[t,DuQxOP!,,,q(q1u5qb1fqj8I8Q8QR]dh8Q8iij||E"**;T*BBr'   c                    [        U R                  S   R                  U R                  S   R                  U R                  S   R                  45      $ Nr   r4   r   r6   r{   r|   r   s    r$   r    RisingFactorial._eval_is_integer  E    $))A,11499Q<3J3J))A,557 8 	8r'   r(   r   r   )r)   r*   r+   r,   r-   r   rk   r   r  r   r#  r-  r   r.   r(   r'   r$   r   r     s>    ;z 8 8t	G.J9C8r'   r   c                  T    \ rS rSrSr\S 5       rSS jrS rS r	S r
SS	 jrS
 rSrg)r  i  ap  
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                  ^ [        T5      m[        U5      nT[        R                  L d  U[        R                  L a  [        R                  $ UR                  (       a  TU:X  a  [	        T5      $ UR
                  (       Ga  UR                  (       a  [        R                  $ UR                  (       a  T[        R                  L a  [        R                  $ T[        R                  L a1  UR                  (       a  [        R                  $ [        R                  $ [        T[        5      (       aI  TR                  n[        U5      S:w  a  [!        S5      e[#        U4S j[%        ['        U5      5      S5      $ [#        U4S j[%        ['        U5      5      S5      $ T[        R                  L a  [        R                  $ T[        R                  L a  [        R                  $ [        T[        5      (       aY  TR                  n[        U5      S:w  a  [!        S5      eS[#        U4S j[%        S[)        ['        U5      5      S-   5      S5      -  $ S[#        U4S j[%        S[)        ['        U5      5      S-   5      S5      -  $ g )Nr4   z0ff only defined for polynomials on one generatorc                .   > U TR                  U* 5      -  $ r   r   r  s     r$   r  'FallingFactorial.eval.<locals>.<lambda>  s    ./!or'   c                   > U TU-
  -  $ r   r(   r  s     r$   r  r7    r  r'   r   c                ,   > U TR                  U5      -  $ r   r   r  s     r$   r  r7    s    011771:r'   c                   > U TU-   -  $ r   r(   r  s     r$   r  r7  	  s    AEr'   )r   r   r   r{   r   r`   r]   r^   r   r_   r
  r   r  r   r  r  r   r   rc   rG   r}   r  s    `  r$   rk   FallingFactorial.eval  s   AJAJ:aee55L\\a1fQ<\\\yyuu==AJJ zz)a00088#$#5#55#$::-%a..#$66D"4y1}&0 2K 'L !L (. />.3CFmQ(@ !@ $**@*/A-$< < AJJ zz)a000 zz)%a..#$66D"4y1}&0 2K 'L !L () 1?05aSVq0I1*N (N !N $%V,B,1!SQ[1_,Eq&J $J JS r'   c                V   SSK Jn  SSKJn  U(       dJ  US:  S:X  a(  [        R
                  U-  U" X!-
  5      -  U" U* 5      -  $ U" US-   5      U" X-
  S-   5      -  $ U" U" US-   5      U" X-
  S-   5      -  US:  4[        R
                  U-  U" X!-
  5      -  U" U* 5      -  S45      $ r  r  r  s          r$   r   'FallingFactorial._eval_rewrite_as_gamma  s    BAA$}}a'ae4uaRy@@Q<%	"2221q5\E!%!),,a1f5]]AeAEl*UA2Y6=? 	?r'   c                $    [        X-
  S-   U5      $ r  )rfr  s       r$    _eval_rewrite_as_RisingFactorial1FallingFactorial._eval_rewrite_as_RisingFactorial  s    !%!)Qr'   c                T    UR                   (       a  [        U5      [        X5      -  $ g r   r!  r  s       r$   r#  *FallingFactorial._eval_rewrite_as_binomial  s!    <<Q<(1.00 r'   c                   SSK Jn  UR                  (       am  UR                  (       a[  U" [        U5      [        U* U-   5      -  US:  4[        R
                  U-  [        X!-
  S-
  5      -  [        U* S-
  5      -  S45      $ g g r  r  r  s        r$   r   +FallingFactorial._eval_rewrite_as_factorial  sy    B<<ALL1iQ//a8!)AEAI"66y!a7HH$OQ Q )<r'   Nc                   SSK Jn  U(       a  UR                  U[        R                  5      nU[        R                  L a6  [        R
                  U-  U" X!-
  5      R                  SSS9-  U" U* 5      -  $ U[        R                  L a'  U" US-   5      U" X-
  S-   5      R                  SSS9-  $ U R                  U5      R                  SSS9$ r&  )r5   r2   r   r   r_   r   r)  r
  r*  s          r$   r-  +FallingFactorial._eval_rewrite_as_tractable%  s    AFF8QZZ0E

"q(qu)=)=kPT)=)UUX]_`^`Xaab!,,,a!euQUQY'7'?'?RV'?'WWX||E"**;T*BBr'   c                    [        U R                  S   R                  U R                  S   R                  U R                  S   R                  45      $ r0  r1  r   s    r$   r   !FallingFactorial._eval_is_integer/  r3  r'   r(   r   r   )r)   r*   r+   r,   r-   r   rk   r   r@  r#  r   r-  r   r.   r(   r'   r$   r  r    s?    <| 2J 2Jh	? 1QC8r'   r  c                      \ rS rSrSrSS jr\S 5       r\S 5       rS r	S r
S rSS	 jrSS jrS rS rS rS rSrg
)r"  i<  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
c                   SSK Jn  US:X  a5  U R                  u  p4[        X45      U" SUS-   5      U" SX4-
  S-   5      -
  -  $ US:X  a5  U R                  u  p4[        X45      U" SX4-
  S-   5      U" SUS-   5      -
  -  $ [	        X5      e)Nr   )r3   r4   rE   )r5   r3   r6   r"  r   )r!   r7   r3   rL   r   s        r$   r8   binomial.fdiff  s    Eq=99DAA>9QA#6!QUQY'$( ) )]99DAA>9Q	#:!QU#$$ % % %T44r'   c                   UR                   (       a  UR                   (       a  US:  a  [        U5      [        U5      p!X!:  a  [        R                  $ X!S-  :  a  X-
  n[        b  [        [        R                  " X5      5      $ X-
  SpC[        SUS-   5       H  nUS-  nXC-  U-  nM     [        U5      $ X-
  SpC[        SUS-   5       H  nUS-  nXC-  nM     U[        U5      -  $ g )Nr   rE   r4   )	r`   rG   r   r   rd   r   bincoefrc   
_factorial)r!   rL   r   r   rh   ri   s         r$   r   binomial._eval  s     <<||Q1vs1v1566MaZA
 $"5==#677E16q!a%AFA#Z1_F ) v&E16q!a%AFAKF ) 
1--3 r'   c                   [        [        X45      u  pX-
  nUR                  UR                  pTUR                  (       d  U(       d  USL a!  UR                  (       a  [
        R                  $ US-
  R                  (       d   U(       d  USL a  US-
  R                  (       a  U$ UR                  (       a{  UR                  (       d  U(       a(  U(       a!  UR                  (       a  [
        R                  $ UR                  (       a)  U R                  X5      nU(       a  UR                  SS9$ U$ g USL a  U(       a  [
        R                  $ UR                  (       a+  SSKJn  U" US-   5      U" US-   5      U" X-
  S-   5      -  -  $ g )NFr4   T)basicr   r   )r   r   r|   r{   r]   r   r^   ra   r   	is_numberr   expandrb   r5   r2   )rK   rL   r   r   n_nonnegn_isintrp   r2   s           r$   rk   binomial.eval  s   7QF#E,,all'99(g&6II55LE??Gu,<UOOH<<}}g!--vviio14szzz-=#=  7$$$[[EQ<q1ueAEAI.>!>?? r'   c                   U R                   u  p#[        S X#U4 5       5      (       a  [        S5      e[        S X#U4 5       5      (       GaA  [	        [
        X#45      u  p#[        U5      SpTUS:  a  [        R                  $ US:  a  U* U-   S-
  nUS-  (       a  SOSnX2:  a  [        R                  $ UR                  n[        U5      nU(       a  XB:  aA  X#pU(       d  U(       a/  U[        Xt-  X-  5      -  U-  nXt-  X-  pU(       a  M&  U(       a  M/  GOiX#-
  n	X9:  a  XpSn
[        SUS-   5       H
  nX-  U-  n
M     U
n[        US-   U	S-   5       H
  nX-  U-  nM     X\-  n[        U	S-   US-   5       H
  nX[-  U-  nM     U[        X-  U-  US-
  U5      -  nXT-  nO[        U5      U:  a  US:w  a  [        X#U5      nO[        [        U5      5      n[        R                   " SUS-   5       H  nXU-
  :  a	  X^-  U-  nM  XS-  :  a  M  X:  a  X.-  X>-  :  a	  X^-  U-  nM6  M8  X#pS=nnUS:  a)  [        X~-  X-  U-   :  5      nX~-  X-  pUU-  nUS:  a  M)  US:  d  Mu  U[        XU5      -  nXT-  nM     [        XQ-  5      $ g )Nc              3  <   #    U  H  oR                   S L v   M     g7f)FN)r{   .0r   s     r$   	<genexpr>%binomial._eval_Mod.<locals>.<genexpr>  s     8i||u$is   z"Integers expected for binomial Modc              3  8   #    U  H  oR                   v   M     g 7fr   )r`   rZ  s     r$   r\  r]    s     /Y||Ys   r4   r   rE   ry   )r6   anyr   allr   rG   r}   r   r   r   r"  rc   rn   rH   r   r   rI   )r!   rQ   rL   r   r   rp   r   rM   Kr   kfri   dfMrO   r   as                    r$   r   binomial._eval_Mod  s   yy8qQi888ABB/aAY///sQF#DA!fa 1uvv1uBFQJaCbQ uvvkkGRB6qq!(1616"::R? w1 !qq Au 1B"1a!e_TBY -B"1q5!a%0TBY 1IC"1q5!a%0!ebj 1 3rurz26266CICqA!q&"1+ aM"--aQ7E1u}!i"na 9qy0"%)b.C 1  !1"#a!e #QY19q=$A BA#$:qzq1HC  !e
 73u2#66CIC' 8* SW:W 0r'   c                   U R                   S   nUR                  (       a  [        U R                   6 $ U R                   S   nX#-
  R                  (       a  X#-
  nUR                  (       a  UR                  (       a  [
        R                  $ UR                  (       a  [
        R                  $ U R                   S   SpB[        SUS-   5       H  nXBU-
  U-   -  nM     U[        U5      -  $ [        U R                   6 $ )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   r4   )r6   r\   r"  r`   r]   r   r^   ra   r   rc   rO  )r!   hintsrL   r   rh   ri   s         r$   _eval_expand_funcbinomial._eval_expand_func3  s     IIaL;;TYY''IIaLCA<<yyuuvv IIaL!6q!a%A!eai'F )
1--TYY''r'   c                L    [        U5      [        U5      [        X-
  5      -  -  $ r   )r   r!   rL   r   r"   s       r$   r   #binomial._eval_rewrite_as_factorialN  s!    |Yq\)AE*::;;r'   c                X    SSK Jn  U" US-   5      U" US-   5      U" X-
  S-   5      -  -  $ r   r   )r!   rL   r   r   r"   r2   s         r$   r   binomial._eval_rewrite_as_gammaQ  s0    AQU|U1q5\%	*::;;r'   Nc                B    U R                  X5      R                  S5      $ )Nr'  )r   r)  )r!   rL   r   r+  r"   s        r$   r-  #binomial._eval_rewrite_as_tractableU  s    **1088EEr'   c                T    UR                   (       a  [        X5      [        U5      -  $ g r   )r{   ffr   rl  s       r$   r  *binomial._eval_rewrite_as_FallingFactorialX  s!    <<a8il** r'   c                    U R                   u  pUR                  (       a  UR                  (       a  gUR                  SL a  gg NTF)r6   r{   r!   rL   r   s      r$   r   binomial._eval_is_integer\  s1    yy<<ALL\\U" #r'   c                    U R                   u  pUR                  (       aW  UR                  (       aE  UR                  (       d"  UR                  (       d  UR                  (       a  gUR                  SL a  gg g g rv  )r6   r{   r|   ra   r   rw  s      r$   r   binomial._eval_is_nonnegativec  sM    yy<<ALL1==AIIe# $ )<r'   c                L    SSK Jn  U R                  U5      R                  XUS9$ )Nr   r   )r   r   )r5   r2   r)  r   )r!   r   r   r   r2   s        r$   r   binomial._eval_as_leading_termk  s$    A||E"88D8QQr'   r(   r   r   r   )r)   r*   r+   r,   r-   r8   r   r   rk   r   ri  r   r   r-  r  r   r   r   r.   r(   r'   r$   r"  r"  <  si    [z5 . .< @ @.Qf(6<<F+Rr'   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   rd   sympy.ntheoryr   sympy.ntheory.residue_ntheoryr   sympy.polys.polytoolsr   mathr   rO  r   r   rH   r   r   r   r   r   r  r?  rs  r"  r(   r'   r$   <module>r     s    "  - - $ N N & - - $ -  6 & = =O &s>% s>j	* 	_( _Dp0& p0p^8+ ^8BY8, Y8x qR$ qRr'   