2 /* Gosper's equation-related routines */
4 /* RISC Institite, Linz, Austria */
5 /* by Fabrizio Caruso */
11 /* It creates the Gosper's polynomial out of the following parameters:*/
12 /* polynomials p,q,r + */
13 /* Ansatz degree deg of the solution + */
15 /* unknown coefficients name */
16 AnsatzDegreeVerboseOpt(p,q,r,indet,mode) :=
18 [qp,qm,degqp,degqm,degp,qpCoeff,qmCoeff,alpha],
23 degqp : degree(expand(qp),indet),
24 degqm : degree(expand(qm),indet),
25 degp : degree(expand(p),indet),
27 if mode >= verbose then
29 print("(Ansatz) Degree of qplus:" , degqp),
30 print("(Ansatz) Degree of qminus: " , degqm),
31 print("(Ansatz) Degree of p: " , degp)
34 /* Case distinction */
35 if degqm >= degqp then
37 if mode >= verbose then
39 print("(Ansatz degree) Ordinary case (degqm>=degqp)"),
40 print("(Ansatz degree) Degree : ", degp-degqm)
46 if mode >= verbose then
47 print("(Ansatz degree) Non-ordinary case (degqm<degqp)"),
48 qpCoeff : leadCoeff(qp,indet),
49 if mode >= verbose then
50 print("(Ansatz degree) Leading coeff. of qplus: ", qpCoeff),
51 qmCoeff : leadCoeff(qm,indet),
52 if mode >= verbose then
53 print("(Ansatz degree) Leading coeff. of qminus: ", qmCoeff),
54 alpha : -2*(qmCoeff/qpCoeff),
55 if mode >= verbose then
56 print("(Ansatz degree) alpha :", alpha),
57 if integerp(alpha) then
59 if mode >= verbose then
60 print("(Ansatz degree) Nasty case (int(-2*qmC/qpC))"),
61 return(max(alpha,degp-degqp+1,0)) /* 0??? */
65 if mode >= verbose then
66 print("(Ansatz degree) Easy case (not(int(-2*qmC/qpC)))"),
67 return(max(degp-degqp+1,0)) /* 0??? */
75 /* p,q,r: Gosper's form polynomials */
76 /* indet: indeterminate */
77 /* coef: prefix of the coefficients */
78 /* deg: desidered degree of the Gosper's polynomial */
79 GosperPoly(p,q,r,indet,coef,deg) :=
80 expand(q*subst(k+1,k,poly(indet,coef,deg))-r*poly(indet,coef,deg)-p);
85 /* It solves the Gosper's equation (Gosper's polynomial=0) */
86 /* and yields the coefficients of the solution in a list */
88 /* We are assuming that Gpoly is fully expanded */
91 /* It solves the Gosper's equation (Gosper's polynomial=0) */
92 /* and yields the coefficients of the solution in a list */
94 /* We are assuming that Gpoly is fully expanded */
96 /* Gpoly: Gosper polynomial */
100 SolveSysVerboseOpt(Gpoly,unkPar,numUnkPar,indet,mode) :=
101 block([dim,base,baseElem,sol],
103 if mode >= verbose then
105 print("(SolveSys) Poly2List: ", poly2List(Gpoly,indet)),
106 print("(SolveSys) Variables: ",
107 makelist(unkPar[i],i,0,numUnkPar-1))
110 sol : linear_solver(poly2List(Gpoly,indet),
111 makelist(unkPar[i],i,0,numUnkPar-1)),
113 dim : length(ind_vars(linear_solver)),
114 if mode >= verbose then
116 print("mode : ", mode),
117 print("dim : ", dim),
118 print("debug : ", ind_vars(linear_solver)),
122 if dim>0 and not(sol=[]) then
130 baseElem : subst(0,ind_vars(linear_solver)[j],baseElem)
132 baseElem : subst(1,ind_vars(linear_solver)[j],baseElem),
133 base : endcons(baseElem,base)
142 /* It solves the Gosper's equation (Gosper's polynomial=0) */
143 /* and yields the coefficients of the solution in a list */
145 /* We are assuming that Gpoly is fully expanded */
147 /* Gpoly: Gosper polynomial */
151 SolveZSysVerboseOpt(Gpoly,unkPar1,numUnkPar1,unkPar2,numUnkPar2,indet,
153 block([sol,dim,base,i,j,baseElem,sys],
155 if mode>=verbose then
157 print("inside : ", mode),
158 print("(SolveZSys) Unknowns: ", unkPar1, unkPar2),
159 print("(SolveZSys) Number of unknowns: ", numUnkPar1, numUnkPar2),
160 print("(SolveZSys) Gpoly : ", Gpoly),
161 print("(SolveZSys) Poly2List: ", poly2List(Gpoly,indet)),
162 print("(SolveZSys) Variables: ",
164 makelist(unkPar1[i],i,0,numUnkPar1-1),
165 makelist(unkPar2[i],i,0,numUnkPar2-1))),
166 print("Gpoly : ", Gpoly)
168 sys : poly2List(Gpoly,indet),
171 print("sys : ", sys),
173 sys : makelist(clearGCD(part(sys,i),unkPar1,numUnkPar1,
174 unkPar2,numUnkPar2),i,1,length(sys)),
176 sol : solver(poly2List(Gpoly,indet),
178 makelist(unkPar1[i],i,0,numUnkPar1-1),
179 makelist(unkPar2[i],i,0,numUnkPar2-1))),
182 print("sys : ", sys),
185 dim : length(ind_vars(solver)),
192 baseElem : subst(1,ind_vars(solver)[j],baseElem)
194 baseElem : subst(0,ind_vars(solver)[j],baseElem),
195 base : endcons(baseElem,base)
203 for i:1 thru length(sol) do
204 res : subst(second(sol[i]),first(sol[i]),res),
209 /* It solves the Gosper's equation (Gosper's polynomial=0) */
210 /* and yields the coefficients of the solution in a list */
212 /* We are assuming that Gpoly is fully expanded */
214 /* Gpoly: Gosper polynomial */
218 SolveZSysVerboseSys(Gpoly,unkPar1,numUnkPar1,unkPar2,numUnkPar2,indet) :=
220 print("(SolveZSys) Unknowns: ", unkPar1, unkPar2),
221 print("(SolveZSys) Number of unknowns: ", numUnkPar1, numUnkPar2),
222 print("(SolveZSys) Poly2List: ", poly2List(Gpoly,indet)),
223 print("First equation : ", part(poly2List(Gpoly,indet),1)),
224 print("Coeff in _z[0] of degree 0 : ", coeff(part(poly2List(Gpoly,indet),1),n,0)),
225 print("(SolveZSys) Variables: ",
227 makelist(unkPar1[i],i,0,numUnkPar2-1),
228 makelist(unkPar2[i],i,0,numUnkPar1-1))),
230 print("(SolveZSys) LINEAR SYSTEM OF EQUATIONS"),
231 showSys(Gpoly,indet),
233 [linear_solver(poly2List(Gpoly,indet),
235 makelist(unkPar1[i],i,0,numUnkPar2-1),
236 makelist(unkPar2[i],i,0,numUnkPar1-1)))]
241 /* It shows the corresponding linear system of a Gosper-polynomial */
242 showSys(Gpoly,indet) :=
243 printSys(poly2List(Gpoly,indet),1);
246 /* Pretty print of am homogeneus system of linear equations */
247 printSys(list,num) :=
251 if length(list) = 1 then
252 print(first(list)," = 0. (",num,")" )
256 print(first(list)," = 0, (",num,")" ),
257 printSys(rest(list),num+1)
262 /* Pretty print of the degrees of the solutions of a system of linear equations */
263 /* Separates the Gosper and Zeilberger Ansatz coefficients */
264 getDegrees(Gres,GLength,ZLength,n) :=
268 minListLength : min(GLength,ZLength),
272 for i : 1 thru minListLength*2 do
276 print(lhs(Gres[i]), "=", factor(xthru(rhs(Gres[i]))), " deg: ",
277 degree(expand(factor(xthru(rhs(Gres[i])))),n)),
279 GDegList : endcons(expand(rhs(Gres[i])),GDegList)
284 print(lhs(Gres[i]), "=", factor(xthru(rhs(Gres[i]))), " deg: ",
285 degree(expand(factor(xthru(rhs(Gres[i])))),n)),
287 ZDegList : endcons(expand(rhs(Gres[i])),ZDegList)
290 if GLength > ZLength then
291 for i: minListLength*2+1 thru GLength+ZLength do
293 print(lhs(Gres[i]), "=", factor(xthru(rhs(Gres[i]))), " deg: ",
294 degree(expand(factor(xthru((rhs(Gres[i]))))),n)),
296 GDegList : endcons(expand(rhs(Gres[i])),GDegList)
298 if ZLength > GLength then
299 for i: minListLength*2+1 thru GLength+ZLength do
301 print(lhs(Gres[i]), "=", factor(xthru(rhs(Gres[i]))), " deg: ",
302 degree(expand(factor(xthru(rhs(Gres[i])))),n)),
304 ZDegList : endcons(expand(rhs(Gres[i])),ZDegList)
312 /* It solves the Gosper's equation (Gosper's polynomial=0) */
313 /* and yields the coefficients of the solution in a list */
315 /* We are assuming that Gpoly is fully expanded */
317 /* Gpoly: Gosper polynomial */
323 SolveZSys(Gpoly,unkPar1,numUnkPar1,unkPar2,numUnkPar2,indet) :=
324 block([sol,dim,base,i,j,baseElem,pList,sys,clearedSys],
325 sys : poly2List(Gpoly,indet),
328 sys : makelist(clearGCD(part(sys,i),unkPar1,numUnkPar1,unkPar2,numUnkPar2),i,1,length(sys)),
330 sol : linear_solver(sys,
332 makelist(unkPar1[i],i,0,numUnkPar1-1),
333 makelist(unkPar2[i],i,0,numUnkPar2-1))),
335 dim : length(ind_vars(linear_solver)),
342 baseElem : subst(1,ind_vars(linear_solver)[j],baseElem)
344 baseElem : subst(0,ind_vars(linear_solver)[j],baseElem),
345 base : endcons(baseElem,base)
353 for i:1 thru length(sol) do
354 res : subst(second(sol[i]),first(sol[i]),res),