
    EdH                         d dl mZmZmZmZmZ d dlmZmZ d dl	m
Z
 d dlmZ d dlmZmZmZ d dlmZmZ d dlmZmZ d Zd	 Z G d
 de          ZdS )    )FunctionSMulPowAdd)ordereddefault_sort_key)expand_func)Dummy)gammasqrtsin)factorcancel)siftuniqc                 >   |                      t                    } |                     t                    }d |D             }|s| S ||z  }||                                                     t                    z  }|rt          d t          |          D              \  }}}|                     t          t          ||                              }t          |d                              t          t          ||                              S t          | d          S )a  
    Simplify expressions with gamma functions.

    Explanation
    ===========

    This function takes as input an expression containing gamma
    functions or functions that can be rewritten in terms of gamma
    functions and tries to minimize the number of those functions and
    reduce the size of their arguments.

    The algorithm works by rewriting all gamma functions as expressions
    involving rising factorials (Pochhammer symbols) and applies
    recurrence relations and other transformations applicable to rising
    factorials, to reduce their arguments, possibly letting the resulting
    rising factorial to cancel. Rising factorials with the second argument
    being an integer are expanded into polynomial forms and finally all
    other rising factorial are rewritten in terms of gamma functions.

    Then the following two steps are performed.

    1. Reduce the number of gammas by applying the reflection theorem
       gamma(x)*gamma(1-x) == pi/sin(pi*x).
    2. Reduce the number of gammas by applying the multiplication theorem
       gamma(x)*gamma(x+1/n)*...*gamma(x+(n-1)/n) == C*gamma(n*x).

    It then reduces the number of prefactors by absorbing them into gammas
    where possible and expands gammas with rational argument.

    All transformation rules can be found (or were derived from) here:

    .. [1] http://functions.wolfram.com/GammaBetaErf/Pochhammer/17/01/02/
    .. [2] http://functions.wolfram.com/GammaBetaErf/Pochhammer/27/01/0005/

    Examples
    ========

    >>> from sympy.simplify import gammasimp
    >>> from sympy import gamma, Symbol
    >>> from sympy.abc import x
    >>> n = Symbol('n', integer = True)

    >>> gammasimp(gamma(x)/gamma(x - 3))
    (x - 3)*(x - 2)*(x - 1)
    >>> gammasimp(gamma(n + 3))
    gamma(n + 3)

    c                 <    h | ]}t          |t                    |S  )
isinstancer   ).0is     8lib/python3.11/site-packages/sympy/simplify/gammasimp.py	<setcomp>zgammasimp.<locals>.<setcomp>C   s'    333AjE223a333    c                 ^    g | ]*}t                      | |j        d  |j        D              f+S )c                 0    g | ]}t          |d           S )Fas_comb)
_gammasimp)r   as     r   
<listcomp>z(gammasimp.<locals>.<listcomp>.<listcomp>K   s2     $? $? $?12
1e,,,$? $? $?r   )r   funcargs)r   fis     r   r"   zgammasimp.<locals>.<listcomp>J   s`     " " "  WWb'"' $? $?68g$? $? $? @ A" " "r   Fr   )
rewriter   atomsr   as_dummyzipr   xreplacedictr    )exprfgammasdumfunsimpds          r   	gammasimpr3   
   s   d <<D
 	

