          /** Canonical form of gamma functions **/

/*K: Gamma functions; canonical form; factorials  */
/*A: John Gottschalk */
/*S: University of Western Australia */
/*D: February 1985 */

/*: GammaConv[$expr,($r)]
          rewrites all the parts in $expr containing $r in terms of 
	  Gamma[$r+$$b] where possible. Substitutions SGammaSpec[$r],
	  SGammainit and SGammaConv[$r] are used. 
	  GammaConv[$expr] converts $expr to Gamma functions. */
GammaConv_:Tier
GammaConv[$x,$r] :: S[Ap[GamB[Num[$1],$r]/GamB[Den[$1],$r],\
   {S[S[S[Cb[$x,{$r}],{SGammaC, SGammaSpec[$r]}],SGammaInit[$r]],\
   SGammaConv[$r]]}],SGammaInit[$r]]

GammaConv[$x] :: S[$x,SGammaC]

/* SGammaC are substitutions converting various special functions to 
	Gamma functions. At present these convert factorials, pochammers 
	and combinatorials. */
SGammaC[1] : Poc[$a,$b]  --> Gamma[$b+$a]/Gamma[$a]
SGammaC[2] : Fctl[$a]    --> Gamma[$a+1]
SGammaC[3] : Comb[$a,$b] --> Gamma[$a+1]/(Gamma[$b+1] Gamma[$a-$b+1])


/*: SGammaSpec[$r][$i] 
	are substitutions used to rewrite sums of expressions in terms
	of Gamma functions. Only sums that yield true when the predicate
	Simplep is applied are converted. */
SGammaSpec_:Ldist;
SGammaSpec[$r][1] : ($$a $r+($$c_=Simplep[$$c/$$a]))       --> ($r+$$c/$$a) $$a
SGammaSpec[$r][2] : ($r/$b+($$c_=Simplep[$$c $b]))         --> ($r+$$c $b)/$b
SGammaSpec[$r][3] : ($$a $r/$b+($$c_=Simplep[$$c $b/$$a])) --> \
							($r+$$c $b/$$a) $$a/$b

SGammaInit[$r] : Gamma[$x]  --> Gamma[Cb[Ex[$x],{$r}]]

/*: SGammaConv[$r][$i]
	      are substitutions used to rewrite Gamma functions containing
	      $r in terms of Gamma functions of the form Gamma[$r+$$b]. 
	      Substitution SGammainit should be used first. */
SGammaConv[$r][1] : Gamma[$$a+($k_=Natp[$k]) $r]  --> (2Pi)^((1-$k)/2) \
		    $k^($$a+$k $r-1/2) Prod[Gamma[($$a+%#s)/$k+$r],{%#s,0,$k-1}]
SGammaConv[$r][2] : Gamma[($k_=Natp[$k]) $r]      --> (2Pi)^((1-$k)/2) \
		      $k^($k $r-1/2) Prod[Gamma[%#s/$k+$r],{%#s,0,$k-1}]
SGammaConv[$r][3] : Gamma[$$a+($k_=Natp[-$k]) $r] --> (-1)^($k $r) Gamma[1-$$a]\
		      Gamma[$$a]/( (2Pi)^((1+$k)/2)(-$k)^(1-$$a-$k $r-1/2)\
		      Prod[Gamma[(1-$$a+%#s)/(-$k)+$r],{%#s,0,-$k-1}])
SGammaConv[$r][4] : Gamma[($k_=Natp[-$k]) $r]     --> (-1)^($k $r) Gamma[0]/\
		      ( (2Pi)^((1+$k)/2)(-$k)^(1-$k $r-1/2)\
		      Prod[Gamma[(1+%#s)/(-$k)+$r],{%#s,0,-$k-1}])

/*: GamB[$expr,$r] 
	converts terms of the form ($r+$$a) to Gamma[$r+$$a+1]/Gamma[$r+$$a]
	in $expr when $expr is a product of these terms. */
GamB_:Tier

GamB[($r+$$a),$r]        :  Gamma[$r+$$a+1]/Gamma[$r+$$a]
GamB[($r+$$a)^$n,$r]     :  Gamma[$r+$$a+1]^$n/Gamma[$r+$$a]^$n
GamB[($r+$$a) $$b,$r]    :: Gamma[$r+$$a+1]/Gamma[$r+$$a] GamB[$$b,$r]
GamB[($r+$$a)^$n $$b,$r] :: Gamma[$r+$$a+1]^$n/Gamma[$r+$$a]^$n GamB[$$b,$r]
GamB[$x_=$x[0] = 'Div ,$r] :: Map[GamB[$1,$r],$x]
GamB[$x_=$x[0] = 'Plus,$r] :: Map[GamB[$1,$r],$x]
GamB[$x,$r]              :  $x

/*: Simplep[$expr]
	is a heuristic rule for deciding if some of the gamma function
	transformations should be applied to $expr. If projectors other
	than 'Plus, 'Div and 'Mult appear in $expr then Simplep[$expr]
	returns false. To override this declare
	that everything is simple by Simplep[$expr] : 1. */
Simplep[$expr] :: Len[Del['Plus,Del['Mult,Del['Div,Cont[$expr,Heldp]]]]]=0

/*W: SGammaConv is incorrect in the case of Natp[a] & (a-kr <= 0 <= a-1). In
      this case the formula is 
      Gamma[a-kr] = (-1)^(kr+1) Gamma[1-a] Gamma[a]/Gamma[1-a+kr].
      However it usually happens there is a cancelling (-1) from another term
      as without another like term the expression conatining Gamma[a-kr] is 
      singular */

_XGammaConv[Loaded] : 1

/*E:
SMP 1.5.0   (May 14 1986)

#I[1]::  <XGammaConv

#I[2]::  m/c+d/c

	 d   m
#O[2]:   - + -
	 c   c

#I[3]::  Simplep[%]

#O[3]:   1

#I[4]::  m + Gamma[m]

#O[4]:   m + Gamma[m]

#I[5]::  Simplep[%]

#O[5]:   0

#I[6]::  Simplep[$expr] : 1

#O[6]:   1

#I[7]::  Simplep[@4]

#O[7]:   1
*/
