
    g                       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e          Z& G d de&          Z! G d de&          Z' G d de&          Z( G d de&          Z) G d de&          Z* G d de&          Z+e*Z,e+Z- G 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                      e Zd ZdZd ZdS )CombinatorialFunctionz(Base class for combinatorial functions. c                ~    ddl m}  ||           }|d         } ||          |d          ||           z  k    r|S | S )Nr   )combsimpmeasureratio)sympy.simplify.combsimpr   )selfkwargsr   exprr   s        d/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/functions/combinatorial/factorials.py_eval_simplifyz$CombinatorialFunction._eval_simplify   s[    444444 x~~#74==F7OGGDMM999K    N)__name__
__module____qualname____doc__r$    r%   r#   r   r      s)        22    r%   r   c                      e Zd ZU dZddZg dZg Zded<   ed             Z	ed             Z
ed	             Zd
 Zd ZddZd Zd Zd Zd Zd Z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                    ddl m}m} |dk    r4 || j        d         dz              |d| j        d         dz             z  S t	          | |          )Nr   )gamma	polygammar,   )'sympy.functions.special.gamma_functionsr.   r/   argsr   )r    argindexr.   r/   s       r#   fdiffzfactorial.fdiffU   sj    NNNNNNNNq==51)**99Q	!q8H+I+III$T8444r%   )!r,   r,   r,      r4         #   r7   i;  ?   i     i  i  #  r:   iS i{/  i! im  i isX iU iP
 ioik iIi/L iSi} #r;   z	list[int]_small_factorialsc                   |dk     r| j         |         S t          t          |                    g }}t          j        d|dz             D ]>}d|}}	 ||z  }|dk    r|dz  dk    r||z  }nn|dk    r|                    |           ?t          j        |dz   |dz  dz             D ]#}||z  dz  dk    r|                    |           $t          t          j        |dz  dz   |dz                       }t          |          }||z  S )N!   r4   r,   Tr      )_small_swingint_sqrtr   
primerangeappendr   )	clsnNprimesprimepq	L_product	R_products	            r#   _swingzfactorial._swingd   s6   r66#A&&E!HHrvA)!QU33 % %!1%KA1uuq5A::JA q55MM!$$$)!a%A:: ) )J!#q((MM%(((U-adQhA>>??IVIY&&r%   c                t    |dk     rdS |                      |dz            dz  |                     |          z  S )Nr?   r,   )
_recursiverN   )rE   rF   s     r#   rP   zfactorial._recursive   s:    q551NN1a4((!+SZZ]]::r%   c                N   t          |          }|j        r|j        rt          j        S |t          j        u rt          j        S |j        r|j        rt          j        S |j	        }|dk     rL| j
        s4d}t          dd          D ]!}||z  }| j
                            |           "| j
        |dz
           }n\t          t          j        |          }n@t          |                              d          }|                     |          d||z
  z  z  }t%          |          S d S d S )N   r,   1r?   )r   	is_Numberis_zeror   OneInfinity
is_Integeris_negativeComplexInfinityrJ   r<   rangerD   _gmpyfacbincountrP   r   )rE   rF   resultibitss        r#   evalzfactorial.eval   s7   AJJ; #	+y "+uajz! += +,,A2vv"4 E%&F%*1b\\ E E &! # 5 < <V D D D D!$!6qs!; *!&1  #1vv||C00!$!2!21q4x=!@"6??*G#	+ #	+
+ +r%   c                   dt          t          |                    }}dg|z  }d}t          j        d|dz             D ]L}|dk    rd||z  }}|r||z  }||z  }|||k     r||         |z  |z  ||<   5|t	          |||          z  |z  }Mt          |          D ]2\  }	}
|	dk    s|
dk    r|
dk    r dS |t	          |
|	|          z  |z  }3|S )Nr,   r?   r   )rA   rB   r   rC   pow	enumerate)r    rF   rK   resrG   pwmrI   yexbss              r#   _facmodzfactorial._facmod   s   CaMMQ SU%aQ// 		/ 		/E1uu!u*1  FA%KA    1uu1ea1#eQ***Q.mm 	) 	)FBQww"''Qwwqqc"b!nn$q(CC
r%   c                   | j         d         }|j        r|j        r|j        rt          |          }||z
  }|j        rt
          j        S |j        }|dk    r%|rd|z  S |du r|dz
  j        rt
          j        S d S d S |j        r|j        rt          t          |||f          \  }}}|r?|dz
  |k     r6|                     |dz
  |          }t          ||dz
  |          }|dz  r| }n|                     ||          }||z  S d S d S d S d S d S )Nr   r,   F   r?   )r1   