8A33333F KA	DMMOO!!(+++A K " " ajj" " " #S$ MM$s3}}--..!U+++44T#c4..5I5IJJJdE****r   c                 \   |                      t          d           } r|                      t          d           } n|                      t          d           } dfd	t          |           } |          } | |k    rt          |           } |                      t          d           } | S )a;  
    Helper function for gammasimp and combsimp.

    Explanation
    ===========

    Simplifies expressions written in terms of gamma function. If
    as_comb is True, it tries to preserve integer arguments. See
    docstring of gammasimp for more information. This was part of
    combsimp() in combsimp.py.
    c                 L    t          d| dz
                                            S N   )_rfexpandns    r   <lambda>z_gammasimp.<locals>.<lambda>a   s    #a!a%))** r   c                 &    t          |dz             S r6   r   r!   bs     r   r<   z_gammasimp.<locals>.<lambda>e   s    q1u r   c                 F    t          | |z             t          |           z  S Nr>   r?   s     r   r<   z_gammasimp.<locals>.<lambda>h   s    q1ueAhh. r   r   c                 "  ()*+,- | j         r| S d ,+fd+dk    r! | j        /fd| j        D              } dz  | j        s| S dk    rX|                                 \  }}|s| S |r6 /t          j        |          dz             t          j        |          z  S dz  dk    r?t          | j        +d          \  }}t          | }t          | }|                                \  }*t          d          D ]}	t          t          t          j        |                              }t          |          D ]_\  }
}|j        rSt          *,/fd	|j        D                                              \  }*|||
<   *                    t"                    s n`t          | }|	dk    r +|          s n*|c}*||z  *z  } | j        r +*          s +|          s| S dz  d
k    r	 | } /| d          } | |k    r| S g }g }g }g }d }t          t          | j                            }|r|                                                                \  }} ||          \  }}|r|                    |           n|du r|                    |            ||          \  }}|r|                    |           n|du r|                    |           |.s|||f|||ffD ]K\  }}}g }|r8|                                }|j        r|                    |           4t          |          D ]\  }
}||z   dz
  }|j        s|                    t.          j                   |                    t3          t.          j        |z                       |                    |
           |dk    r.t          |          D ]}|                    d|z
  |z              n2|dk     r,t          |           D ]}|                    | |z
              n|                    |           |8||dd<   M||||f||||ffD ]+\  }}}} 	 |D ]}!|D ]}"|!d|"z  z
  }|j        r n nn|                    |!           |                    |"           |dk    r.t          |          D ]}|                    d|"z  |z              n7|dk     r1t          |           D ] }|                     d|"z  dz
  |z
             !|                    |"t.          j        z              |                    dd|"z  dz
  z             |                     t9          t.          j                             "-d ((fd}#|||f|||ffD ]\  }}} |#|||           dk    r3)-fd}$i --fd))-fd}%||z   |z   |z   D ]}  |%|            |||f|||ffD ]\  }}}g }|r|                                }&d}'|'rd}' |$||&          }"|"H|                    |"           |"|&k    r&|                    |"|&z              |%|"|&z             |&dz  }&d}' |$||&dz
            }"|"Q|                    |"           |"|&dz
  k    r,|                    |&dz
  |"z              |%|&dz
  |"z             |&dz  }&d}'|'|                    |&           |||dd<   t          d |D              t          d |D              z  t          | z  t          | z  S )z/ Simplify products of gamma functions further. c                     |                      t                    }|                     t          d           }|                     t                    |k     r|} | S )Nc                     t          d| dz
                                                                t           d           S )Nr7   c                 F    t          | |z             t          |           z  S rB   r>   r?   s     r   r<   zU_gammasimp.<locals>.rule_gamma.<locals>.gamma_rat.<locals>.<lambda>.<locals>.<lambda>t   s    E!a%LLq,A r   )r8   r9   replacer:   s    r   r<   zC_gammasimp.<locals>.rule_gamma.<locals>.gamma_rat.<locals>.<lambda>s   s8    CAE>>3C3C - -'#AABB r   )countr   rG   )xwasxxs      r   	gamma_ratz1_gammasimp.<locals>.rule_gamma.<locals>.gamma_ratp   sU    ''%..C5 #C #C D DBxx$ Hr   c                     t          | t                    rdS | j        s| j        r t	          fd| j        D                       S | j        r(| j        j        s| j	        j
        r | j	                  S dS )NTc              3   .   K   | ]} |          V  d S rB   r   )r   xigamma_factors     r   	<genexpr>zG_gammasimp.<locals>.rule_gamma.<locals>.gamma_factor.<locals>.<genexpr>~   s-      ==<<++======r   F)r   r   is_Addis_Mulanyr$   is_Powexp
is_integerbaseis_positive)rI   rP   s    r   rP   z4_gammasimp.<locals>.rule_gamma.<locals>.gamma_factory   s    !U## tx >18 >====af======x ,QU- ,1C ,#|AF+++5r   r   c                 .    g | ]} |d z             S r7   r   )r   rI   level
rule_gammas     r   r"   z2_gammasimp.<locals>.rule_gamma.<locals>.<listcomp>   s)    KKKAzz!UQY77KKKr   r7      T)binaryc                 F    g | ]}  |z            d z             S r[   r   )r   r!   ddrL   r\   r]   s     r   r"   z2_gammasimp.<locals>.rule_gamma.<locals>.<listcomp>   sH     'U 'U 'UGHJJyy2	BB'U 'U 'Ur         c                     | t           j        u rd g fS |                                 \  }}|j        r0t	          |t
                    rd|j        d         g|z  fS d|g|z  fS d| gfS )NTr   F)r   Oneas_base_exp
is_Integerr   r   r$   )pr@   es      r   	explicatez1_gammasimp.<locals>.rule_gamma.<locals>.explicate   sy    AEz  Rx==??DAq| "a'' (!&)Q.. 1#a%<'qcz!r   FNc                   
 t          t          |                     t          t                              D ]

