hilbertp.red 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. module hilbertp; % Computing Hilbert Polynomial from the Hilbert series.
  2. comment
  3. Authors: H. Michael Moeller, Fernuniversitaet
  4. Hagen, Germany
  5. email: MA105@DHAFEU11.bitnet
  6. H. Melenk, Konrad-Zuse-Zentrum
  7. Berlin, Germany
  8. email: melenk@sc.ZIB-Berlin.de
  9. ;
  10. symbolic procedure newhilbi (bas,var,vars);
  11. begin scalar baslt,n,u,grad,h,joa,a,ii,dim0,varx,dmode!*,!*modular;
  12. % extract leading terms
  13. Baslt:= for each p in cdr bas collect
  14. <<u := Hgspliteval list (p,vars); cadr u>>;
  15. % replace non atomic elements in the varlist by gensyms
  16. for each x in cdr vars do
  17. if (pairp x) then
  18. baslt := cdr subeval list(list('equal,x,gensym()),
  19. 'list . Baslt);
  20. % compute the Hilbertseries
  21. joa := hilbsereval list ('list . baslt,var);
  22. % get the Hilbert polynomial
  23. grad := deg(joa,var);
  24. A:= for i:=0:grad collect coeffn (joa,var,i);
  25. n:= length cdr vars;
  26. %dim0 := (for i:=1:n product (var + i))/( for i:=1:n product i);
  27. varx := !*a2f var;
  28. dim0 := 1;
  29. for i:=1:n do dim0:= multf (addd(i,varx),dim0);
  30. dim0 := multsq(dim0 ./ 1,1 ./ (for i:=1:n product i));
  31. H := multsq(car(A) ./ 1,dim0);
  32. A := cdr(A);
  33. ii := 0;
  34. while a do
  35. << dim0 := multsq (dim0, addf(varx,numr simp (minus ii) )
  36. ./ addf(varx,numr simp (n -ii)));
  37. ii := ii + 1;
  38. if not (car a = 0) then H := addsq (H , multsq(car(A) ./ 1 ,dim0));
  39. A := cdr(A) >>;
  40. return mk!*sq H;
  41. end;
  42. symbolic procedure psnewhilbi (u);
  43. begin scalar zz,pl,vl;
  44. pl:=reval car u;
  45. if cdr u then vl:=listeval(cadr u,nil);
  46. zz := 'list.groebnervars(cdr pl,vl);
  47. return newhilbi(pl,'x,zz)
  48. end;
  49. put ('hilbertpolynomial , 'psopfn ,'psnewhilbi);
  50. symbolic procedure HGspliteval pars;
  51. % A variant of Gsplit from grinterf.red.
  52. % Split a polynomial into leading monomial and reductum.
  53. begin scalar vars,x,u,v,w,oldorder,!*factor,!*exp;
  54. integer n,pcount!*; !*exp := t;
  55. n := length pars;
  56. u := reval car pars;
  57. v := if n>1 then reval cadr pars else nil;
  58. u := list('LIST,u);
  59. w := for each j in groerevlist u
  60. collect if eqexpr j then !*eqn2a j else j;
  61. vars :=groebnervars(w,v);
  62. if not vars then vdperr 'hilbertpolynomial;
  63. oldorder := vdpinit vars;
  64. w := a2vdp car w;
  65. if vdpzero!? w then x := w else
  66. % <<x := vdpfmon(vdplbc w,vdpevlmon w);
  67. <<x := vdpfmon('( 1 . 1),vdpevlmon w);
  68. w := vdpred w>>;
  69. w := list('LIST,vdp2a x,vdp2a w);
  70. setkorder oldorder;
  71. return w;
  72. end;
  73. % simple Array access method for one- and two-dimensional arrays
  74. % NO check against misusage is done!
  75. % Usage: Rar:=makeRarray list dim1; Rar:=makeRarray list(dim1,dim2);
  76. % val:=getRarray(Rar,ind1); val:=getrarray(Rar,ind1,ind2);
  77. % putRarray(Rar,ind1,val); PutRarray(Rar,in1,ind2,val);
  78. % for two dimensional array access only !
  79. macro procedure functionIndex2(u);
  80. begin scalar dims,ind1,ind2;
  81. dims := cadr u;
  82. ind1 := caddr u;
  83. ind2 := cadddr u;
  84. return %%%% ((ind1 #- 1) #* cadr dims) #+ ind2;
  85. list ('iplus2,ind2,list('itimes2,list('cadr,dims),
  86. list('iplus2,ind1,-1)));
  87. end;
  88. macro procedure getRarray u;
  89. begin scalar arry,inds;
  90. arry := cadr(u);
  91. inds := cddr u;
  92. if length(inds) = 1 then
  93. return list('getv,list('cdr,arry),car inds)
  94. else
  95. return list('getv,list('cdr,arry),
  96. 'functionIndex2 . list('car,arry) . inds);
  97. end;
  98. symbolic procedure makeRarray dims;
  99. begin scalar u,n;
  100. n := for each i in dims product i;
  101. u := mkvect n;
  102. return dims . u;
  103. end;
  104. macro procedure putRarray u;
  105. begin scalar arry,inds, val;
  106. arry := cadr(u);
  107. inds := cddr u;
  108. val := nth (u,length u); % PSL: lastcar u;
  109. if length(inds) = 2 then
  110. return list('putv,list('cdr,arry),car inds,val)
  111. else
  112. return list('putv,list('cdr,arry), 'functionIndex2 .
  113. list('car,arry).car inds. cadr inds . NIL , val);
  114. end;
  115. procedure HilbertZeroDimp(nrall, n, rarray);
  116. begin integer i, k, count, vicount;
  117. count := 0;
  118. i := 0;
  119. while ((i:= i+1) <= nrall and count < n) do
  120. begin vicount := 1;
  121. for k := 1:n do
  122. if (getrarray(rarray,i,k) = 0) then vicount := vicount + 1;
  123. if vicount = n then count := count + 1;
  124. end;
  125. return count = n;
  126. end;
  127. symbolic procedure groezerodim!?(F,n);
  128. begin scalar explist,A;
  129. integer r;
  130. %explist:= list( vev(lt(f1)),...,vev(lt(fr)) );
  131. explist:= for each fi in F collect vdpevlmon fi;
  132. r:= length(F);
  133. A := makerarray list(r,n);
  134. for i:=1 step 1 until r do
  135. for k:=1 step 1 until n do
  136. putRarray(A ,i,k, nth(nth(explist,i),k));
  137. return HilbertZeroDimp (r, n, A);
  138. end;
  139. symbolic procedure gzerodimeval u;
  140. begin scalar vl;
  141. if cdr u then vl:=reval cadr u;
  142. return gzerodim1(reval car u,vl)
  143. end;
  144. put('gzerodim!?,'psopfn,'gzerodimeval);
  145. symbolic procedure gzerodim1(u,v);
  146. begin scalar vars,w,oldorder;
  147. w := for each j in getrlist u
  148. collect if eqexpr j then !*eqn2a j else j;
  149. if null w then rerror(groebnr2,21,
  150. "Empty list in HilbertPolynomial");
  151. vars := groebnervars(w,v);
  152. oldorder := vdpinit vars;
  153. w := for each j in w collect f2vdp numr simp j;
  154. w := groezerodim!? (w,length vars);
  155. setkorder oldorder;
  156. return if w then newhilbi(u,'x,'list . v) else nil;
  157. end;
  158. symbolic procedure gbtest(g);
  159. % test, if the given set of polynomials is a Groebner basis.
  160. % only fast to compute plausilbility test.
  161. begin scalar fredu,g1,r,s;
  162. g := vdplsort g;
  163. % make abbreviated version of G
  164. g1:= for each p in g collect
  165. << r := vdpred p;
  166. if vdpzero!? r then p else
  167. vdpsum(vdpfmon(vdplbc p,vdpevlmon p),
  168. vdpfmon(vdplbc r,vdpevlmon r))
  169. >>;
  170. while g1 do
  171. <<for each p in cdr g1 do
  172. if not groebBuchcrit4t(vdpevlmon car g1,vdpevlmon p) then
  173. <<s := groebSpolynom(car g1,p);
  174. if not vdpzero!? s and
  175. null groebSearchInList (vdpevlmon s,cddr g1)
  176. then rerror(groebnr2,22,
  177. "****** Not a GROEBNER basis wrt current ordering");
  178. >>;
  179. if groebSearchInList(vdpevlmon car g1,cdr g1) then
  180. fredu := T;
  181. g1 := cdr g1;
  182. >>;
  183. if fredu then
  184. <<terpri!* t;
  185. prin2t "WARNING:system is not a fully reduced GROEBNER basis";
  186. prin2t "with current term ordering";
  187. >>;
  188. end;
  189. endmodule;
  190. end;