is_integeris_nonnegativeabsis_nonpositiver   Zerois_primerX   maprA   rm   re   )r    rK   rF   aqdisprimefcs          r#   	_eval_Modzfactorial._eval_Mod   so   IaL< 	"A, 	" 	"QBQA "v+66
  &!Av E))rAv.E) v *)))\ 
"al 
""3Ar
33HAq" 1AEAII!\\!a%44 R!VR00Q3 %"$B!\\!R006M5	" 	" 	" 	" 	" 	" 
" 
" 
" 
"r%   Tc                *    ddl m}  ||dz             S Nr   r.   r,   r0   r.   )r    rF   	piecewiser!   r.   s        r#   _eval_rewrite_as_gammaz factorial._eval_rewrite_as_gamma   s&    AAAAAAuQU||r%   c                r    ddl m} |j        r'|j        r"t	          dd          } |||d|f          S d S d S )Nr   )Productra   T)integerr,   )sympy.concrete.productsr   rr   rq   r   )r    rF   r!   r   ra   s        r#   _eval_rewrite_as_Productz"factorial._eval_rewrite_as_Product   sf    333333 	) 	)c4(((A71q!Qi(((	) 	) 	) 	)r%   c                V    | j         d         j        r| j         d         j        rdS d S d S Nr   Tr1   rq   rr   r    s    r#   _eval_is_integerzfactorial._eval_is_integer   <    9Q<" 	ty|'B 	4	 	 	 	r%   c                V    | j         d         j        r| j         d         j        rdS d S d S r   r   r   s    r#   _eval_is_positivezfactorial._eval_is_positive   r   r%   c                T    | j         d         }|j        r|j        r|dz
  j        S d S d S )Nr   r?   r   r    xs     r#   _eval_is_evenzfactorial._eval_is_even  B    IaL< 	*A, 	*E))	* 	* 	* 	*r%   c                T    | j         d         }|j        r|j        r|dz
  j        S d S d S )Nr   r4   r   r   s     r#   _eval_is_compositezfactorial._eval_is_composite  r   r%   c                @    | j         d         }|j        s|j        rdS d S r   )r1   rr   is_nonintegerr   s     r#   _eval_is_realzfactorial._eval_is_real  s0    IaL 	q 	4	 	r%   Nr   c                    | j         d                             |          }|                    |d          }|j        rt          j        S |j        s|                     |          S t          d| z            )Nr   zCannot expand %s around 0)	r1   as_leading_termsubsrU   r   rV   is_infinitefuncr   )r    r   logxcdirargarg0s         r#   _eval_as_leading_termzfactorial._eval_as_leading_term  sl    il**1--xx1~~< 	"5L! 	"99S>>!3t<===r%   r,   TNr   )r&   r'   r(   r)   r3   r@   r<   __annotations__classmethodrN   rP   rc   rm   r|   r   r   r   r   r   r   r   r   r*   r%   r#   r   r   $   sJ        . .`5 5 5 5  L $&%%%%' ' ['< ; ; [; &+ &+ [&+P  <" " "<   ) ) )    * * *
* * *
  
