conj.red 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. % We need to suppress following to avoid a non-
  40. % terminating evaluation of df(tan((sqrt(1-x^2)
  41. % *asin acos x + 2*sqrt(1-x^2)*x)/x),x).
  42. % v := subs2q v;
  43. % if not domainp numr quotsq(u,v)
  44. % then rationalizesq v else v>>
  45. subs2q v>>
  46. else u
  47. end;
  48. symbolic procedure lowertowerp(u,v);
  49. % True if v is potentially an algebraic component of a member of v.
  50. if null u then nil
  51. else if atom car u or cdar u = v then lowertowerp(cdr u,v)
  52. else if caar u eq 'expt
  53. and eqcar(caddar u,'quotient)
  54. and cadr caddar u = cadr cadr v % numerator of quotient.
  55. and fixp caddr caddar u and fixp caddr cadr v
  56. and cdr divide(caddr caddar u,caddr cadr v) = 0 % denominator.
  57. and lowertowerp1(cadar u,car v)
  58. then car u
  59. else lowertowerp(cdr u,v);
  60. symbolic procedure lowertowerp1(u,v);
  61. % This procedure decides if u can be an algebraic extension of v.
  62. % The = case is decidedly heuristic at the moment.
  63. % We could think of this as a membership test (including =).
  64. % However, different SQRT representations complicate things.
  65. (if x>y then t
  66. else if numberp u and numberp v then not(gcdn(u,v)=1)
  67. else x=y)
  68. where x=exprsize u,y=exprsize v;
  69. symbolic procedure exprsize u;
  70. % Get size of u. Iterative to avoid excessive recursion.
  71. begin integer n;
  72. a: if null u then return n else if atom u then return n+1;
  73. n := exprsize car u + n;
  74. u := cdr u;
  75. go to a
  76. end;
  77. symbolic procedure rationalizef u;
  78. % Look for I and sqrts, cbrts, quartics at present.
  79. % I'm not sure I in the presence of (-1)^(1/4) say is handled
  80. % properly.
  81. % It is assumed that any surd powers have been reduced before
  82. % entering this procedure.
  83. begin scalar x,y,z;
  84. x := z := kernels u;
  85. a: if null x then return 1;
  86. y := car x;
  87. if eqcar(y,'expt) and eqcar(caddr y,'quotient)
  88. and lowertowerp(z,cdr y)
  89. then nil
  90. else if y eq 'i or eqcar(y,'expt) and caddr y = '(quotient 1 2)
  91. or eqcar(y,'sqrt)
  92. then return conjquadratic(mkmain(u,y),y)
  93. else if eqcar(y,'expt) and caddr y = '(quotient 1 3)
  94. then return conjcubic(mkmain(u,y),y)
  95. else if eqcar(y,'expt) and caddr y = '(quotient 1 4)
  96. then return conjquartic(mkmain(u,y),y);
  97. x := cdr x;
  98. go to a
  99. end;
  100. symbolic procedure conjquadratic(u,v);
  101. if ldeg u = 1
  102. then subtrf(multf(!*k2f v,reorder lc u),reorder red u)
  103. else errach list(ldeg u,"invalid power in rationalizef");
  104. symbolic procedure conjcubic(u,v);
  105. begin scalar c1,c2,c3,w;
  106. if ldeg u = 2 then <<c1 := reorder lc u;
  107. if degr(red u,v) = 1
  108. then <<c2 := reorder lc red u;
  109. c3 := reorder red red u>>
  110. else c3 := reorder red u>>
  111. else <<c2 := reorder lc u;
  112. c3 := reorder red u>>;
  113. w := conj2 v;
  114. if w eq 'failed then return u;
  115. v := !*k2f v;
  116. return addf(multf(exptf(v,2),subtrf(exptf(c2,2),multf(c1,c3))),
  117. addf(multf(v,subtrf(multf(w,exptf(c1,2)),
  118. multf(c2,c3))),
  119. subtrf(exptf(c3,2),multf(w,multf(c1,c2)))))
  120. end;
  121. symbolic procedure conj2 u;
  122. % (if not domainp denr v then errach list("conj2",u)
  123. (if not domainp denr v then 'failed
  124. else if denr v neq 1 then multd(!:recip denr v,numr v)
  125. else numr v)
  126. where v = simp cadr u;
  127. symbolic procedure conjquartic(u,v);
  128. begin scalar c1,c3,c4,q1,q2,q3,q4,w;
  129. if ldeg u = 3
  130. then <<c1 := reorder lc u;
  131. if degr(red u,v) = 1
  132. then <<c3 := reorder lc red u;
  133. c4 := reorder red red u>>
  134. else c4 := reorder red u>>
  135. else if ldeg u = 1
  136. then <<c3 := reorder lc u;
  137. c4 := reorder red u>>;
  138. w := conj2 v;
  139. if w eq 'failed then return u;
  140. v := !*k2f v;
  141. q1 := subtrf(addf(exptf(c3,3),multf(c1,exptf(c4,2))),
  142. multf(w,multf(c3,exptf(c1,2))));
  143. q2 := negf addf(multf(w,multf(c4,exptf(c1,2))),
  144. multf(exptf(c3,2),c4));
  145. q3 := addf(multf(c3,exptf(c4,2)),
  146. subtrf(multf(exptf(w,2),exptf(c1,3)),
  147. multf(w,multf(c1,exptf(c3,2)))));
  148. q4 := subtrf(multf(w,multf(multd(2,c1),multf(c3,c4))),exptf(c4,3));
  149. return addf(multf(exptf(v,3),q1),
  150. addf(multf(exptf(v,2),q2),addf(multf(v,q3),q4)))
  151. end;
  152. symbolic procedure mkmain(u,var);
  153. % Make kernel var the main variable of u.
  154. begin scalar kord!*; kord!* := list var; return reorder u end;
  155. endmodule;
  156. end;