conj.red 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. module conj; % Rationalize denoms of standard quotients by conjugate
  2. % computation.
  3. % Author: Anthony C. Hearn.
  4. % Modifications by: Eberhard Schruefer.
  5. % Copyright (c) 1992 RAND. All rights reserved.
  6. fluid '(!*algint !*rationalize !*structure dmode!* kord!* powlis!*);
  7. put('rationalize,'simpfg,'((t (rmsubs)) (nil (rmsubs))));
  8. symbolic smacro procedure subtrf(u,v);
  9. % Returns u - v for standard forms u and v.
  10. addf(u,negf v);
  11. symbolic procedure rationalizesq u;
  12. % Rationalize the standard quotient u.
  13. begin scalar !*structure,!*sub2,v,x; % Modified by R. Liska.
  14. % We need structure off to form rationalized denominator properly
  15. % in subs2f1.
  16. % ACH had hoped that the cost of having GCD on here was small,
  17. % since the consequences can be large (e.g., df(log((sqrt(a^2+x^2)
  18. % +2*sqrt(sqrt(a^2+x^2)*a+a*x)+a+x)/(sqrt(a^2+x^2) - a + x)),x)).
  19. % However, limit((sqrt(x^(2/5) +1) - x^(1/3)-1)/x^(1/3),x,0) takes
  20. % too long.
  21. if x := get(dmode!*,'rationalizefn) then u := apply1(x,u);
  22. % We need the following in case we are in sparse_bareiss.
  23. powlis!* := '(i 2 (nil . t) -1 nil) . powlis!*;
  24. v := subs2q u;
  25. powlis!* := cdr powlis!*;
  26. % We need the subs2 to get rid of surd powers.
  27. % We also need to check if u has changed from the example
  28. % df((1/x)**(2/3),x).
  29. return if domainp denr v then v
  30. else if (x := rationalizef denr v) neq 1
  31. then <<v := multf(numr v,x) ./ multf(denr v,x);
  32. % We need the gcdchk so that df((1/x)**(2/3),x)
  33. % is not in a loop. However, algint needs all
  34. % factors for some reason.
  35. if null !*algint and null !*rationalize
  36. then v := gcdchk v;
  37. % There used to be an exptchk here, but that led
  38. % to loops (e.g., in df(int(1/(3*x**4+7),x),x)).
  39. v := subs2q v;
  40. if not domainp numr quotsq(u,v)
  41. then rationalizesq v else v>>
  42. else u
  43. end;
  44. symbolic procedure lowertowerp(u,v);
  45. % True if v is potentially an algebraic component of a member of v.
  46. if null u then nil
  47. else if atom car u or cdar u = v then lowertowerp(cdr u,v)
  48. else if caar u eq 'expt
  49. and eqcar(caddar u,'quotient)
  50. and cadr caddar u = cadr cadr v % numerator of quotient.
  51. and fixp caddr caddar u and fixp caddr cadr v
  52. and cdr divide(caddr caddar u,caddr cadr v) = 0 % denominator.
  53. and lowertowerp1(cadar u,car v)
  54. then car u
  55. else lowertowerp(cdr u,v);
  56. symbolic procedure lowertowerp1(u,v);
  57. % This procedure decides if u can be an algebraic extension of v.
  58. % The = case is decidedly heuristic at the moment.
  59. % We could think of this as a membership test (including =).
  60. % However, different SQRT representations complicate things.
  61. (if x>y then t
  62. else if numberp u and numberp v then not(gcdn(u,v)=1)
  63. else x=y)
  64. where x=exprsize u,y=exprsize v;
  65. symbolic procedure exprsize u;
  66. % Get size of u. Iterative to avoid excessive recursion.
  67. begin integer n;
  68. a: if null u then return n else if atom u then return n+1;
  69. n := exprsize car u + n;
  70. u := cdr u;
  71. go to a
  72. end;
  73. symbolic procedure rationalizef u;
  74. % Look for I and sqrts, cbrts, quartics at present.
  75. % I'm not sure I in the presence of (-1)^(1/4) say is handled
  76. % properly.
  77. % It is assumed that any surd powers have been reduced before
  78. % entering this procedure.
  79. begin scalar x,y,z;
  80. x := z := kernels u;
  81. a: if null x then return 1;
  82. y := car x;
  83. if eqcar(y,'expt) and eqcar(caddr y,'quotient)
  84. and lowertowerp(z,cdr y)
  85. then nil
  86. else if y eq 'i or eqcar(y,'expt) and caddr y = '(quotient 1 2)
  87. or eqcar(y,'sqrt)
  88. then return conjquadratic(mkmain(u,y),y)
  89. else if eqcar(y,'expt) and caddr y = '(quotient 1 3)
  90. then return conjcubic(mkmain(u,y),y)
  91. else if eqcar(y,'expt) and caddr y = '(quotient 1 4)
  92. then return conjquartic(mkmain(u,y),y);
  93. x := cdr x;
  94. go to a
  95. end;
  96. symbolic procedure conjquadratic(u,v);
  97. if ldeg u = 1
  98. then subtrf(multf(!*k2f v,reorder lc u),reorder red u)
  99. else errach list(ldeg u,"invalid power in rationalizef");
  100. symbolic procedure conjcubic(u,v);
  101. begin scalar c1,c2,c3,w;
  102. if ldeg u = 2 then <<c1 := reorder lc u;
  103. if degr(red u,v) = 1
  104. then <<c2 := reorder lc red u;
  105. c3 := reorder red red u>>
  106. else c3 := reorder red u>>
  107. else <<c2 := reorder lc u;
  108. c3 := reorder red u>>;
  109. w := conj2 v;
  110. if w eq 'failed then return u;
  111. v := !*k2f v;
  112. return addf(multf(exptf(v,2),subtrf(exptf(c2,2),multf(c1,c3))),
  113. addf(multf(v,subtrf(multf(w,exptf(c1,2)),
  114. multf(c2,c3))),
  115. subtrf(exptf(c3,2),multf(w,multf(c1,c2)))))
  116. end;
  117. symbolic procedure conj2 u;
  118. % (if not domainp denr v then errach list("conj2",u)
  119. (if not domainp denr v then 'failed
  120. else if denr v neq 1 then multd(!:recip denr v,numr v)
  121. else numr v)
  122. where v = simp cadr u;
  123. symbolic procedure conjquartic(u,v);
  124. begin scalar c1,c3,c4,q1,q2,q3,q4,w;
  125. if ldeg u = 3
  126. then <<c1 := reorder lc u;
  127. if degr(red u,v) = 1
  128. then <<c3 := reorder lc red u;
  129. c4 := reorder red red u>>
  130. else c4 := reorder red u>>
  131. else if ldeg u = 1
  132. then <<c3 := reorder lc u;
  133. c4 := reorder red u>>;
  134. w := conj2 v;
  135. if w eq 'failed then return u;
  136. v := !*k2f v;
  137. q1 := subtrf(addf(exptf(c3,3),multf(c1,exptf(c4,2))),
  138. multf(w,multf(c3,exptf(c1,2))));
  139. q2 := negf addf(multf(w,multf(c4,exptf(c1,2))),
  140. multf(exptf(c3,2),c4));
  141. q3 := addf(multf(c3,exptf(c4,2)),
  142. subtrf(multf(exptf(w,2),exptf(c1,3)),
  143. multf(w,multf(c1,exptf(c3,2)))));
  144. q4 := subtrf(multf(w,multf(multd(2,c1),multf(c3,c4))),exptf(c4,3));
  145. return addf(multf(exptf(v,3),q1),
  146. addf(multf(exptf(v,2),q2),addf(multf(v,q3),q4)))
  147. end;
  148. symbolic procedure mkmain(u,var);
  149. % Make kernel var the main variable of u.
  150. begin scalar kord!*; kord!* := list var; return reorder u end;
  151. endmodule;
  152. end;