> > > > > >r%   r   c                      e Zd ZdS )MultiFactorialN)r&   r'   r(   r*   r%   r#   r   r     s        Dr%   r   c                  z    e Zd ZdZeed                         Zed             Zd Zd Z	d Z
ddZd	 Zd
 Z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                    |st           j        S |dk    rt           j        S d\  }}t          d|dz             D ]}||dz
  ||z   z  }}|S )Nr,   )r,   r   r?   )r   rV   ru   r[   )r    rF   z1z2ra   s        r#   _evalzsubfactorial._evalG  sd      	5L!VV6MFB1a!e__ / /a!eb2g.BIr%   c                    |j         rW|j        r|j        r|                     |          S |t          j        u rt          j        S |t          j        u rt          j        S d S d S N)rT   rX   rr   r   r   NaNrW   )rE   r   s     r#   rc   zsubfactorial.evalT  si    = 	"~ "#"4 "yy~~%u
""z!	" 	"
 #"r%   c                V    | j         d         j        r| j         d         j        rdS d S d S r   )r1   is_oddrr   r   s    r#   r   zsubfactorial._eval_is_even^  s<    9Q< 	49Q<#> 	4	 	 	 	r%   c                V    | j         d         j        r| j         d         j        rdS d S d S r   r   r   s    r#   r   zsubfactorial._eval_is_integerb  r   r%   c                    ddl m} t          d          }t          j        |z  t          |          z  }t          |           |||d|f          z  S )Nr   )	summationra   )sympy.concrete.summationsr   r   r   NegativeOner   )r    r   r!   r   ra   fs         r#   _eval_rewrite_as_factorialz'subfactorial._eval_rewrite_as_factorialf  sY    777777#JJM1y||+~~		!aC[ 9 999r%   Tc                    ddl m} ddlm}m} t
          j        |dz   z   |t           t          z  |z            z   ||dz   d          z   ||dz             z    |d          z  S )Nr   )exp)r.   
lowergammar,   ro   )	&sympy.functions.elementary.exponentialr   r0   r.   r   r   r   r   r   )r    r   r   r!   r   r.   r   s          r#   r   z#subfactorial._eval_rewrite_as_gammal  s    >>>>>>OOOOOOOOa(aRU3Y7

37B8O8OO%a..!"%#b''* 	*r%   c                F    ddl m}  ||dz   d          t          j        z  S )Nr   )
uppergammar,   ro   )r0   r   r   Exp1)r    r   r!   r   s       r#   _eval_rewrite_as_uppergammaz(subfactorial._eval_rewrite_as_uppergammar  s1    FFFFFFz#'2&&qv--r%   c                V    | j         d         j        r| j         d         j        rdS d S d S r   r   r   s    r#   _eval_is_nonnegativez!subfactorial._eval_is_nonnegativev  r   r%   c                V    | j         d         j        r| j         d         j        rdS d S d S r   )r1   is_evenrr   r   s    r#   _eval_is_oddzsubfactorial._eval_is_oddz  s<    9Q< 	DIaL$? 	4	 	 	 	r%   Nr   )r&   r'   r(   r)   r   r	   r   rc   r   r   r   r   r   r   r   r*   r%   r#   r   r     s        ' 'R 	 	 W [	 " " ["    : : :* * * *. . .      r%   r   c                  H    e Zd ZdZed             Zd Zd Zd Zd Z	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                R   |j         r|j        st          d          |j        rC|j        r|dz  }d|z  t          |          z  S t          |          t          |dz
            z  S |j        r)|t          j	        d|z
  dz  z  z  t          |           z  S t          d          d S )Nz<argument must be nonnegative integer or negative odd integerr?   r,   )
rT   rX   
ValueErrorrr   r   r   r   r   r   r   )rE   r   ks      r#   rc   zfactorial2.eval  s     = 	;> ?  "> ? ? ?
 ! <; /aAa4)A,,.. ~~
