quotf.red 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. module quotfx;
  2. % Author: Herbert Melenk.
  3. Comment in many calls to QUOTF, the result is not checked for NIL
  4. because the caller is sure there will be no remainder, e.g. if the
  5. divisor is a gcd. This occurs not only at several places in the REDUCE
  6. kernel, but especially in Groebner, which simplifies polynomials with
  7. parameters by dividing out their contents.
  8. In all those cases, QUOTF computes too much: if you divide
  9. P= p_n x^n + p_n-1 x^(n-1) + ...
  10. Q= q_m x^m + q_m-1 x^(m-1) + ...
  11. (the coefficients may be polynomials in other variables)
  12. the result comes only from the first k=(n-m+1) coefficients of P. The
  13. remaining terms only have influence on the potential remainder. So it
  14. is not necessary to execute the subtractions completely if we don't
  15. need the remainder (or test for its absence).
  16. You can stop after the the power x^(n-k) in P and x^(m-k) in Q, and in
  17. the loop n down to m you can stop in Q again at each step depending on
  18. the actual k.
  19. The method is a polynomial extension of Jebelean's method for dividing
  20. bignums where you know in advance they have no remainder. The
  21. resulting code is a modification of the standard QUOTF code in polrep;
  22. symbolic procedure quotfx(u,v);
  23. if null !*exp or null !*mcd then quotf(u,v) else quotfx1(u,v);
  24. symbolic procedure quotfx1(p,q);
  25. % P and Q are standard forms where Q divides P without remainder.
  26. % Value is the quotient of P and Q.
  27. if null p then quotfxerr(p,q)
  28. else if p=q then 1
  29. else if q=1 then p
  30. else if domainp q then quotfdx(p,q)
  31. else if domainp p then quotfxerr(p,q)
  32. else if mvar p eq mvar q
  33. then begin scalar f,dp,dq,u,v,w,x,y,z; integer n;
  34. w := mvar q;
  35. dq:=ldeg q;
  36. a: if (dp:=ldeg p) <dq then return quotfxerr(p,q);
  37. u := lt!* p;
  38. v := lt!* q;
  39. w := mvar q;
  40. x := quotfx1(tc u,tc v);
  41. n := idifference(dp,dq);
  42. if n=0 then return rnconc(z,x);
  43. y := w .** n;
  44. if null f then p := cutf(p,w,isub1 idifference(dp,n));
  45. f:=t;
  46. q:=cutf(q,w,isub1 idifference(dq,n));
  47. p := addf(p,multf(if n=0 then q else multpf(y,q),negf x));
  48. if p and (domainp p or not(mvar p eq w)) then
  49. return quotfxerr(p,q);
  50. z := aconc!*(z,y .* x);
  51. if null p then return z;
  52. go to a
  53. end
  54. else if ordop(mvar p,mvar q) then quotkx(p,q)
  55. else quotfxerr(p,q);
  56. symbolic procedure quotkx(p,q);
  57. (if w then if null red p then list(lpow p .* w)
  58. else (if y then lpow p .* w .+ y else nil)
  59. where y=quotfx1(red p,q)
  60. else nil)
  61. where w=quotfx1(lc p,q);
  62. symbolic procedure quotfdx(p,q);
  63. if p=q then 1
  64. else if flagp(dmode!*,'field) then divd(p,q)
  65. else if domainp p then quotdd(p,q)
  66. else quotkx(p,q);
  67. symbolic procedure quotfxerr(u,v);
  68. rederr("exact division failed");
  69. symbolic procedure cutf(u,x,n);
  70. % U is a standard form. Delete the terms with a degree in x below n.
  71. if ilessp(n,1) then u else cutf1(u,x,n);
  72. symbolic procedure cutf1(u,x,n);
  73. if domainp u or mvar u neq x or ilessp(ldeg u,n) then nil else
  74. lt u .+ cutf1(red u,x,n);
  75. endmodule;
  76. end;