xreduct.red 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. module xreduct;
  2. % Normal form algorithms
  3. % Author: David Hartley
  4. fluid '(!*trxmod !*trxideal xtruncate!*);
  5. infix xmod;
  6. precedence xmod,freeof;
  7. put('xmod,'rtypefn,'getrtypecar);
  8. put('xmod,'listfn,'xmodlist);
  9. put('xmod,'simpfn,'simpxmod);
  10. symbolic procedure simpxmod u;
  11. % u:{prefix,prefix} -> simpxmod:sq
  12. begin scalar x;
  13. if length u neq 2 then
  14. rerror(xideal,0,"Wrong number of arguments to xmod");
  15. x := getrlist aeval cadr u;
  16. return !*pf2sq repartit xreduce(xpartitop car u,
  17. for each g in x join
  18. if g := xpartitop g then {g});
  19. end;
  20. symbolic procedure xmodlist(u,v);
  21. % u:{prefix,prefix},v:bool -> xmodlist:prefix
  22. begin scalar x;
  23. if length u neq 2 then
  24. rerror(xideal,0,"Wrong number of arguments to xmod");
  25. x := getrlist aeval cadr u;
  26. u := foreach f in getrlist aeval car u collect xpartitop f;
  27. x := for each f in x join
  28. if f := xpartitop f then {f};
  29. return makelist foreach f in u join
  30. if f := xreduce(f,x) then {!*q2a1(!*pf2sq repartit f,v)};
  31. end;
  32. infix xmodideal;
  33. precedence xmodideal,freeof;
  34. put('xmodideal,'rtypefn,'getrtypecar);
  35. put('xmodideal,'listfn,'xmodideallist);
  36. put('xmodideal,'simpfn,'simpxmodideal);
  37. symbolic procedure simpxmodideal u;
  38. % u:{prefix,prefix} -> simpxmodideal:sq
  39. begin scalar x;
  40. if length u neq 2 then
  41. rerror(xideal,0,"Wrong number of arguments to xmodideal");
  42. x := getrlist aeval cadr u;
  43. u := xpartitop car u;
  44. xtruncate!* := xmaxdegree u;
  45. x := for each f in x join if f := xpartitop f then {f};
  46. foreach f in x do if not xhomogeneous f then xtruncate!* := nil;
  47. x := xidealpf x where !*trxmod = nil; % is this desirable?
  48. return !*pf2sq repartit xreduce(u,x);
  49. end;
  50. symbolic procedure xmodideallist(u,v);
  51. % u:{prefix,prefix},v:bool -> xmodideallist:prefix
  52. begin scalar x;
  53. if length u neq 2 then
  54. rerror(xideal,0,"Wrong number of arguments to xmodideal");
  55. x := getrlist aeval cadr u;
  56. u := foreach f in getrlist aeval car u collect xpartitop f;
  57. xtruncate!* := eval('max . foreach f in u collect xmaxdegree f);
  58. x := for each f in x join if f := xpartitop f then {f};
  59. foreach f in x do if not xhomogeneous f then xtruncate!* := nil;
  60. x := xidealpf x where !*trxmod = nil; % is this desirable?
  61. return makelist foreach f in u join
  62. if f := xreduce(f,x) then {!*q2a1(!*pf2sq repartit f,v)};
  63. end;
  64. put('xauto,'rtypefn,'quotelist);
  65. put('xauto,'listfn,'xautolist);
  66. symbolic procedure xautolist(u,v);
  67. % u:{prefix},v:bool -> xautolist:prefix
  68. begin scalar x;
  69. if length u neq 1 then
  70. rerror(xideal,0,"Wrong number of arguments to xauto");
  71. u := foreach f in getrlist aeval car u collect xpartitop f;
  72. return makelist foreach f in xautoreduce u join
  73. {!*q2a1(!*pf2sq repartit f,v)};
  74. end;
  75. symbolic procedure xreduce(f,p);
  76. % f:pf, p:list of pf -> xreduce:pf
  77. % returns left normal form of f wrt p
  78. % l contains reduction chain (not used at present).
  79. begin scalar g,l;
  80. l := nil . nil;
  81. if !*trxmod then
  82. <<writepri(mkquote preppf f,'nil);
  83. writepri(" =",'last)>>;
  84. g := xreduce1(f,p,l);
  85. if !*trxmod then
  86. <<writepri(" ",'first);
  87. writepri(mkquote preppf g,'last)>>;
  88. return g;
  89. end;
  90. symbolic procedure xreduce1(f,p,l);
  91. % f:pf, p:list of pf, l:list of {pf,pf} -> xreduce1:pf
  92. % Returns left normal form of f wrt p. Chain of reducing poly's and
  93. % cofactors stored in l as side-effect.
  94. if (f := weak_xreduce1(f,p,l)) then lt f .+ xreduce1(red f,p,l);
  95. symbolic procedure weak_xreduce(f,p);
  96. % f:pf, p:list of pf, result:pf
  97. % Returns weak left normal form of f wrt p (i.e. lpow f is
  98. % irreducible).
  99. begin scalar g,l;
  100. l := nil . nil;
  101. if !*trxmod then
  102. <<writepri(mkquote preppf f,'nil);
  103. writepri(" =",'last)>>;
  104. g := weak_xreduce1(f,p,l);
  105. if !*trxmod then
  106. <<writepri(" ",'first);
  107. writepri(mkquote preppf g,'last)>>;
  108. return g;
  109. end;
  110. symbolic procedure weak_xreduce1(f,p,l);
  111. % f:pf, p:list of pf, l:list of {pf,pf} -> weak_xreduce1:pf
  112. % Returns weak left normal form of f wrt p (i.e. lpow f is
  113. % irreducible).
  114. % Chain of reducing poly's and cofactors stored in l as side-effect.
  115. begin scalar q,g,h,c,r;
  116. q := p;
  117. while f and q do
  118. begin
  119. g := car q; q := cdr q;
  120. if (r := xdiv(xval g,xval f)) then
  121. begin
  122. r := !*k2pf mknwedge r;
  123. h := wedgepf(r,g); % NB: left multiplication here
  124. c := quotsq(lc f,lc h);
  125. f := subs2pf addpf(f,multpfsq(h,negsq c));
  126. if !*trxmod then l := nconc(l,{{multpfsq(r,c),g}});
  127. if !*trxmod then
  128. <<writepri(" ",'first);
  129. writepri(mkquote
  130. {'wedge,preppf multpfsq(r,c),preppf g},nil);
  131. writepri(" +",'last);>>;
  132. q := p;
  133. end;
  134. end;
  135. return f;
  136. end;
  137. symbolic procedure xautoreduce F;
  138. % F:list of pf -> weak_xautoreduce:list of pf
  139. % returns autoreduced form of F,
  140. % sorted in increasing order of leading terms
  141. xautoreduce1 weak_xautoreduce F;
  142. symbolic procedure xautoreduce1 G;
  143. % G:list of pf -> xautoreduce1:list of pf
  144. % G is weakly autoreduced, result is autoreduced and sorted
  145. begin scalar H;
  146. H := reversip sort(G,'pfordp); % otherwise need to reduce wrt H too.
  147. G := {};
  148. while H do
  149. begin scalar k;
  150. k := car H; H := cdr H;
  151. k := xreduce(k,G);
  152. if k then G := k . G;
  153. end;
  154. return reversip G;
  155. end;
  156. symbolic procedure weak_xautoreduce F;
  157. % F:list of pf -> weak_xautoreduce:list of pf
  158. % returns weakly autoreduced form of F
  159. weak_xautoreduce1(F,{});
  160. symbolic procedure weak_xautoreduce1(F,G);
  161. % F,G:list of pf -> weak_xautoreduce1:list of pf
  162. % G is (weakly) autoreduced, F may be reducible wrt G.
  163. begin
  164. while F do
  165. begin scalar k;
  166. k := car F; F := cdr F;
  167. if k := weak_xreduce(k,G) then
  168. begin
  169. k := xnormalise k;
  170. foreach h in G do
  171. if xdiv(xval k,xval h) then
  172. <<F := h . F;
  173. G := delete(h,G)>>;
  174. G := append(G,{k});
  175. end;
  176. end;
  177. return G;
  178. end;
  179. % symbolic procedure print_reduction_chain(f,l,g);
  180. % % f,g:pf, l:list of {pf,pf} -> print_reduction_chain:nil
  181. % begin
  182. % writepri(mkquote preppf f,'nil);
  183. % writepri(" =",'last);
  184. % foreach pr in cdr l do
  185. % <<writepri(" ",'first);
  186. % writepri(mkquote preppf car pr,nil);
  187. % writepri(mkquote '(wedge " " " "),'nil);
  188. % writepri("(",'nil);
  189. % writepri(mkquote preppf cadr pr,nil);
  190. % writepri(") +",'last);>>;
  191. % writepri(" ",'first);
  192. % writepri(mkquote preppf g,'last);
  193. % end;
  194. endmodule;
  195. end;