37(;(;;; z MAMa#gq[99Jt<L<LLL : ; ; ;!	; 	;r%   c                z    | 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)r1   rq   r   r   is_positiverU   r    rF   s     r#   r   zfactorial2._eval_is_even  sl    IaL< 	!x uy !=  49 ! 5	! 	!! !! !r%   c                l    | j         d         }|j        r|dz   j        rdS |j        r|dz   j        S d S d S )Nr   r,   Tr4   )r1   rq   rr   r   r   s     r#   r   zfactorial2._eval_is_integer  sX     IaL< 	.A% tx .A--		. 	.. .r%   c                x    | j         d         }|j        r
|dz   j        S |j        r|j        rdS |j        rdS d S d S )Nr   r4   FT)r1   r   rr   r   r   rU   r   s     r#   r   zfactorial2._eval_is_odd  sb     IaL8 	*E))9 	} uy t		 	 r%   c                r    | j         d         }|j        r |dz   j        rdS |j        r|dz   dz  j        S d S d S )Nr   r,   Tr?   )r1   rq   rr   r   r   r   s     r#   r   zfactorial2._eval_is_positive  s\     IaL< 	-A% tx -Q!,,		- 	-- -r%   Tc                   ddl m} ddlm} ddlm} d|dz  z   ||dz  dz             z   |dt          t          |d          d          f |dt          z            t          t          |d          d          f          z  S )Nr   )r   	Piecewiser   r?   r,   )	(sympy.functions.elementary.miscellaneousr   $sympy.functions.elementary.piecewiser   r0   r.   r   r   r   )r    rF   r   r!   r   r   r.   s          r#   r   z!factorial2._eval_rewrite_as_gamma  s    AAAAAABBBBBBAAAAAA1Q3xacAg&Ar#a))Q7G7G3HadRAq		1--.*0 *0 0 	0r%   Nr   )r&   r'   r(   r)   r   rc   r   r   r   r   r   r*   r%   r#   r   r     s        # #J ; ; [;.
! 
! 
!. . .
 
 
	- 	- 	-0 0 0 0 0 0r%   r   c                  P    e Zd ZdZed             ZddZd Zd Zd Z	dd	Z
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                   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        rt          j        u rt          j        S t          j	        u r|j
        rt          j	        S t          j        S t          t                    rWj        }t          |          dk    rt          d          t!          fdt#          t%          |                    d          S t!          fdt#          t%          |                    d          S t          j        u rt          j        S t          j	        u rt          j        S t          t                    rkj        }t          |          dk    rt          d          dt!          fdt#          dt'          t%          |                    dz             d          z  S dt!          fdt#          dt'          t%          |                    dz             d          z  S |j        dk    rj        rj        rt          j        S d S d S d S )Nr,   0rf only defined for polynomials on one generatorc                4    |                      |          z  S r   shiftrra   r   s     r#   <lambda>z&RisingFactorial.eval.<locals>.<lambda>Q  s    ./n r%   c                    | |z   z  S r   r*   r   s     r#   r   z&RisingFactorial.eval.<locals>.<lambda>U      q!a%y r%   c                6    |                      |           z  S r   r   r   s     r#   r   z&RisingFactorial.eval.<locals>.<lambda>d  s    01177A2;; r%   c                    | |z
  z  S r   r*   r   s     r#   r   z&RisingFactorial.eval.<locals>.<lambda>h  s    ,-q1uI r%   F)r   r   r   rV   r   rX   rU   r   rW   NegativeInfinityr   
