nestrad.red 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. module nestrad; % Simplify nested square roots.
  2. % Author: H. Melenk.
  3. % Modifications by: A. C. Hearn:
  4. % The case sqrt(x+8-6*sqrt(x-1)) gave the wrong sign for say x=5.
  5. % However, adding an abs call messed up int(1/(x**4+4*x**2+1),x).
  6. % So for the time being, we only use this code when the argument can
  7. % be shown to be a non-negative number.
  8. fluid '(!*intflag!*);
  9. symbolic procedure unnest!-sqrt!-sqrt!*(a0,b0,r0);
  10. % look for a simplified equivalent to sqrt(a + b*sqrt(c));
  11. % See: Borodin et al, JSC (1985) 1,p 169ff.
  12. begin scalar d,a,b,r,s,w;
  13. if numberp r and r<0 then return nil;
  14. a:=simp a0; b:=simp b0; r:=simp r0;
  15. % discriminant: d:=sqrt(a^2-b^2*r).
  16. d:=subtrsq(multsq(a,a),multsq(multsq(b,b),r));
  17. if denr d neq 1 or (not domainp(d:=numr d) and not evenp ldeg d)
  18. or cdr(d:=radf(d,2)) then return nil;
  19. d := car d ./ 1;
  20. % s := 2(a+d).
  21. s:=addsq(a,d); s:=addsq(s,s); s:=prepsq s;
  22. % w:=(s+2 b sqrt r)/2 sqrt s.
  23. w:={'quotient,{'times,{'sqrt,s},{'plus,s,{'times,2,b0,{'sqrt,r0}}}},
  24. {'times,2,s}};
  25. return w;
  26. end;
  27. symbolic procedure unnest!-sqrt!-sqrt(a,b,r);
  28. begin scalar w;
  29. return if (w:=unnest!-sqrt!-sqrt!*(a,b,r)) then chkabs w
  30. else if (w:=unnest!-sqrt!-sqrt!*({'times,b,r},a,r))
  31. then chkabs {'quotient,w,{'expt,r,{'quotient,1,4}}}
  32. else nil
  33. end;
  34. symbolic procedure chkabs u;
  35. if !*intflag!* then u % The integrator doesn't care about sign.
  36. % else (if null x then {'abs,u}
  37. else (if null x then u
  38. else if not minusp!: x then u
  39. else {'minus,u})
  40. where x = not_imag_num u;
  41. symbolic operator unnest!-sqrt!-sqrt;
  42. algebraic;
  43. sqrtsqrt_rules := {
  44. (~a + ~b * ~c^(1/2)) ^(1/2) => !*!*w
  45. when (!*!*w:=unnest!-sqrt!-sqrt(a,b,c)),
  46. (~a + ~c^(1/2)) ^(1/2) => !*!*w
  47. when (!*!*w:=unnest!-sqrt!-sqrt(a,1,c))}$
  48. let sqrtsqrt_rules;
  49. endmodule;
  50. end;