fdt          
dz   t                              D             }|D ]\  }}|j        dk    r|j        dk    r|j        }
g}t          t          d|                    }|D ]C\  }}||z  }|j        r2||v r.|                    |           |                    |           |s nDt          |          D ]'\  
}|         }	|                     |	           |	|
<   (|j        |d         |dd          fc c S ݐd S )Nc                 <    g | ]}|                  z
  d z  |fS r[   r   )r   jr   us     r   r"   z@_gammasimp.<locals>.rule_gamma.<locals>._run.<locals>.<listcomp>+  s/    PPPaQqTAaD[A-q1PPPr   r7   r   )
listr   rangelenrh   qrg   removeappend	enumerate)coeffsdjonerm   r;   gotgetr2   mcr   rn   s             @@r   _runz,_gammasimp.<locals>.rule_gamma.<locals>._run&  s    f&&s1vv : :APPPPP5QA;O;OPPPB"$ : :Q5A: :#%1* : #A#$#C"&uQ{{"3"3C(* ) )1$%aC#$< !.AH !.$'JJqMMM$'JJqMMM+. %.(- ((1# + +1$%aD &a 0 0 0)*A#&5#a&#abb'#999999%:: :r   c                    i }| D ]B}|                                 \  }|                    g                               |           Ct          |t                    }|D ] t          t          |                             }g }	  |          }	|	n|	\  }
}}|D ]D}|z   dz
  }t          t          ||z
                      D ]}|                    ||z
             E|
|z   z  }|                    dt          j	        z  t          |
dz
            dz  z  |
t          j
        |z
  z  z             |                    |           Ĉfd|D             |z   |<   g }|D ]||         z  }|| d d <   d S )N)keyTr7   r^   c                     g | ]}|z   S r   r   )r   r|   resids     r   r"   zE_gammasimp.<locals>.rule_gamma.<locals>._mult_thm.<locals>.<listcomp>k  s    "="="=519"="="=r   )as_coeff_Add
setdefaultrt   sortedr	   ro   rp   intr   PiHalf)r.   numerdenomratsgr|   keysrv   newrunr;   uiotherrn   conkr   r}   s                   @r   	_mult_thmz1_gammasimp.<locals>.rule_gamma.<locals>._mult_thm@  s   
  9 9A ~~//HAuOOE2..55a8888 d(8999! D DE!&e"5"566FC("d6ll "! (+2u "' 6 6A"'!)a-C%*3q2v;;%7%7 6 6 %S1W 5 5 5 56  n af!a%
%;%&#%6&7 8 8 8 

33(8 #>"="="=f"="="="CDKK ! % %Ee$AAqqq			r   c                    | sd S  
|          \  }}| D ]}|         \  }}||k    s9|                     |          s%|t                      k    s|t                      k    rMt          t          ||z            j                  }t          |j                  }t          |j                  }	|dk    r|dk    s|	dk    r|c S d S )Nr   )intersectionsetrq   r   free_symbols)lrI   S1T1yS2T2r!   r@   r|   
compute_STinvs             r   
find_fuzzyz2_gammasimp.<locals>.rule_gamma.<locals>.find_fuzzy  s     F#AB ! !A VFBRx !(;(; !%'355[!46#%%K!  F1Q3KK455AAN++AAN++AAv !1q5 !AE ! ! !r   c                     | v r|          S | j         |                     t                                        d |                     t                    D                       fS )Nc                     h | ]	}|j         
S r   )rV   )r   ri   s     r   r   zE_gammasimp.<locals>.rule_gamma.<locals>.compute_ST.<locals>.<setcomp>  s    8881888r   )r   r'   r   unionr   )r,   r   s    r   r   z2_gammasimp.<locals>.rule_gamma.<locals>.compute_ST  sb    3; %t9$)4::h+?+?+E+E88

