# This is a Maple 7, 8 and 9 package for computing recurrence relations closed form expressions # and uniformly bounded convergence of non-terminating hypergeometric series # (c) Raimundas Vidunas, University of Amsterdam, 2000-2001; # at present at Kyushu University, Hakozaki, Fukuoka, Japan # Supported by the Dutch NWO, project number 613-06-565. # # Function "infsumrecuresion" computes the recurrence relation for # non-terminating hypergeometric series. # Input: like in Koepf's sumrecursion (without options). # Output: [ recursion relation, certificate, # conditions on parameters if necessary ], # or error message, if series does not converge absolutely. # # Function "infclosedform" computes a closed form (2 or 3-term) expression # for non-terminating hypergeometric series, in terms of # Gamma-function and (possibly) other hypergeometric series. # Works if the recurrence relation with respect to the suggested # variable has order one. # Input: the hypergeometric term term, # the hypergeometric summation variable k, # the recurrence relation variable n. # Output: the expression. # # Function "uniformconvergence" checks whether given non-terminating hypergeometric # series can be uniformly bounded by an absolutely convergent series. # Input: the hypergeometric term term, # the hypergeometric summation variable k, # the recurrence relation variable n. # Output: error messages, # or the termwise limit of the series as n->infinity. # # Function infhsumhelp() invokes package's help system # # These routines are not meant for terminating series # iHPGversion:= " Version 4.29, 30-Nov-2005.": ### Global variables iHPGDigits:= 14: iHPGUCstrict:= true: iHPGconditions: iHPGcertificate: iHPGerr1:= "The series does not converge, unless it is terminating": iHPGerr2:= "The series does not converge uniformly, unless it is terminating": iHPGerr3:= "The limit series does not exist/does not converge": print(`This is a Maple package for computing recurrence relations,`); print(`closed form expressions and uniformly bounded convergence of`); print(`non-terminating hypergeometric series; written by R. Vidunas`); print(iHPGversion); print(`tested in Maple 7, 8 and 9`); print(`Supported by NWO, project number 613-06-565`); print(`The help function is envoked by " infhsumhelp( ) "`); infhsumhelp:= proc( ) if args=NULL then printf(`This is a Maple 7, 8 and 9 package for computing recurrence relations,\n`); printf(` closed form expressions and uniformly bounded convergence\n`); printf(` of non-terminating hypergeometric series\n`); printf(" %s\n\n", iHPGversion); printf(`(c) Raimundas Vidunas, University of Amsterdam, 2000-2001;\n`); printf(`Supported by the Dutch NWO, project number 613-06-565\n\n`); printf(`at present at Kyushu University, Hakozaki, Fukuoka, Japan;\n`); printf(`URL: http://www.math.kyushu-u.ac.jp/~vidunas/\n\n`); printf(`We use Zeilberger's algorithm to compute recurrence relations,\n`); printf(`a modification of Wilf-Zeilberger's method to compute closed\n`); printf(`expressions. We use W. Koepf's Maple package\n`); printf(`"hsum9.mpl", where similar procedures are implemented for\n`); printf(`terminating hypergeometric series. Koepf's package can be downloaded from\n`); printf(`http://www.mathematik.uni-kassel.de/~koepf/Publikationen/index.html#down\n\n`); printf(`Our method is described in the following two papers:\n`); printf(`[1] R. Vidunas and T.H. Koornwinder, "Zeilberger method for\n`); printf(`non-terminating hypergeometric series", in preparation.\n`); printf(`[2] T.H. Koornwinder, "Identities of nonterminating series by\n`); printf(`Zeilberger's algortihm", J. Comput. Appl. Math., 99 (1998), 449-461.\n\n`); printf(`The commands: infsumrecursion, infclosedform, uniformconvergence.\n`); printf(`For more information please invoke infhsumhelp( command_name ).\n`); printf(`The first two commands are the analogues of Koepf's procedures\n`); printf(`"sumrecursion" and "closedform" for non-terminating series.\n`); printf(`Other reserved names of our package start with "iHPG...."`); elif args=`infsumrecursion` then print(`infsumrecursion(term, k, f(n))`); printf(`computes a recurrence relation of hypergeometric series`); print(`f(n)=sum(hterm, k=0..infinity)`); printf(`It uses Zeilberger's algorithm and checks the convergence\n`); printf(`of the relevant (Zeilberger's) telescoping sum and of the\n`); printf(`hypergeometric series itself. This command is based on\n`); printf(`Koepf's procedure "sumrecursion" (from his package "hsum9.mpl")\n`); printf(`which implements Zeilberger's algorithm for terminating series.\n`); printf(`If the relevant series does not convergence, an error message is\n`); printf(`displayed. If there are convergence conditions on the parameters,\n`); printf(`they are displayed as a warning, unless an option "conditions" is\n`); printf(`present. The command with all options is:`); print(`infsumrecursion(term, k, f(n), certificate, conditions)`); printf(`If "conditions" is present, then the convergence restrictions\n`); printf(`are returned in the output sequence after the computed recurrence\n`); printf(`If "certificate" is present, then a so-called certificate of a\n`); printf(`Zeilberger-type proof of the recurrence relation is returned,\n`); printf(`after the recursion and before the convergence conditions.`); elif args=`infclosedform` then print(`infclosedform(term, k, n)`); printf(`computes a closed form expression for the hypergeometric series`); print(`f(n)=sum(hterm, k=0..infinity)`); printf(`This command is based on Koepf's procedure "closedform" (from\n`); printf(`his package "hsum9.mpl"). The procedure is successful only if\n`); printf(`"infsumrecursion(term,k,s(n))" finds a first order recurrence\n`); printf(`relation (or a recurrence relation with two homogeneous terms),\n`); printf(`and the series is uniformly bounded (with respect to n) by an\n`); printf(`absolutely convergent series. For a single "initial" evaluation\n`); printf(`we use the limit n->infinity of the series. If the series does\n`); printf(`not converge uniformly (as described above) an error message is\n`); printf(`returned. If there are convergence conditions on the parameters,\n`); printf(`these conditions are returned as a warning unless the option\n`); printf(`"conditions" is present. The command with all options is\n`); print(`infclosedform(term, k, n=0, certificate, conditions, ucrelaxed)`); printf(`If "conditions" is present, then the convergence restrictions\n`); printf(`are returned in the output sequence after the computed recurrence\n`); printf(`The optional substitution "n=0" (instead of just a name "n") is\n`); printf(`performed after the computation; then the discrete parameter "n"\n`); printf(`is not seen in the output. (General substitutions are allowed).\n`); printf(`If "certificate" is present, then a so-called certificate of a\n`); printf(`Zeilberger-type proof of the hypergeometric identity is returned.\n`); printf(`If "ucrelaxed" is present, then in the case that the series\n`); printf(`can be majorized by a sum of O(k^p) with -1<=p<0, no error but a\n`); printf(`warning message is generated, and a conjectural expression is\n`); printf(`returned.`); elif args=`uniformconvergence` then print(`uniformconvergence(term, k, n)`); printf(`checks whether the hypergeometric series`); print(`f(n)=sum(term,k=0..infinity)`); printf(`is uniformly bounded (with respect to n) by an absolutely\n`); printf(`convergent series. If the series does not converge uniformly in\n`); printf(`this sense, an error message is returned. Otherwise the output is\n`); printf(`the limit n->infinity of the hypergeometric series. If there are\n`); printf(`convergence conditions on the parameters, these conditions are\n`); printf(`returned as a warning unless the option "conditions" is present.\n`); printf(`The command with all options is\n`); print(`uniformconvergence(term, k, n, conditions, ucrelaxed)`); printf(`If "conditions" is present, then the convergence restrictions\n`); printf(`are returned in the output sequence after the computed recurrence\n`); printf(`If "ucrelaxed" is present, then in the case that the series\n`); printf(`can be majorized by a sum of O(k^p) with -1<=p<0, no error but a\n`); printf(`but a warning message is generated, and a conjectural expression\n`); printf(`is returned.`); fi; end: infsumrecursion:= proc( term, k::name, f::function(name) ) global iHPGconditions, iHPGcertificate; local res, i, condout, certout; iHPGconditions:= [ ]; condout:= false; certout:= false; for i from 4 to nargs do if args[i]=`conditions` then condout:= true elif args[i]=`certificate` then certout:= true else error("Wrong option %1", args[i]) fi od; res:= iHPGsumrecursion( term, k, f ); iHPGoutconditions(); if certout then res:= res, iHPGcertificate fi; if condout then res:= res, op(iHPGconditions) elif iHPGconditions<>[] then WARNING("The condition(s) for uniformly bounded convergence are: %0", op( iHPGconditions ) ) fi; res end: infclosedform:= proc( term, k::name, nn::{name,name=anything} ) global iHPGconditions, iHPGUCstrict, iHPGcertificate; local hrec, nrec, limH, res, f, n, i, condout, certout; iHPGconditions:= [ ]; iHPGUCstrict:= true; n:=op(1,nn); condout:= false; certout:= false; for i from 4 to nargs do if args[i]=`conditions` then condout:= true elif args[i]=`certificate` then certout:= true elif args[i]=`ucrelaxed` then iHPGUCstrict:= false else error("Wrong option %1", args[i]) fi od; hrec:= iHPGsumrecursion( term, k, f(n) ); nrec:= iHPGrecnormalize( hrec, f(n) ); limH:= iHPGuniconvergence( simpcomb(nrec[2]*subs(n=nrec[3]*n,term)), k, n ); if nrec[1]<>0 then # the non-homogeneous part nrec[1]:= Sumtohyper( subs(n=n+f, nrec[1]), f ) end; res:= simplify( subs(n=n/nrec[3], limH/nrec[2]) ) - simplify( subs(n=n/nrec[3], nrec[1]/nrec[2]) ); if not type(nn,name) then res:= subs(nn,res); iHPGconditions:= subs(nn,iHPGconditions) fi; if certout then res:= res,iHPGcertificate fi; if condout then res:= res,op(iHPGconditions) elif iHPGconditions<>[] then WARNING("The condition(s) for uniformly bounded convergence are: %0", op( iHPGconditions ) ) fi; res end: uniformconvergence:= proc( hterm, k::name, n::name ) ### Input: a hypergeometric term hterm ### Returns error and/or warning messages if the hypergeometric series (over k) ### do not converge uniformly convergence with respect to n ### In the case of (possible) uniform convergence, ### returns the limit n->infty of the hypergeometric series, ### and a sequence of restrictions on the parameters. global iHPGconditions, iHPGUCstrict; local res, i, condout; condout:= false; iHPGUCstrict:= true; for i from 4 to nargs do if args[i]=`conditions` then condout:= true elif args[i]=`ucrelaxed` then iHPGUCstrict:= false else error("Wrong option %1", args[i]) fi od; iHPGconditions:= [ ]; res:= iHPGuniconvergence( hterm, k, n ); if condout then res:= res, op(iHPGconditions) elif iHPGconditions<>[] then WARNING("The condition(s) for uniformly bounded convergence are: %0", op( iHPGconditions ) ) fi; res end: iHPGsumrecursion:= proc( term, k::name, f::function(name) ) global iHPGcertificate, iHPGerr1, iHPGerr2; local H, hrec, nhom, sumac, cond, rho1; hrec:= sumrecursion( term, k, f, certificate=true ); iHPGcertificate:= op(2,hrec); hrec:= op(1,hrec); rho1:= min(0, 1-degree(numer(iHPGcertificate),k) +degree(denom(iHPGcertificate),k) ); ### rho1=min(0,1-rho) nhom:= subs(k=0, -iHPGcertificate*term); H:= iHPGterm2hyperg( term, k ); sumac:= Re( normal(convert(H[2],`+`)-convert(H[3],`+`)) ); ### limit k->infinity if nops(H[2])>nops(H[3])+1 then error( iHPGerr1 ) elif nops(H[2])=nops(H[3])+1 then if not type(H[4], constant) then if type(sumac,constant) and Re(sumac)0 then error( iHPGerr1 ) elif abs(H[4])=1 then if not type(sumac,constant) then if H[4]=1 and rho1<0 then iHPGaddcondition( Re(sumac)<=rho1 ) else iHPGaddcondition( Re(sumac)0 then error( iHPGerr2 ) elif Re(sumac)=rho1 then if H[4]=1 and rho1<0 then nhom:= simpcomb( nhom+H[1]*lcoeff(iHPGcertificate,k)* convert(map(GAMMA,H[3]),`*`)/convert(map(GAMMA,H[2]),`*`) ) else error( iHPGerr1 ) fi fi fi fi; subsop(2=nhom, hrec) end: iHPGuniconvergence:= proc( hterm, k, n ) ### Input: a hypergeometric term hterm ### Returns error and/or warning messages if the hypergeometric series (over k) ### do not converge uniformly convergence with respect to n ### In the case of uniform convergence, the limit n->infty series is returned global iHPGerr1, iHPGerr2, iHPGerr3; local H, H1, smrm1, absz, tildesr, S, R, zeta, alpha, gamma, salpgam, papg, tildeac, hatac, sumac, gt, t, tmp, L0, L1, ff, f1, f2, i; Digits:= iHPGDigits; H:= iHPGterm2hyperg( hterm, k ); H1:= simpcomb( subs(n=n+1,H[1])/H[1] ); smrm1:= nops(H[2])-nops(H[3])-1; absz:= abs(H[4]); # s-r-1, |z| sumac:= normal(convert(H[2],`+`)-convert(H[3],`+`)); # Sum(a)-Sum(c) alpha:= select(T->T<>0,map(coeff,H[2],n)); # alpha's gamma:= select(T->T<>0,map(coeff,H[3],n)); # gamma's tildesr:= nops(alpha)-nops(gamma); # tildes-tilder salpgam:= convert(alpha,`+`)-convert(gamma,`+`); # Salpha-Sgamma papg:= convert(alpha,`*`)/convert(gamma,`*`)*H[4]; # z*Palpha/Pgamma S:= degree(numer(H1),n); R:= degree(denom(H1),n); # S, R tildeac:= 0; # computing Sum(tildea)-Sum(tildec) if S>0 then tildeac:= normal(coeff(numer(H1),n,S-1)/S/lcoeff(numer(H1),n)) fi; if R>0 then tildeac:= normal( tildeac - coeff(denom(H1),n,R-1)/R/lcoeff(denom(H1),n) ) fi; # Stildea-Stildec zeta:= lcoeff(H1, n); # constant zeta hatac:= convert( select(T->degree(T,n)=0,H[2]), `+`) - convert( select(T->degree(T,n)=0,H[3]), `+`); # Shata-Shatc hatac:= normal( hatac + tildeac + tildesr/2 ); # Shata-Shatc+... if smrm1>0 then error( iHPGerr1 ) ### Th.2, (i)-1 elif smrm1=0 then if salpgam>0 then ### (ii) error("The series does not converge for large n, unless it is terminating") fi; if not type(absz, constant) then if type(sumac,constant) and signum(Re(sumac))<0 then iHPGaddcondition( absz<=1 ) else iHPGaddcondition( absz<1 ) fi elif signum(absz-1)>0 then error( iHPGerr1 ) elif absz=1 then iHPGsumOkpower( Re(sumac) ); if salpgam=0 then ### (viii) tmp:= convert( map(T->abs(T)^T, alpha), `*`) /convert( map(T->abs(T)^T, alpha), `*`); if abs(zeta)>tmp then error( iHPGerr2 ) elif abs(zeta)=tmp then iHPGsumOkpower( Re(hatac) ); if iHPGordfx0( convert( map(T->T^2*x/(1+T*x), alpha), `+`) - convert( map(T->T^2*x/(1+T*x), gamma), `+`), x)[2] > 0 then error( iHPGerr2 ) fi fi fi fi fi; if S>R then error( iHPGerr3 ) ### (i)-2 elif S=R then ### (iii) if tildesr>0 then error( iHPGerr3 ) fi; if abs(zeta)>1 then error( iHPGerr3 ) elif abs(zeta)=1 then if not type(tildeac, constant) then iHPGaddcondition( Re(tildeac)<0 ) elif signum(Re(tildeac))>0 then error( iHPGerr2 ) elif zeta<>1 or tildeac<>0 then error( iHPGerr2 ) fi; if tildesr=0 then ### (vii), Lem.3(c) tmp:= abs(papg); if not type(tmp, constant) then if type(hatac,constant) and signum(Re(hatac))<0 then iHPGaddcondition( tmp<=1 ) else iHPGaddcondition( tmp<1 ) fi elif signum(tmp-1)>0 then error( iHPGerr2 ) elif tmp=1 then iHPGsumOkpower( Re(hatac) ); if iHPGordfx0( convert( map(T->x/(x+T), alpha), `+`) - convert( map(T->x/(x+T), gamma), `+`), x)[2] > 0 then error( iHPGerr2 ) fi fi fi fi fi; gt:= simplify( abs(zeta)*convert( map(T->((1+T*t)/(T*t))^T,alpha),`*`) /convert( map(T->((1+T*t)/(T*t))^T,gamma),`*`) ); if not depends(gt, t) then ### then g(t) = |z|, right? if not type(absz, constant) then ### (iv) iHPGaddcondition( absz<1 ) elif signum(absz-1)>0 then error( iHPGerr2 ) elif absz=1 then ### (v) iHPGsumOkpower( Re(hatac) ); gt:= select(type, {op(alpha),op(gamma)}, negint); for tmp in gt do ### (vi) iHPGsumOkpower( Re(hatac-iHPGsumacbeta(tmp,H[2],H[3],n)) ) od fi else ### (iv), Lem.3(d) if not type([op(alpha),op(gamma)],list(even)) then gt:=gt^2 fi; L0:= [ fsolve( numer(gt)-denom(gt), t, 0..infinity, avoid={t=0}, fulldigits ) ]; gt:= absz*convert( map(T->abs(1+T*t),alpha),`*`) /convert( map(T->abs(1+T*t),gamma),`*`); L1:= map( T->evalf(abs(subs(t=T,gt))), L0 ); gt:= max(op(L1)); # if L1=[], then gt=-infinity gt:= evalf(gt, Digits-4); if gt>1 then error( iHPGerr2 ) elif gt=1 then ### (v) iHPGsumOkpower( Re(hatac) ); ff:= normal( convert( map(T->x/(x+t+1/T), gamma), `+`) - convert( map(T->x/(x+t+1/T), alpha), `+`) ); for i to nops(L0) do ### (v),(vi) if L1[i]=1 then f1:= normal( subs(t=L0[i], ff) ); f2:= iHPGordfx0(f1, x); if type(f2[1],odd) or f2[2]>0 then error( iHPGerr2 ) fi; tmp:= -1/L0[i]; tmp:=evalf(tmp, Digits-4); tmp:= iHPGsumacbeta( evalf(tmp,Digits-4), H[2], H[3], n); if tmp<>0 then iHPGsumOkpower( Re(hatac-tmp) ) fi fi od fi fi; iHPGoutconditions(); ### Return the limit series ### Th.2-output if (S=R) and (zeta=1) and (tildeac=0) then if not type(H[1],`*`) then H[1]:= iHPGcontribc(H[1],n) else H[1]:= simpcomb( map(iHPGcontribc,H[1],n) ) fi; if tildesr<0 then H[1] else # tildesr=0 H[2]:= select( T->coeff(T,n)=0, H[2] ); H[3]:= select( T->coeff(T,n)=0, H[3] ); H[1]*simplify( hypergeom(H[2], H[3], papg) ) fi else 0 fi end: iHPGrecnormalize:= proc( rec::equation, ff::function(name) ) # Input: a first order recurrence relation, expectedly of form # ??*f(n+t)+??*f(n)=??, with ff=f(n) # Output: the non-homogeneous part of the normalized equation F(n+1)-F(n)=???, # the normalizing factor F(n)/ff(n), and the shift (normally 1) in n local nhom, hom, hom0, hom1, f, n, kn, fn; hom:= op(1,rec); nhom:= op(2,rec); f:= op(0,ff); n:= op(1,ff); if nops(hom)>2 then # Expected: type(hom,plus) ERROR("The recurrence relation has more than two homogeneous terms") fi; hom0:= coeff(hom,f(n)); hom1:= coeff(hom,f(n+1)); if hom1<>0 then kn:= 1 else # the recurrence has higher order, but it is a two-term recurrence hom1:= hom-hom0*f(n); if type(hom1, function) then fn:= hom1 else fn:= select(type, hom1, function) fi; kn:= subs(n=0, op(1,fn)); # excpeted kn>0 hom0:= map(factor, subs(n=kn*n,hom0) ); hom1:= map(factor, subs(n=kn*n,hom1/fn) ); nhom:= simpcomb( subs(n=kn*n,nhom) ) fi; if nhom<>0 then nhom:= simpcomb( nhom*iHPGrat2gamma(-hom1/subs(n=n+1,hom0),n) ) fi; [ nhom, iHPGrat2gamma(-hom1/hom0,n), kn ] ### Would returns gamma-differences of the non-homogeneous part ### and of the normalizing factor; and the shift in n # if nhom<>0 then # nhom:= -hom1/subs(n=n+1,hom0)*simpcomb(subs(n=n+1,nhom)/nhom) # fi: # [ nhom, -hom1/hom0, kn ] end: iHPGrat2gamma:= proc( g, n::name ) # Input: a rational expression g(n)/h(n) # Output: the solution of a(n+1)=g(n)a(n) of form c^n*G(n+?,??) local num, den, gg, D3, Q, x, dx, kx, yy, dd, j; gg:= normal(g); num:= iHPGfactorsinn(numer(gg), n); den:= iHPGfactorsinn(denom(gg), n); D3:= map(T->T[1]$T[2], den[3]); # denominator non-linear factors Q:= 1; for x in num[3] do kx:= x[2]; # x is [a factor, its power] dx:= degree(x[1], n); for j from nops(D3) to 1 by -1 do yy:= D3[j]; # yy is a nonlinear dominator factor if degree(yy,n)=dx then dd:= normal( (coeff(x[1],n,dx-1)-coeff(yy,n,dx-1) )/dx ); if type(dd,integer) and normal(x[1]-subs(n=n+dd,yy))=0 then if dd>0 then Q:= Q*mul(normal(subs(n=n+i,yy)), i=0..dd-1) else Q:= Q/mul(normal(subs(n=n-i,yy)), i=1..-dd) fi; D3:= subsop(j=NULL, D3); kx:= kx-1; if kx<=0 then break fi fi fi od; if kx>0 then Q:= Q*convert( map(T->GAMMA(n-T),[solve(x[1],n)]), `*`)^kx fi od; D3:= convert( map(T->GAMMA(n-T), map(solve,D3,n)), `*`); simpcomb( Q/D3*(num[1]/den[1])^n* iHPGconvert2gamma(num[2])/iHPGconvert2gamma(den[2]) ) end: iHPGsumOkpower:= proc( reterm ) global iHPGerr1; ### Returns the case when the hypergeometric series is O(k^{power}) if not type(reterm, constant) then iHPGaddcondition( reterm<0 ) elif signum(reterm-1)>=0 then error( iHPGerr1 ) elif signum(reterm)>=0 then if iHPGUCstrict then error( iHPGerr1 ) else WARNING("The uniform majorant series does not converge,\ check the uniform convergence; the results are unreliable") fi fi end: iHPGcontribc:= proc( Q, n::name ) # Returns a contribution of the term for lim_{n->infty} # assuming that the product of terms has a finite limit # The term is: a constant, power or exponent of n, Gamma-term, rat. function local beta, b, t; t:= op(1, Q); if not depends(Q,n) then Q elif type(Q,`^`) then if not type(op(2,Q),integer) then 1 else iHPGcontribc(t,n)^op(2,Q) fi elif op(0,Q)=`GAMMA` then beta:= coeff(t,n); if beta=1 then 1 else b:= subs(n=0, t); t:= (2*Pi)^((1-beta)/2)*abs(beta)^(b-1/2); if beta>0 then t elif type(b,integer) then error("The series undefined for large n") else t/2/sin(Pi*b) fi fi else ### Suppose that Q is a polynomial lcoeff(Q, n) ## WARNING("Can't estimate %1 as n->infty", Q); 1 fi end: iHPGordfx0:= proc( f, x ) ### Returns the order of f at x=0, and the starting coefficient local ff, k; ff:= normal( f ); if ff=0 then return([0,0]) fi; k:= 0; while subs(x=0, ff)=0 do k:=k+1; ff:= normal(ff/x) od; [k, subs(x=0,ff)] end: iHPGsumacbeta:= proc( beta, U, L, n ) ### Returns Sum_{alpha_i=beta}(a_i) - Sum_{gamma_i=beta}(c_i) local f1, f2; f1:= select( T->evalb(t=beta), U); f2:= select( T->evalb(t=beta), L); if nops(f1)<>nops(f2) then error( iHPGerr2 ) else #if nops(f1)>0 then convert(map2(subs,n=0,f1),`+`)-convert(map2(subs,n=0,f2),`+`) fi end: iHPGfactorsinn:= proc( f, n::name ) # a version of Maple's "factors", # with f considered as a polynomial in n only, # and seprating linear and nonlinear factors. # Factors are monic with respect to n # Output: [lcoeff, linear factors, other factors] local ff, c, lc; ff:= factors(f); c:= ff[1]*convert(map(T->lcoeff(T[1],n)^T[2],ff[2]),`*`); ff:= map(T->[T[1]/lcoeff(T[1],n),T[2]], ff[2]); [c, select(T->degree(T[1],n)=1,ff), select(T->degree(T[1],n)>1,ff) ] end: iHPGconvert2gamma:= proc( L ) # Input: A list of [term,power] # Output: The product of GAMMA(term)^power convert( map(T->GAMMA(T[1])^T[2],L), `*`) end: iHPGterm2hyperg:= proc( term, k::name) ## Given a hypergeometric term, returns the following ## data of the corresponding hypergeometric sum: ## [the multiplicative constant term, ## the upper parameters, the lower parameters, ## the argument ] local F, H; F:= Sumtohyper( term, k ); if op(0,F)=`Hypergeom` then H:=F else H:= select( T->evalb(op(0,T)=`Hypergeom`), F) fi; [ normal(F/H), op(H) ] end: iHPGaddcondition:= proc( cond ) ### Add the inequality cond to the conditions list; ### It is expected that cond is either a*Re(x)iHPGconditions[i,3] then iHPGconditions[i,3]:= rh; iHPGconditions[i,5]:= eq elif rh=iHPGconditions[i,3] then iHPGconditions[i,5]:= iHPGconditions[i,5] and eq fi; return fi od; if s=1 then iHPGconditions:= [ op(iHPGconditions), [lh, rh, -infinity, eq, true] ] else iHPGconditions:= [ op(iHPGconditions), [lh, infinity, rh, true, eq] ] fi end: iHPGoutconditions:= proc( ) ### The condition list is prepared for the output global iHPGconditions; local L, T; L:= [ ]; for T in iHPGconditions do if T[2]>T[3] then if T[3]>-infinity then if T[5] then L:= [op(L),T[1]>=T[3]] else L:= [op(L),T[1]>T[3]] fi fi; if T[2]