isinstancer   genslenr   r   r[   rA   rs   rq   rY   ru   rE   r   r   r   s    `  r#   rc   zRisingFactorial.eval5  s   AJJAJJ::ae5L!%ZZQ<<\ ,	Jy +Ju= (JAJ z)a0008 .#$#55#$:-%a.. <#$6D"4yy1}}&0 2K 'L 'L !L (. /= /= /= /=.3CFFmmQ(@ (@ !@ $**@*@*@*@*/A--$< $< < AJ z)a000 z)%a.. J#$6D"4yy1}}&0 2K 'L 'L !L () 1@ 1@ 1@ 1@05aSVVq0I0I1*N *N (N !N $%V -6 -6 -6 -6,1!SQ[[1_,E,Eq&J &J $J J <5  |  v !    r%   Tc                ~   ddl m} ddlm} |sU|dk    dk    r1t          j        |z   |d|z
            z   || |z
  dz             z  S  |||z              ||          z  S  | |||z              ||          z  |dk    ft          j        |z   |d|z
            z   || |z
  dz             z  df          S Nr   r   r   Tr,   r   r   r0   r.   r   r   r    r   r   r   r!   r   r.   s          r#   r   z&RisingFactorial._eval_rewrite_as_gammap  s   BBBBBBAAAAAA 	+Q4}a'a!e4uuaR!VaZ7H7HHH5Q<<%%((**yU1q5\\EE!HH$a!e,]AeeAEll*UUA26A:->->>EG G 	Gr%   c                .    t          ||z   dz
  |          S Nr,   )FallingFactorialr    r   r   r!   s       r#   !_eval_rewrite_as_FallingFactorialz1RisingFactorial._eval_rewrite_as_FallingFactorial{  s    A	1---r%   c                
   ddl m} |j        rs|j        rn |t          ||z   dz
            t          |dz
            z  |dk    ft          j        |z  t          |           z  t          | |z
            z  df          S d S d S Nr   r   r,   Tr   r   rq   r   r   r   r    r   r   r!   r   s        r#   r   z*RisingFactorial._eval_rewrite_as_factorial~  s    BBBBBB< 	JAL 	J91q519%%iA&6&66A>!)QB--/	1"q&0A0AA4HJ J J	J 	J 	J 	Jr%   c                `    |j         r&t          |          t          ||z   dz
  |          z  S d S r   rq   r   binomialr   s       r#   _eval_rewrite_as_binomialz)RisingFactorial._eval_rewrite_as_binomial  s9    < 	9Q<<(1q519a"8"888	9 	9r%   Nc                   ddl m} |r|                    |t          j                  }|t          j        u r/ |||z                                 dd           ||          z  S |t          j        u rFt          j        |z   |d|z
            z   || |z
  dz                                 dd          z  S |                     |                              dd          S Nr   r   	tractableT)deepr,   )r0   r.   r   r   rW   rewriter   r   r    r   r   limitvarr!   r.   k_lims          r#   _eval_rewrite_as_tractablez*RisingFactorial._eval_rewrite_as_tractable  s    AAAAAA 	kFF8QZ00E
