horner.red 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. module horner; % Convert an expression into a nested Horner product.
  2. % Author: Herbert Melenk.
  3. fluid '(!*exp !*div);
  4. symbolic procedure hornersq u;
  5. if !*div and null dmode!* and numberp denr u and denr u neq 1 then
  6. <<setdmode('rational,t);
  7. u:=hornerf quotf(numr u, denr u);
  8. setdmode('rational,nil);
  9. u ./ 1>>
  10. else hornerf numr u . hornerf denr u;
  11. symbolic procedure hornerf u;
  12. <<u:=expnd u where !*exp=t; hornerf1 u where !*exp=nil>>;
  13. symbolic procedure hornerf1 u;
  14. begin scalar x,a,b,c; integer n,m;
  15. if domainp u then return u;
  16. if domainp red u then goto q;
  17. % Identify the pattern
  18. % x^n*a + x^m*b + c with n>m
  19. % and transform it into
  20. % x^m(x^(n-m)*a + b) + c
  21. % calling hornerf1 again for folding x^m with powers of
  22. % x in c. Also a and b are folded recursively.
  23. % The term x^n*a may have the form (x^k*f+g)*x^n*h
  24. % by recursion; in that case a is (x^k*f+g)*h.
  25. if (x:=mvar u) = mvar red u then
  26. << n:=ldeg u; a:=hornerf1 lc u; u:=red u; m:=ldeg u;
  27. b:=hornerf1 lc u; c:=red u >>
  28. else if sfp mvar u and not domainp lc u and (x:=mvar lc u)=mvar red u
  29. and (n:=ldeg lc u)>(m:=ldeg red u) then
  30. << a:=multf(mvar u,lc lc u); u:=red u; b:=hornerf1 lc u; c:=red u >>
  31. else goto q;
  32. return hornerf1
  33. addf(multf(exptf(!*k2f x,m),
  34. addf(multf(exptf(!*k2f x,n-m),a),
  35. b)), c);
  36. q: return addf(multf(!*p2f lpow u,hornerf1 lc u),hornerf1 red u);
  37. end;
  38. put('horner,'polyfn,'hornerf);
  39. endmodule;
  40. end;