3888,: ,: ; ;r   c                 $     |           | <   d S rB   r   )r,   r   r   s    r   	update_STz1_gammasimp.<locals>.rule_gamma.<locals>.update_ST  s    &Jt,,D			r   c                 ,    g | ]}t          |          S r   r>   r   r   s     r   r"   z2_gammasimp.<locals>.rule_gamma.<locals>.<listcomp>  s    444!U1XX444r   c                 ,    g | ]}t          |          S r   r>   r   s     r   r"   z2_gammasimp.<locals>.rule_gamma.<locals>.<listcomp>  s    333E!HH333r   )is_Atomr#   r$   rS   args_cncr   
_from_argsr   as_numer_denomrp   ro   r   	make_argsru   rR   r   hasr   popextendrW   rt   rg   r   r   r   rs   r   r   )0r,   r\   r$   ncTF	gamma_indr2   ndipassr   nirJ   numer_gammasdenom_gammasnumer_othersdenom_othersrj   newargsr;   isgr   r.   r   r   r   g1g2r   ngdgnodorI   r   r   r   r   r   contr}   r   ra   rP   rL   r   r   r]   s0    `                                      @@@@@@r   r]   z_gammasimp.<locals>.rule_gammaj   s	    < 	K	 	 		 	 	 	 	 A: 	49KKKKKKKKLDQJE{ 	K A: 	}}HD"  V!z#."6"6	BB3>RTCUCUUUQJE A: 		<===DAqQIQA%%''FBq    GCM"$5$56677&t__ " "EAry "!$ 'U 'U 'U 'U 'U 'U 'ULNG'U 'U 'U ",n.. B #%Q!vve}} "!E$ZQ; ||B'7'7 ERBBR<?DK \\"%5%5 b9I9I QJE A: 	  !z$**3;  K	  
	" 
	" 
	" wty))** 	';;==//11DAqYq\\FC '##A&&&& '##A&&&Yq\\FC '##A&&&& '##A&&&  	'  `	+ lL*:!<>)@    $u  'B} !

2 !*6!2!2 ' '2GaK | %$QT***Sb\\222

1q5 6%*1XX 9 9 %QVaZ 8 8 8 89U 6%*A2YY 6 6 %bS1W 5 5 5 5

2)  ',  qqq		 %1,$0$2$0,$0$2#3 * *BB
* 	 	!# % %A !AaCA | & %& %IIaLLLIIaLLL1u 3!&q / /AIIacAg..../Q 3!&r 3 3AIIacAgk2222IIa!&j)))IIa!A#'l+++IId14jj)))+* :: : :42 2 2 2 2h &2<$N%1<$N$P + +5%	!UE**** A: E	 
! ! ! ! ! !0 C; ; ; ; ;- - - - - -$|3lB\Q    	$ lL*:!<>)@    $u  "

AD ($&Jua00 (!LLOOO Av / %QqS 1 1 1 )	!A#FA#'D&Jua!e44 (!LLOOO AEz 5 %a!eQY 7 7 7 )	1q5!) 4 4 4FA#'D#  ($ JJqMMM+  ".  qqq		 44|444533l33345< !#&#56 	6r   c                 f    | j         rt          t          |                     nt          |           S rB   )is_Rationalr
   r   r:   s    r   r<   z_gammasimp.<locals>.<lambda>  s&    1=F+eAhh'''eAhh r   )r   )rG   r   r8   r   )r,   r   rJ   r]   s    ` @r   r    r    T   s     <<**, ,D  0||C%%' ' ||C..0 0[6 [6 [6 [6 [6 [6 [6z
 ,,C:c??Ds{ d||<<FFH HD Kr   c                   $    e Zd Zed             ZdS )r8   c           	      L   |j         rw|st          j        S t          |          }|dk    r"t	          fdt          |          D              S |dk     r*dt	          fdt          d| dz             D              z  S d S |j        rv|                                \  }}|j         rX|dk    r$t          |          t          |z   |          z  S |dk     r(t          |          t          |z   |z   |           z  S j        r                                \  }}|j         r|dk    r5t          ||          t          ||z   |          z  t          ||          z  S |dk     rAt          ||          t          ||z   |           z  t          ||z   |z   |           z  S d S d S d S )Nr   c                     g | ]}|z   S r   r   r   r   r!   s     r   r"   z_rf.eval.<locals>.<listcomp>  s    555qQU555r   r7   c                     g | ]}|z
  S r   r   r   s     r   r"   z_rf.eval.<locals>.<listcomp>  s    ???q1u???r   )	rg   r   re   r   r   rp   rR   r   r8   )clsr!   r@   r;   r|   _b_as    `     r   evalz_rf.eval  s   < 	N uAA1u A5555E!HH55566Q A????eArAv.>.>???@@@A A x >((2< >1u >"1bzz#a"fa..88Q >"1bzz#a"fqj1"*=*===x N((2< N1u N"2qzz#b1fa..8RCCQ N"2qzz#b1fqb//9#b1fqj1":M:MMMN NN NN Nr   N)__name__
__module____qualname__classmethodr   r   r   r   r8   r8     s2        N N [N N Nr   r8   N)
sympy.corer   r   r   r   r   sympy.core.sortingr   r	   sympy.core.functionr
   sympy.core.symbolr   sympy.functionsr   r   r   sympy.polysr   r   sympy.utilities.iterablesr   r   r3   r    r8   r   r   r   <module>r      s   1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 8 8 8 8 8 8 8 + + + + + + # # # # # # , , , , , , , , , , & & & & & & & & 0 0 0 0 0 0 0 0G+ G+ G+T| | |~N N N N N( N N N N Nr   