""a!e,,[t,DDuuQxxOP!,,,q(q1u5qb1fqj8I8I8Q8QR]dh8Q8i8iij||E""**;T*BBBr%   c                    t          | j        d         j        | j        d         j        | j        d         j        f          S Nr   r,   r   r1   rq   rr   r   s    r#   r   z RisingFactorial._eval_is_integer  ;    $)A,149Q<3J)A,57 8 8 	8r%   r   r   )r&   r'   r(   r)   r   rc   r   r   r   r   r  r   r*   r%   r#   r   r     s        ; ;z 8 8 [8t	G 	G 	G 	G. . .J J J9 9 9C C C C8 8 8 8 8r%   r   c                  P    e Zd ZdZed             ZddZd Zd Zd Z	dd	Z
d
 ZdS )r   a0  
    Falling factorial (related to rising factorial) is a double valued
    function arising in concrete mathematics, hypergeometric functions
    and series expansions. It is defined by

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

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

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

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

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

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

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

    See Also
    ========

    factorial, factorial2, RisingFactorial

    References
    ==========

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

    c                   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        rt          j	        u rt          j	        S t          j
        u r|j        rt          j
        S t          j	        S t          t                    rWj        }t          |          dk    rt!          d          t#          fdt%          t'          |                    d          S t#          fdt%          t'          |                    d          S t          j	        u rt          j	        S t          j
        u rt          j	        S t          t                    rkj        }t          |          dk    rt!          d          dt#          fdt%          dt)          t'          |                    dz             d          z  S dt#          fdt%          dt)          t'          |                    dz             d          z  S d S )Nr,   z0ff only defined for polynomials on one generatorc                6    |                      |           z  S r   r   r   s     r#   r   z'FallingFactorial.eval.<locals>.<lambda>  s    ./!o r%   c                    | |z
  z  S r   r*   r   s     r#   r   z'FallingFactorial.eval.<locals>.<lambda>  r   r%   r   c                4    |                      |          z  S r   r   r   s     r#   r   z'FallingFactorial.eval.<locals>.<lambda>  s    011771:: r%   c                    | |z   z  S r   r*   r   s     r#   r   z'FallingFactorial.eval.<locals>.<lambda>	  s    AE r%   )r   r   r   rq   r   rX   rU   rV   r   rW   r   r   r   r   r   r   r   r   r[   rA   rs   r   s    `  r#   rc   zFallingFactorial.eval  s   AJJAJJ::ae5L\ ,	Ja1ffQ<<\ *	Jy )Ju= &JAJ z)a0008 .#$#55#$:-%a.. <#$6D"4yy1}}&0 2K 'L 'L !L (. /> /> /> />.3CFFmmQ(@ (@ !@ $**@*@*@*@*/A--$< $< < AJ z)a000 z)%a.. J#$6D"4yy1}}&0 2K 'L 'L !L () 1? 1? 1? 1?05aSVVq0I0I1*N *N (N !N $%V,B,B,B,B,1!SQ[[1_,E,Eq&J &J $J JS*	J *	Jr%   Tc                ~   ddl m} ddlm} |sU|dk     dk    r+t          j        |z   |||z
            z   ||           z  S  ||dz              |||z
  dz             z  S  | ||dz              |||z
  dz             z  |dk    ft          j        |z   |||z
            z   ||           z  df          S r   r   r   s          r#   r   z'FallingFactorial._eval_rewrite_as_gamma  s   BBBBBBAAAAAA 	3A$}a'a!e4uuaRyy@@5Q<<%%A	"2"222yU1q5\\EE!a%!),,,a1f5]AeeAEll*UUA2YY6=? ? 	?r%   c                .    t          ||z
  dz   |          S r   )rfr   s       r#    _eval_rewrite_as_RisingFactorialz1FallingFactorial._eval_rewrite_as_RisingFactorial  s    !a%!)Qr%   c                T    |j         r t          |          t          ||          z  S d S r   r   r   s       r#   r   z*FallingFactorial._eval_rewrite_as_binomial  s/    < 	1Q<<(1a..00	1 	1r%   c                
   ddl m} |j        rs|j        rn |t          |          t          | |z             z  |dk    ft          j        |z  t          ||z
  dz
            z  t          | dz
            z  df          S d S d S r   r   r   s        r#   r   z+FallingFactorial._eval_rewrite_as_factorial  s    BBBBBB< 	QAL 	Q91iQ///a8!)AEAI"6"66y!a7H7HH$OQ Q Q	Q 	Q 	Q 	Qr%   Nc                   ddl m} |r|                    |t          j                  }|t          j        u r@t          j        |z   |||z
                                dd          z   ||           z  S |t          j        u r5 ||dz              |||z
  dz                                 dd          z  S |                     |                              dd          S r   )r0   r.   r   r   rW   r   r  r   r  s          r#   r  z+FallingFactorial._eval_rewrite_as_tractable%  s    AAAAAA 	YFF8QZ00E
""q(q1u)=)=kPT)=)U)UUX]X]_`^`XaXaab!,,,a!euuQUQY'7'7'?'?RV'?'W'WWX||E""**;T*BBBr%   c                    t          | j        d         j        | j        d         j        | j        d         j        f          S r  r	  r   s    r#   r   z!FallingFactorial._eval_is_integer/  r
  r%   r   r   )r&   r'   r(   r)   r   rc   r   r  r   r   r  r   r*   r%   r#   r   r     s        < <| 2J 2J [2Jh	? 	? 	? 	?     1 1 1Q Q QC C C C8 8 8 8 8r%   r   c                      e Zd ZdZddZed             Zed             Zd Zd Z	d Z
