home *** CD-ROM | disk | FTP | other *** search
-
- (* :Copyright: Copyright 1991 Wolfram Research, Inc.
- Permission is hereby granted to modify and/or make copies of
- this file for any purpose other than direct profit, or as part
- of a commercial product, provided this copyright notice is left
- intact. Sale, other than for the cost of media, is prohibited.
-
- Permission is hereby granted to reproduce part or all of
- this file, provided that the source is acknowledged.
- *)
-
- (* :Version: Mathematica 2.1 *)
-
- (* :Title: PolyGamma-functions Simplifications *)
-
- (* :Author:
- Victor S. Adamchik, October 1991.
- *)
-
- (* :Context: Simplify`PolyGamma` *)
-
- (* :Keywords: polygamma *)
-
- (* :Requirements: none. *)
-
- (* :Warnings: none. *)
-
- (* :Limitations: none known. *)
-
- (* :Summary:
- This package allows to simplify any expressions with
- PolyGamma-functions using a sequence of 10 rules which
- apply to the expression.
- *)
-
- (*========================================================================*)
-
- Begin["System`"]
-
- SimplifyPolyGamma::usage =
- "SimplifyPolyGamma[expr] performs a sequence of polygamma-function
- transformations on expr, and returns the simplest form it finds."
-
- Begin["Simplify`PolyGamma`Private`"]
-
- (*========================================================================*)
-
- Unprotect[ SimplifyPolyGamma]
-
- SimplifyPolyGamma[ expr_ ] := SimpPolyGamma[expr//Simplify]
-
- SimpPolyGamma[f_Times] := SimpPolyGamma[#]&/@f
-
- SimpPolyGamma[ expr_/;!FreeQ[Denominator[expr],PolyGamma[___]] ] :=
- SimpPolyGamma[Numerator[expr]] / SimpPolyGamma[Denominator[expr]]
-
- SimpPolyGamma[ expr_ ] :=
- SimpPolyGammaG[ Expand[expr/.PolyGamma[v_] :> PolyGamma[0,v]] ]
-
- SimpPolyGammaG[ expr_/;FreeQ[expr,PolyGamma[___]] ] := expr
-
- SimpPolyGammaG[ PolyGamma[a_,b_]^n_.] := SimpPolyGammaN[{{{a,b},1}}]^n
-
- SimpPolyGammaG[ expr_Plus ] :=
- Block[ { PolyGamma, answer,exprnew,
- rr = Cases[expr,s_. PolyGamma[a__]^n_], rrr},
- exprnew = expr-Plus@@rr-
- (rrr=Plus@@Cases[expr,a_/;FreeQ[a,PolyGamma[__]]]);
- answer = Plus@@(SimpPolyGamma[#]&/@rr) + rrr;
- answer +=
- If[ FreeQ[ exprnew,PolyGamma[__]],
- exprnew,
- rrr = If[ MatchQ[exprnew, s_. PolyGamma[a__]],
- {exprnew},
- Cases[exprnew,s_. PolyGamma[a__]]
- ];
- rr = exprnew-Plus@@rrr;
- If[ rr === exprnew, SimpPolyGamma[exprnew],
- SimpPolyGamma[exprnew-Plus@@rrr] +
- SimpPolyGammaN[ rrr/.
- PolyGamma[a_,b_] n_. :> If[ FreeQ[n,PolyGamma],
- {{a,Expand[b]},n}, FailS] ]
- ]
- ];
- If[ FreeQ[answer, FailS], answer, expr ]
- ]
-
- SimpPolyGammaG[ f_[expr___] ] := f@@(SimpPolyGamma[#]&/@{expr})
-
- SimpPolyGammaN[ expr_ ] := FailS/; !FreeQ[expr,FailS]
-
- SimpPolyGammaN[ expr_ ] :=
- Module[ { rr = expr, i = 0, answer = 0, max },
- max = Max[(#/.{{a_,_},_} :> a)&/@expr];
- While[ i <= max,
- answer +=
- Multiplication[new = Cases[rr, {{i,_},_}]];
- rr = Complement[rr, new]; i+=1
- ];
- answer
- ]
-
- Multiplication[ expr_ ] :=
- If[ Length[expr]<2,
- SimpPolyGamma1[expr]
- ,
- Block[ { SimpPolyGamma1 },
- (MultiplicationVar[Cases[expr,{{_,a_/;!NumberQ[a]},_}],False] //.
- SimpPolyGamma1[a_] + SimpPolyGamma1[b_] :>SimpPolyGamma1[Join[a,b]])
- +
- (MultiplicationVar[Cases[expr,{{_,a_/;NumberQ[a]},_}],True] //.
- SimpPolyGamma1[a_] + SimpPolyGamma1[b_] :>SimpPolyGamma1[Join[a,b]])
- ]
- ]
-
- MultiplicationVar[ expr_, const_ ] :=
- If[ Length[expr]<2,
- SimpPolyGamma1[expr]
- ,
- Module[ { r, rr },
- If[ const,
- r = (#/.{{_,n_Rational},d_}:>
- {0,d})&/@(rr=Cases[expr, {{_,n_Rational},_}]),
- r = (#/.{{_,n_Rational+s},d_}:>
- {s,d})&/@(rr=Cases[expr, {{_,n_Rational+s},_}])
- ];
- Plus@@(MultiplicationVar1[Sort[#]]&/@(
- Cases[rr, {{_,n_Rational + #[[1]]},#[[2]]}]&/@Union[r])) +
- SimpPolyGamma1[Complement[expr,rr]]
- ]
- ]
-
- MultiplicationVar1[ expr_ ] :=
- If[ Length[expr]<2,
- SimpPolyGamma1[expr]
- ,
- Module[ { var, flag, max, univ, p=expr[[1,1,1]], r=expr[[1,2]] },
- var = expr[[1,1,2]]/.{n_Rational+s_. :> s+Floor[n]};
- flag = If[Positive[expr[[1,1,2]]-var],1,-1];
- max = Max[(#/.{{_,s_},_}:>Denominator[s-var])&/@expr];
- univ = Complement[Table[
- {{p,i/max flag+var},r},{i,max-1}],expr];
- If[ max - Length[univ] > Floor[max/2] + 1,
- If[IntegerQ[var] && Negative[var],
- r ( If[ p==0, (1-max) EulerGamma,
- (max^(p+1)-1) (-1)^(p+1) p! Zeta[p+1]
- ] +
- max^(p+1) p! Sum[1/i^(p+1),{i,-max var}] -
- p! Sum[1/i^(p+1),{i,-var}] -
- If[p==0, max Log[max], 0] )
- ,
- If[ flag == 1,
- SimpPolyGamma1[{{{p,Expand[max var]}, max^(p+1) r},
- {{p,var},-r} }] -
- If[p==0, r max Log[max], 0],
- SimpPolyGamma1[{{{p,Expand[max var-max]}, max^(p+1) r},
- {{p,var-1},-r} }] -
- If[p==0, r max Log[max], 0]
- ]
- ] +
- SimpPolyGamma1[ Join[Complement[ Join[expr,univ],
- Table[{{p,i/max flag+var},r}, {i,max-1}]
- ], (#/.{{a_,b_},c_}:>{{a,b},-c})&/@univ ]]
- ,
- rr = Cases[Union[expr],{{_,a_/;Denominator[a-var]==max},_}];
- SimpPolyGamma1[rr] +
- MultiplicationVar1[
- Delete[expr,Flatten[Position[expr,#]&/@rr,1]]]
- ]
- ]
- ]
-
- SimpPolyGamma1[ {} ] := 0
-
- SimpPolyGamma1[ expr_ ] :=
- Module[ { new, exprnew=expr, i=1, answer=0 },
- While[ i<=3 && Length[exprnew]!=0,
- answer +=
- If[ i==3, Plus@@(function[#[[1]],i]&/@(new=FindListCond[exprnew, i])),
- Plus@@(Fold[ function[#1, #2, i]&,
- #[[1]], Rest[#] ]&/@(new=FindListCond[exprnew, i])) ];
- If[ !FreeQ[answer,polygamma]&&i!=3,True,i+=1];
- exprnew = Join[ ComplementNotSet[exprnew,Flatten[new,1]],
- If[MatchQ[answer,s_. polygamma[a__]],
- {answer},
- Cases[answer,s_. polygamma[a__]]
- ]/.s_. polygamma[w1_,w2_] :>{{w1,w2},s}
- ];
- answer = answer/.polygamma[__]:>0
- ];
- SimpLog[answer] + Plus@@(Times[PolyGamma@@#[[1]], #[[2]]]&/@exprnew)
- ]
-
- FindListCond[ {v1___, {{p_,u_},n_},v2___ }, 3 ] :=
- Join[ {{{{p,u},n}}}, FindListCond[{v1,v2}, 3] ] /;
- IntegerQ[u] || RationalQ[u]
-
- FindListCond[ {v1___, {{p_,u_},n_}, v2___, {{p_,v_},m_}, v3___},c_/;c!=3] :=
- Join[ {{{{p,u},n},{{p,v},m}}}, FindListCond[{v1,v2,v3}, c] ] /;
- cond[{{p,u},n},{{p,v},m}, c]
-
- FindListCond[___] := {}
-
- cond[{{p_,u_/;!IntegerQ[u]},n_},{{p_,v_},m_}, 1] :=
- IntegerQ[u+v] && If[ EvenQ[p], Znak[m n], !Znak[m n]]
-
- cond[{{p_,u_},n_},{{p_,v_},m_}, 2] := IntegerQ[u-v] && Negative[m n]
-
- function[{{p_,u_},n_},{{p_,v_},m_}, 1] :=
- If[ n+m===0,
- If[ Positive[u+v],
- -m p! Sum[ 1/(u-k)^(p+1), {k, 0, u+v-1} ],
- m p! Sum[ 1/(u+k)^(p+1), {k, 1, -u-v} ]
- ] -
- n Pi Module[ { y }, Pi^p D[Cot[y],{y,p}]/.y ->Expand[Pi u] ] -
- (-1)^p n p!/u^(p+1)
- ,
- If[ FreeQ[ {n,m},Complex] && NumberQ[n] && NumberQ[m],
- If[ Positive[u+v],
- -m p! Sum[ 1/(u-k)^(p+1), {k, 0, u+v-1} ],
- m p! Sum[ 1/(u+k)^(p+1), {k, 1, -u-v} ]
- ] -
- Sign[n] Min[Abs[n], Abs[m]]*
- ( Pi Module[ { y }, Pi^p D[Cot[y], {y,p}]/.y->Expand[Pi u] ] +
- (-1)^p p!/u^(p+1)) +
- (n-Sign[n] Min[Abs[n], Abs[m]]) polygamma[p,u] +
- Sign[m] (Abs[m]-Min[Abs[n], Abs[m]]) polygamma[p,-u],
- n PolyGamma[p,u] + m PolyGamma[p,v]
- ]
- ]
-
- function[{{1,1/4},n_}, 3] := n(Pi^2 + 8 Catalan)
- function[{{1,3/4},n_}, 3] := n(Pi^2 - 8 Catalan)
- function[{{k_,1},n_}, 3] := (-1)^(k+1) k! n Zeta[k+1]
- function[{{k_,1/2},n_},3] := (-1)^(k+1) k! n Zeta[k+1] (2^(k+1)-1)
- function[{{0,k_/;0<k<1},n_},3] :=
- n(-EulerGamma - Log[2 Denominator[k]] -
- Pi Cos[Pi k]/(2 Sin[Pi k]) +
- 2 Sum[Cos[2 k i Pi] Log[Sin[Pi i/Denominator[k]]],
- {i,1,Floor[(Denominator[k]-1)/2]}])
- function[{{p_,k_Integer},n_},3] :=
- (-1)^p p! n (-Zeta[p+1]+Sum[i^(-p-1),{i,k-1}])
- function[{{p_,k_/;k>1 || k<0},n_},3] :=
- If[ k>1, n(-1)^p p!(k-1)^(-p-1) + function[{{p,k-1},n},3],
- -n(-1)^p p!k^(-p-1) + function[{{p,k+1},n},3]
- ]/; p==0 || Denominator[k]==2 || Denominator[k]==4
- function[{{p_,k_},n_},3] := n polygamma[p,k]
- function[{{p_,u_},n_},{{p_,v_},m_}, 2] :=
- If[ Positive[u-v],
- n p! (-1)^p Sum[ 1/(v+k)^(p+1), {k, 0, u-v-1} ] +
- (n+m) polygamma[p,v],
- m p! (-1)^p Sum[ 1/(u+k)^(p+1), {k, 0, v-u-1} ] +
- (n+m) polygamma[p,u]
- ]
-
- ComplementNotSet[ list1_, list2_ ] :=
- If[ list2==={}, list1,
- Join[ Complement[list1,list2],
- ComplementNotSet[SameElem[list1],SameElem[list2]]
- ]
- ]
-
- SameElem[ {v1___,e1_,v2___,e2_,v3___} ] :=
- Join[{e1},SameElem[{v1,v2,v3,e2}]] /; e1===e2
-
- SameElem[ ___ ] := {}
-
- RationalQ[ s_ ] := If[ Head[s]===Rational, True, False ]
-
- Znak[ s_?Negative ] := True
- Znak[ s_?Negative w_ ] := True
- Znak[ _ ] := False
-
- SimpLog[ expr_/; !FreeQ[expr,Log[_]] ] :=
- Module[ {exprN = Expand[expr],list,div,pos = {},i=0 },
- exprN = exprN//.{
- Log[a_Power] :> a[[2]] Log[a[[1]]] /;NumberQ[N[a]],
- Log[a_ s_./;NumberQ[N[a]]] :>
- Log[Numerator[a]]-Log[Denominator[a]]+Log[s]
- };
- list = Union[Cases[exprN,w_. Log[n_Integer]/;FreeQ[w,Log[_]]]/.
- w_. Log[n_] :> n];
- div = GCD@@list;
- If[ Length[list]>1 && div!=1,
- list = Complement[list,{div}];
- SimpLog[exprN//.BuildRule[
- Log[#]&/@list ,Log[div]+Log[#]&/@(list/div) ]]
- ,
- If[ Length[list]<=2,
- exprN
- ,
- While[Length[pos]==0 && Length[list]>1,
- i = i+ 1;
- listN = {list[[1]],#}&/@Rest[list];
- list = Rest[list];
- pos = Position[ (GCD@@#)&/@listN,a_/; a != 1 ]
- ];
- If[ Length[pos]!=0,
- list = Take[listN,pos[[1]]][[1]];
- div = GCD@@list;
- SimpLog[exprN//.BuildRule[Log[#]&/@list ,
- Log[div]+Log[#]&/@(list/div) ]]
- ,
- exprN
- ]
- ]
- ]
- ]
-
- SimpLog[ expr_ ] := expr
-
- BuildRule[{l_,lR___},{r_,rR___}] :=
- Join[{l :> r},BuildRule[{lR},{rR}]]
-
- BuildRule[{},{}] := {}
-
-
- (*========================================================================*)
-
- End[] (* Simplify`PolyGamma`Private` *)
-
- SetAttributes[SimplifyPolyGamma, { ReadProtected, Protected } ];
-
- End[] (* System` *)
-
- (*========================================================================*)
-
-