hille.red 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. module hille; % Hillebrand decomposition of a zero - dimensional polynomial
  2. % ideal following
  3. % D. Hillebrand: Triangulierung nulldimensionaler Ideale - Implementierung und
  4. % Vergleich zweier Algorithmen. Diplomarbeit im Studiengang Mathematik
  5. % der Universit"at Dortmund. Betreuer: Prof. Dr. H. M. M"oller, 1999
  6. % Dasi: hille.sav7
  7. % triang4: groeposthillebrand: interface for the solver (for zero -
  8. % dimensional polynomial ideals).
  9. symbolic procedure groeposthillebrand(u,v);
  10. % Solve - interface for the module 'hille' (for:Hillebrand);
  11. % ' u ' is the (partial) basis in external form (the first word is 'list);
  12. % ' v ' is the total list of variables (the first word is 'list);
  13. % the routine returns a list of solutions, if 'u' is zero-dimensional;
  14. % else it returns 'nil'.
  15. begin scalar a,d,e;u:=cdr u;
  16. vdpinit groebnervars(u,nil);groedomainmode();
  17. a:=for each uu in u collect numr simp uu;
  18. vars!*:=dipvars!*:=vdpvars!*:=cdr v;
  19. if null hillebrandtriangular(cdr v,a,nil)then return nil;
  20. % From now on, the zero-dimensionality has been assured.
  21. !*groebopt:=nil;
  22. a:=hillebrand(a,nil);
  23. for each b in a do
  24. <<d:='list.for each c in b collect prepf c;
  25. e:=append(e,groepostfastsolve(d,v))>>;
  26. return groesolvearb(e,v) end; %%%AENDERUNG 18.9.00
  27. % triang3: saturation of a basis and a polynomial.
  28. symbolic procedure hillebrandstdsat(g,p);
  29. % Compute the basis of the saturation ideal ' g ' and polynomial ' p ' .
  30. begin scalar a,b,c,e;
  31. if cdr g then go to a ;
  32. % ' g ' is a one - polynomial list .
  33. p:=p./ 1;g:=car g ./ 1;a:=t;
  34. while a do<<a:=hillebrandquot(g,p);if a then g:=a>>;
  35. e:=if not domainp numr g then{numr g}else nil;return e;
  36. a: % The list 'g' has more than one polynomial.
  37. p:=prepf p;a:='list.for each gg in g collect prepf gg;
  38. b:=saturationeval{a,p};
  39. if b='(list 1)then return'(1);
  40. c:=for each bb in cdr b collect numr simp bb;
  41. return sort(c,function hillebrandcompare)end;
  42. symbolic procedure hillebrandquot(g,p);
  43. % Compute the quotient of 'g' and 'p', if 'p' divides 'g' as a
  44. % polynomial (if 'p' is a polynomial divisor of 'g', ignoring the
  45. % quotients of coefficients).
  46. (if hillebrandvar(denr a , vars!*)then numr a ./ 1 else nil)
  47. where a=quotsq(g,p);
  48. symbolic procedure hillebrandvar(p,m);
  49. % Tests, if the variables of 'p' are contained in 'm' ; 'nil'
  50. % if a variable of 'p' is part of 'm' ; else return 't'.
  51. if domainp p then t else if mvar p member m then nil else
  52. hillebrandvar(lc p,m)and hillebrandvar(red p,m);
  53. % triang2: the main routine 'hillebrand1'.
  54. symbolic procedure hillebrand(g,fact);
  55. % 'g' ist an untagged list of standard polynomials, a Groebner basis,
  56. % 'fact' is a swich which involves faczorization (if set).
  57. begin scalar a ; vars!*:=dipvars!*;!*trgroesolv and hillebrandmsg1 g;
  58. a:=hillebrand1(sort(g,function hillebrandcompare),fact);
  59. !*trgroesolv and hillebrandmsg2 a;return a end;
  60. % The sorting is inverse to the normal sorting (polynomial with the
  61. % highest leading term (normally) is the last one).
  62. symbolic procedure hillebrandcompare(a,b);
  63. % Comparison of 'a' and 'b' (standard polynomials) after inverse 'lex' principle.
  64. hillebrandcompare1(a,b,vars!*);
  65. symbolic procedure hillebrandcompare1(a,b,v);
  66. % If the result is 't', 'a' and 'b' are sorted 'a'<'b'; if the result
  67. % is 'nil', they are ordered 'b'<'a'.
  68. begin scalar aa,bb,c;
  69. aa:=a;bb:=b;
  70. if domainp aa or not(mvar aa member v) then return t else
  71. if domainp bb or not(mvar bb member v) then
  72. (if mvar aa member v then return nil else return t);
  73. aa: if domainp bb or not(mvar bb member v)then
  74. (if domainp aa or not(mvar aa member v)then
  75. return hillebrandcompare1(red a,red b,v)else return t) else
  76. if mvar aa member v and mvar aa=mvar bb then
  77. (if ldeg aa=ldeg bb then<<aa:=lc aa;bb:=lc bb;go to aa>>else
  78. if ldeg aa #< ldeg bb then return t else return nil)else
  79. if(c:=mvar bb member v)then
  80. (if domainp aa or not(mvar aa member c)or mvar aa member cdr c then return t else
  81. if mvar aa member v then return nil);
  82. return hillebrandcompare1(red a,red b,v)end;
  83. % The routine HILLEBRAND1: the main(recursive) routine.
  84. symbolic procedure hillebrand1(g,fact);
  85. % Input: 'g' : a (reduced ) lexicographical groebner basis,
  86. % fact: a switch, which involves factorization (if set);
  87. % output: a list of bases (a decomposition of 'g' in triangular bases),
  88. % internal form.
  89. if hillebrandtriangular(vars!*,g,t)then hillebrandfactorizelast(g,fact)else
  90. begin scalar a,aa,b,c,r,f,ff,fh,g2,g3,h,l,o;
  91. % first part of the split.
  92. g3:=g;while cdr g3 do g3:=cdr g3;
  93. a:=hillebranddecompose(g,mvar car g3);
  94. c:=for each aa in cdr a collect lc aa ;
  95. r:=hillebrandgroebner hillebrandjoin(car a,c);
  96. f:=hillebrand1(r,fact); % Recursive call with reduced basis.
  97. aa:=hillebrandlast g;
  98. for each tt in f do
  99. <<b:=hillebrandnormalform(aa,tt);
  100. ff:=hillebrandappend1(ff,tt,b)>> ; % append(tt,{b}).ff
  101. f:=reversip ff;
  102. % second part of the split.
  103. h:=car a; % H := { g_1 1, ... , g_n-1 c_n-1 }
  104. o:=length c;
  105. for k := 1:o do
  106. <<l:=nth(c,k);
  107. g2:=hillebrandstdsat(h,l);
  108. if not(car g2=1)then
  109. <<fh:=hillebrand1(g2,fact);
  110. fh:=for each tt in fh collect
  111. hillebrandgroebner hillebrandappend(tt,{car cdr a});
  112. f:=hillebrandappend(f,fh)>>;
  113. h:=append(h,{nth(c,o)})>>;
  114. f:=for each ff in f collect sort(ff,function hillebrandcompare);
  115. return f end;
  116. % Append a basis, (if that is not empty).
  117. symbolic procedure hillebrandappend(a,b);
  118. if null car b then a else append(a,b);
  119. symbolic procedure hillebrandappend1(ff,tt,b);
  120. % append(tt,{b}).ff.
  121. <<if b then tt:=append(tt,{b});tt.ff>>;
  122. % Detect, if 'g' is already triangular.
  123. symbolic procedure hillebrandtriangular(a,g,m);
  124. % 'a' is the list of variables, 'g' is the Groebner basis. If m='t',
  125. % a basis with a mixed leading term is rejected. If m='nil', only the
  126. % zero - dimensionality is tested (that each variable occurs once isolated).
  127. begin scalar b,c;
  128. for each gg in g do
  129. if domainp lc gg or not(mvar lc gg member a)then b:=mvar gg.b else c:=t;
  130. if m and c then return nil;
  131. c:=t;for each gg in g do c and(c:=hillebrandtriangular1(a,gg,b));
  132. return c end;
  133. symbolic procedure hillebrandtriangular1(a,g,b);
  134. % Test, if all variables of 'g' occur in 'b'; return
  135. % 't' then; return 'nil' if that is not the case. 'g'
  136. % is a standard polynomial ; the 'variables' are the leading ones.
  137. if domainp g or not(mvar g member a)then t else
  138. if not(mvar g member b)then nil else
  139. hillebrandtriangular1(a,lc g,b)and hillebrandtriangular1(a,red g,b);
  140. symbolic procedure hillebrandfactorizelast(g,f);
  141. % Factorize the last polynomial of 'g' if 'f' is non-nil.
  142. if null f then {g} else
  143. begin scalar a,b,c,d;
  144. aa: if cdr g then<<a:=car g.a;g:=cdr g>>;if cdr g then go to aa;
  145. b:=fctrf car g;if domainp car b then b:=cdr b;
  146. c:=for each bb in b collect
  147. <<d:={car bb};for each aa in a do d:=aa.d;d>>;
  148. return if null cdr c then c else
  149. for each cc in c collect sort(cc,function hillebrandcompare)end ;
  150. % Decompose 'g' wrt'n'-th variable 'v'.
  151. symbolic procedure hillebranddecompose(g,v);
  152. begin scalar a,b,c,d;
  153. while g do
  154. <<c:=car g;d:=hillebranddecompose1(c,v,vars!*,0);
  155. if d=1 then a:=c.a else if d=2 then b:=c.b;g:=cdr g>>;
  156. return reversip a.reversip cdr b end;
  157. symbolic procedure hillebranddecompose1(p,v,vv,m);
  158. % 'p' is a polynomial; look, if it is a product of the
  159. % variable 'v'; return '1' if the leading factor is not a product of
  160. % variable 'v', '2' if it is.
  161. if domainp p or not(mvar p member vv)then m else
  162. hillebranddecompose1(lc p,v,vv,n)
  163. where n=if mvar p=v then 2 else if m #< 1 and mvar p member vv then 1 else m;
  164. % Join 2 lists.
  165. symbolic procedure hillebrandjoin(a,b);
  166. % Join 'a' and 'b' if 'b' is not 'nil'.
  167. if null b then a else append(a,b);
  168. % Last polynomial of a list.
  169. symbolic procedure hillebrandlast g;
  170. <<while cdr g do g:=cdr g; car g>>;
  171. % Compute a Groebner basis .
  172. symbolic procedure hillebrandgroebner g;
  173. % Compute the Groebner basis of 'g'; return the Groebner basis as a sorted
  174. % list of standard polynomials sorted descending.
  175. begin scalar a,b,c,d;
  176. for each gg in g do
  177. <<d:=prepf gg;if not(d=0)then a:=d.a>>;
  178. b:=groebnereval{'list.a,'list.vars!*}
  179. where dipvars!*=dipvars!*,vdpvars!*=vdpvars!*;
  180. c:=for each x in cdr b collect numr simp x;
  181. return sort(c,function hillebrandcompare)end;
  182. % Compute the normal form of a polynomial.
  183. symbolic procedure hillebrandnormalform(p,g);
  184. % Compute 'p' modulo Groebner basis 'g'.
  185. <<p:=hillebrandf2vdp p;
  186. g:=for each x in g collect hillebrandf2vdp x;
  187. vdp2f groebnormalform(p,g,'sort)>>;
  188. symbolic procedure hillebrandf2vdp p;
  189. gsetsugar(a,nil)where a=f2vdp p;
  190. % General .
  191. symbolic procedure hillebrandmsg1 g;
  192. if !*trgroesolv then
  193. <<writepri(" ",'only);writepri(" Hillebrand routine;solve{",'only);
  194. while g do<<writepri(mkquote prepf car g,'first);g:=cdr g;
  195. if g then writepri(" , ",'last)>>;
  196. writepri(" } with respect to ",nil);
  197. writepri(mkquote('list.vars!*),'last);
  198. writepri(" ",'only);>>;
  199. symbolic procedure hillebrandmsg2 a;
  200. if !*trgroesolv then
  201. <<writepri(" Decomposition by Hillebrand : ",'only);
  202. for each aa in a do
  203. <<writepri(" { ",'only);
  204. while aa do<<writepri(mkquote prepf car aa,'first);
  205. aa:=cdr aa;
  206. if aa then writepri(" , ",'last)>>;
  207. writepri(" } ",'last)>>;
  208. writepri(" ",'only);>>;
  209. endmodule;;end;