resultnt.red 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. module resultnt;
  2. % Author: Eberhard Schruefer.
  3. % Modifications by: Anthony C. Hearn, Winfried Neun.
  4. %**********************************************************************
  5. % *
  6. % The resultant function defined here has the following properties: *
  7. % *
  8. % degr(p1,x)*degr(p2,x) *
  9. % resultant(p1,p2,x) = (-1) *resultant(p2,p1,x) *
  10. % *
  11. % degr(p2,x) *
  12. % resultant(p1,p2,x) = p1 if p1 free of x *
  13. % *
  14. % resultant(p1,p2,x) = 1 if p1 free of x and p2 free of x *
  15. % *
  16. %**********************************************************************
  17. %exports resultant;
  18. %imports reorder,setkorder,degr,addf,negf,multf,multpf;
  19. load_package polydiv;
  20. fluid '(!*bezout !*exp kord!*);
  21. switch bezout;
  22. put('resultant,'simpfn,'simpresultant);
  23. symbolic procedure simpresultant u;
  24. if length u neq 3
  25. then rerror(matrix,19,
  26. "Resultant called with wrong number of arguments")
  27. else resultantsq(simp!* car u,simp!* cadr u,!*a2k caddr u)
  28. where !*exp = t;
  29. symbolic procedure resultant(u,v,var);
  30. % Kept for compatibility with old code.
  31. if domainp u and domainp v then 1
  32. else begin scalar x;
  33. kord!* := var . kord!*; % updkorder can't be used here.
  34. % See sum test.
  35. if null domainp u and null(mvar u eq var) then u := reorder u;
  36. if null domainp v and null(mvar v eq var) then v := reorder v;
  37. x := if !*bezout then bezout_resultant(u,v,var)
  38. else !*a2f polyresultant(prepf u,prepf v,var);
  39. setkorder cdr kord!*;
  40. return x
  41. end;
  42. symbolic procedure resultantsq(u,v,var);
  43. if domainp numr u and domainp numr v and denr u = 1 and denr v = 1
  44. then 1 ./ 1
  45. else begin scalar x;
  46. kord!* := var . kord!*; % updkorder can't be used here.
  47. % See sum test.
  48. if null domainp numr u and null(mvar numr u eq var)
  49. then u := reordsq u;
  50. if null domainp numr v and null(mvar numr v eq var)
  51. then v := reordsq v;
  52. x := if !*bezout then !*f2q bezout_resultant(!*q2f u,!*q2f v,var)
  53. else simp polyresultant(prepsq u,prepsq v,var);
  54. setkorder cdr kord!*;
  55. return x
  56. end;
  57. algebraic (co_off := { co(0,~x) => x });
  58. % algebraic procedure notunivariatep(uu);
  59. % for i:=1:length uu sum if fixp part(uu,i) then 0 else 1;
  60. algebraic procedure notunivariatep uu;
  61. for each u in uu sum if fixp u then 0 else 1;
  62. algebraic procedure polyresultant(u,v,var);
  63. % See Zippel's book p 151, subresultant algorithm --
  64. % more or less the same.
  65. begin scalar g,h,delta,beta,temp,uu,vv;
  66. uu := coeff(u,var); vv := coeff(v,var);
  67. if length uu<length vv
  68. then return (-1 * polyresultant(v,u,var))
  69. else if (notunivariatep(uu) > 0) or (notunivariatep(vv)>0)
  70. then <<u := for i:=1:length uu sum
  71. (if fixp part(uu,i) then part(uu,i)
  72. else (co(0,part(uu,i))))*var^(i-1);
  73. v := for i:=1:length vv sum
  74. (if fixp part(vv,i) then part(vv,i)
  75. else (co(0,part(vv,i))))*var^(i-1)>>;
  76. % Change to nested domain.
  77. g := h := 1;
  78. while not (V=0) do
  79. <<delta := deg(u,var) - deg(v,var);
  80. beta := (-1)^(delta +1) * g * h^delta;
  81. h := h*(lcof(v,var)/h)^delta;
  82. temp := u;
  83. u := v;
  84. v := pseudo_remainder(temp,v,var)/beta;
  85. g := lcof(u,var)>>;
  86. if deg(u,var) = 0 then u := u^delta else return 0;
  87. let co_off; u := u; clearrules co_off;
  88. return u
  89. end;
  90. symbolic procedure lcoff(u,var);
  91. if domainp u or not(mvar u eq var) then 0 else lc u;
  92. symbolic procedure bezout_resultant(u,v,w);
  93. % U and v are standard forms. Result is resultant of u and v
  94. % w.r.t. kernel w. Method is Bezout's determinant using exterior
  95. % multiplication for its calculation.
  96. begin integer n,nm; scalar ap,ep,uh,ut,vh,vt;
  97. if domainp u or null(mvar u eq w)
  98. then return if not domainp v and mvar v eq w
  99. then exptf(u,ldeg v)
  100. else 1
  101. else if domainp v or null(mvar v eq w)
  102. then return if mvar u eq w then exptf(v,ldeg u) else 1;
  103. n := ldeg u - ldeg v;
  104. ep := 1;
  105. if n<0 then
  106. <<for j := (-n-1) step -1 until 1 do
  107. ep := b!:extmult(!*sf2exb(multpf(w to j,u),w),ep);
  108. ep := b!:extmult(!*sf2exb(multd((-1)**(-n*ldeg u),u),
  109. w),
  110. ep)>>
  111. else if n>0 then
  112. <<for j := (n-1) step -1 until 1 do
  113. ep := b!:extmult(!*sf2exb(multpf(w to j,v),w),ep);
  114. ep := b!:extmult(!*sf2exb(v,w),ep)>>;
  115. nm := max(ldeg u,ldeg v);
  116. uh := lc u;
  117. vh := lc v;
  118. ut := if n<0 then multpf(w to -n,red u)
  119. else red u;
  120. vt := if n>0 then multpf(w to n,red v)
  121. else red v;
  122. ap := addf(multf(uh,vt),negf multf(vh,ut));
  123. ep := if null ep then !*sf2exb(ap,w)
  124. else b!:extmult(!*sf2exb(ap,w),ep);
  125. for j := (nm - 1) step -1 until (abs n + 1) do
  126. <<if degr(ut,w) = j then
  127. <<uh := addf(lc ut,multf(!*k2f w,uh));
  128. ut := red ut>>
  129. else uh := multf(!*k2f w,uh);
  130. if degr(vt,w) = j then
  131. <<vh := addf(lc vt,multf(!*k2f w,vh));
  132. vt := red vt>>
  133. else vh := multf(!*k2f w,vh);
  134. ep := b!:extmult(!*sf2exb(addf(multf(uh,vt),
  135. negf multf(vh,ut)),w),ep)>>;
  136. return if null ep then nil else lc ep
  137. end;
  138. symbolic procedure !*sf2exb(u,v);
  139. %distributes s.f. u with respect to powers in v.
  140. if degr(u,v)=0 then if null u then nil
  141. else list 0 .* u .+ nil
  142. else list ldeg u .* lc u .+ !*sf2exb(red u,v);
  143. %**** Support for exterior multiplication ****
  144. % Data structure is lpow ::= list of degrees in exterior product
  145. % lc ::= standard form
  146. symbolic procedure b!:extmult(u,v);
  147. %Special exterior multiplication routine. Degree of form v is
  148. %arbitrary, u is a one-form.
  149. if null u or null v then nil
  150. else if v = 1 then u
  151. else (if x then cdr x .* (if car x then negf multf(lc u,lc v)
  152. else multf(lc u,lc v))
  153. .+ b!:extadd(b!:extmult(!*t2f lt u,red v),
  154. b!:extmult(red u,v))
  155. else b!:extadd(b!:extmult(red u,v),
  156. b!:extmult(!*t2f lt u,red v)))
  157. where x = b!:ordexn(car lpow u,lpow v);
  158. symbolic procedure b!:extadd(u,v);
  159. if null u then v
  160. else if null v then u
  161. else if lpow u = lpow v then
  162. (lambda x,y; if null x then y else lpow u .* x .+ y)
  163. (addf(lc u,lc v),b!:extadd(red u,red v))
  164. else if b!:ordexp(lpow u,lpow v) then lt u .+ b!:extadd(red u,v)
  165. else lt v .+ b!:extadd(u,red v);
  166. symbolic procedure b!:ordexp(u,v);
  167. if null u then t
  168. else if car u > car v then t
  169. else if car u = car v then b!:ordexp(cdr u,cdr v)
  170. else nil;
  171. symbolic procedure b!:ordexn(u,v);
  172. %u is a single integer, v a list. Returns nil if u is a member
  173. %of v or a dotted pair of a permutation indicator and the ordered
  174. %list of u merged into v.
  175. begin scalar s,x;
  176. a: if null v then return(s . reverse(u . x))
  177. else if u = car v then return nil
  178. else if u and u > car v then
  179. return(s . append(reverse(u . x),v))
  180. else <<x := car v . x;
  181. v := cdr v;
  182. s := not s>>;
  183. go to a
  184. end;
  185. endmodule;
  186. end;