dd
ZddZd Zd Z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                :   ddl m} |dk    r=| j        \  }}t          ||           |d|dz              |d||z
  dz             z
  z  S |dk    r=| j        \  }}t          ||           |d||z
  dz              |d|dz             z
  z  S t	          | |          )Nr   )r/   r,   r?   )r0   r/   r1   r   r   )r    r2   r/   rF   r   s        r#   r3   zbinomial.fdiff  s    EEEEEEq==9DAqAq>>99QA#6#6	!QUQY''$( ) )]]9DAqAq>>99QA	#:#:	!QU##$$ % % %T8444r%   c                   |j         r|j         r|dk    rt          |          t          |          }}||k    rt          j        S ||dz  k    r||z
  }t          "t          t	          j        ||                    S ||z
  d}}t          d|dz             D ]}|dz  }||z  |z  }t          |          S ||z
  d}}t          d|dz             D ]}|dz  }||z  }|t          |          z  S d S )Nr   r?   r,   )	rX   rA   r   ru   r\   r   bincoefr[   
_factorial)r    rF   r   ry   r`   ra   s         r#   r   zbinomial._eval  s     < 	.| .Q1vvs1vv1q556MaZZAA
 $"5=A#6#6777E16q!a% - -AFA#aZ1_FFv&E16q!a%    AFAaKFF
1--3	. 	.r%   c                0   t          t          ||f          \  }}||z
  }|j        |j        }}|j        s|s|du r|j        rt
          j        S |dz
  j        s|s|du r|dz
  j        r|S |j        rW|j        s|r|r|j        rt
          j        S |j	        r0| 
                    ||          }|r|                    d          n|S d S |du r|rt
          j        S |j	        r5ddlm}  ||dz              ||dz              |||z
  dz             z  z  S d S )NFr,   T)basicr   r   )rw   r   rr   rq   rU   r   rV   rY   ru   	is_numberr   expandrZ   r0   r.   )rE   rF   r   ry   n_nonnegn_isintrg   r.   s           r#   rc   zbinomial.eval  s   7QF##1E,al'9 	( 	g&6&6I '75LE? 	 	Gu,<,<UO -=H< 	@} > >g >!- >v >ii1oo14=szzz---#=> > 7$$[ 	@EEEEEE5Q<<q1ueeAEAI.>.>!>??	@ 	@r%   c                d   | j         \  }}t          d |||fD                       rt          d          t          d |||fD                       r]t	          t
          ||f          \  }}t          |          d}}|dk     rt          j        S |dk     r| |z   dz
  }|dz  rdnd}||k    rt          j        S |j	        }t          |          }|r||k     r4||}}|s|r*|t          ||z  ||z            z  |z  }||z  ||z  }}|(|*n||z
  }	||	k    r|	|}	}d}
t          d|dz             D ]
}|
|z  |z  }
|
}t          |dz   |	dz             D ]
}||z  |z  }||z  }t          |	dz   |dz             D ]
}||z  |z  }|t          |
|z  |z  |dz
  |          z  }||z  }nt          |          |k     r|dk    rt          |||          }nt          t          |                    }t          j        d|dz             D ]}|||z
  k    r	||z  |z  }||dz  k    r||k    r||z  ||z  k     r||z  |z  }9||}}dx}}|dk    r1t          ||z  ||z  |z   k               }||z  ||z  }}||z  }|dk    1|dk    r|t          |||          z  }||z  }t          ||z            S d S )Nc              3  (   K   | ]}|j         d u V  dS )FN)rq   .0r   s     r#   	<genexpr>z%binomial._eval_Mod.<locals>.<genexpr>  s)      88q|u$888888r%   z"Integers expected for binomial Modc              3  $   K   | ]}|j         V  d S r   )rX   r&  s     r#   r(  z%binomial._eval_Mod.<locals>.<genexpr>  s$      //q|//////r%   r,   r   r?   ro   )r1   anyr   allrw   rA   rs   r   ru   rv   r   r[   re   rB   r   r   rC   )r    rK   rF   r   rx   rg   rz   rG   Kry   kfra   dfMrI   r   as                    r#   r|   zbinomial._eval_Mod  s   y188q!Qi88888 	CABBB//aAY///// K	sQF##DAq!ffaB 1uuv1uuBFQJaC&bbQ 1uuvkGRB 8&66aqA 0q 0!(1r61r6":"::R? BwR1  0q 0 AA1uu !1B"1a!e__ ' 'TBYB"1q5!a%00 ' 'TBY2IC"1q5!a%00 ) )!!ebj3r"urz262666C2ICCqA!q&&"1a++ aMM"-aQ77 & &Eq1u}}!%i"na u9q5y00"%e)b.C !1"#a!ee #QY1u9q=$A B BA#$:qEzqA1HC  !ee
 773uc2#6#66C2ICS1W::WK	 K	r%   c                x   | j         d         }|j        rt          | j          S | j         d         }||z
  j        r||z
  }|j        rh|j        rt
          j        S |j        rt
          j        S | j         d         d}}t          d|dz             D ]}|||z
  |z   z  }|t          |          z  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,   )r1   rT   r   rX   rU   r   rV   rY   ru   r[   r  )r    hintsrF   r   r`   ra   s         r#   _eval_expand_funczbinomial._eval_expand_func3  s     IaL; 	(TY''IaLaC 	AA< 	(y .u .v IaL!6q!a% ( (Aa!eai'FF
1--TY''r%   c                f    t          |          t          |          t          ||z
            z  z  S r   )r   r    rF   r   r!   s       r#   r   z#binomial._eval_rewrite_as_factorialN  s*    ||Yq\\)AE*:*::;;r%   Tc                l    ddl m}  ||dz              ||dz              |||z
  dz             z  z  S r~   r   )r    rF   r   r   r!   r.   s         r#   r   zbinomial._eval_rewrite_as_gammaQ  sN    AAAAAAuQU||UU1q5\\%%A	*:*::;;r%   Nc                T    |                      ||                              d          S )Nr   )r   r  )r    rF   r   r  r!   s        r#   r  z#binomial._eval_rewrite_as_tractableU  s&    **1a0088EEEr%   c                T    |j         r t          ||          t          |          z  S d S r   )rq   ffr   r5  s       r#   r   z*binomial._eval_rewrite_as_FallingFactorialX  s/    < 	+a88ill**	+ 	+r%   c                P    | j         \  }}|j        r	|j        rdS |j        du rdS d S NTF)r1   rq   r    rF   r   s      r#   r   zbinomial._eval_is_integer\  s?    y1< 	AL 	4\U""5 #"r%   c                    | 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;  )r1   rq   rr   rY   r   r<  s      r#   r   zbinomial._eval_is_nonnegativec  sp    y1< 	AL 	 1= AI te##		 	 	 	 $#r%   r   c                d    ddl m} |                     |                              |||          S )Nr   r   )r   r   )r0   r.   r  r   )r    r   r   r   r.   s        r#   r   zbinomial._eval_as_leading_termk  s;    AAAAAA||E""88D8QQQr%   r   r   r   r   )r&   r'   r(   r)   r3   r   r   rc   r|   r3  r   r   r  r   r   r   r   r*   r%   r#   r   r   <  s       [ [z5 5 5 5 . . [.< @ @ [@.Q Q Qf( ( (6< < << < < <F F F F+ + +    R R R R R 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   r\   sympy.ntheoryr   sympy.ntheory.residue_ntheoryr   sympy.polys.polytoolsr   mathr   r  r   r   rB   r   r   r   r   r   r   r  r9  r   r*   r%   r#   <module>rL     s   " " " " " "       - - - - - - - - - - - - $ $ $ $ $ $ G G G G G G G G G G & & & & & & - - - - - - - - - - $ $ $ $ $ $ - - - - - -       6 6 6 6 6 6 & & & & & & = = = = = = = = = =    H   &s> s> s> s> s>% s> s> s>j	 	 	 	 	* 	 	 	_ _ _ _ _( _ _ _Dp0 p0 p0 p0 p0& p0 p0 p0p^8 ^8 ^8 ^8 ^8+ ^8 ^8 ^8BY8 Y8 Y8 Y8 Y8, Y8 Y8 Y8x qR qR qR qR qR$ qR qR qR qR qRr%   