hsub.red 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. module hsub;
  2. %% Harmonic substitution: the CAMAL HSUB operation, as well as other
  3. %% substitutions.
  4. fluid '(!*trharm);
  5. switch trham;
  6. symbolic procedure hsub1(x,u,v,A,n);
  7. %% Substitute v+A for u in x to order n
  8. begin scalar ans, c, tmp, fs!:zero!-generated;
  9. %% fs!:zero!-generated := 0;
  10. ans := fs!:subang(x, u, v);
  11. % c := ensure!-fourier A;
  12. c := car A;
  13. if c then c := cdr c;
  14. A := c;
  15. if !*trham
  16. then << print "A"; if null A then print 0 else fs!:prin A >>;
  17. for i:=1:n do <<
  18. if !*trham then << print "i="; print i >>;
  19. x := hdiff(x, u);
  20. if !*trham then << prin2!* "df(x,u,i)="; fs!:prin x; terpri!* t;
  21. prin2!* "A^i ="; fs!:prin c; terpri!* t >>;
  22. c := fs!:times(cdr !*sq2fourier (1 ./ i), c);
  23. if !*trham
  24. then << prin2!* "A^i/fact(i) ="; fs!:prin c; terpri!* t>>;
  25. tmp := fs!:times(fs!:subang(x, u, v), c);
  26. if !*trham then <<
  27. prin2!* "f'(0)*A^i/fact i = "; fs!:prin tmp; terpri!* t>>;
  28. ans := fs!:plus(ans, tmp);
  29. if !*trham
  30. then << prin2!* "partial sum ="; fs!:prin ans; terpri!* t>>;
  31. if not(i=n) then c := fs!:times(c,A);
  32. >>;
  33. return ans
  34. end;
  35. symbolic procedure fs!:subang(x, u, v);
  36. if null x then nil
  37. else begin scalar vv, n;
  38. vv := mkvect 7;
  39. n := getv!.unsafe(fs!:angle x, u);
  40. for i:=0:7 do if i = u then putv!.unsafe(vv, i, n*getv!.unsafe(v,i))
  41. else putv!.unsafe(vv, i,
  42. getv!.unsafe(fs!:angle x,i) + n*getv!.unsafe(v,i));
  43. return fs!:plus(fs!:subang(fs!:next x, u, v),
  44. make!-term(fs!:fn x, vv, fs!:coeff x));
  45. end;
  46. symbolic procedure fs!:sub(x,u);
  47. if null x then nil else
  48. begin scalar ans;
  49. ans := aeval prepsq fs!:coeff x;
  50. if not fixp ans then ans := subsq(cadr ans, u)
  51. else ans := fs!:coeff x;
  52. if eqcar(numr ans, '!:fs!:) then ans := cdar ans
  53. else ans := cdr !*sq2fourier ans;
  54. ans := fs!:times(make!-term(fs!:fn x, fs!:angle x, 1 ./ 1), ans);
  55. return fs!:plus(fs!:sub(fs!:next x, u), ans);
  56. end;
  57. symbolic procedure simphsub uu;
  58. begin scalar x, u, v, vv, A, n, dmode!*;
  59. dmode!* := '!:fs!:;
  60. if (length uu = 5) then <<
  61. x := car uu; uu := cdr uu;
  62. u := car uu; uu := cdr uu;
  63. v := car uu; uu := cdr uu;
  64. A := car uu; uu := cdr uu;
  65. n := car uu
  66. >>
  67. else if (length uu = 3) then <<
  68. x := car uu; uu := cdr uu;
  69. u := car uu; uu := cdr uu;
  70. v := car uu; uu := cdr uu;
  71. if not harmonicp u then <<
  72. A := ( ((get('fourier, 'tag) .
  73. fs!:sub(cdar simp x, list(u . v))) ./ 1)
  74. ) where wtl!*=delasc(u,wtl!*);
  75. return A;
  76. >>;
  77. A := 0;
  78. n := 0
  79. >>;
  80. if not harmonicp u then
  81. rerror(fourier, 7, "Not an angle in HSUB");
  82. x := cdar simp x;
  83. if not angle!-expression!-p v then
  84. rerror(fourier, 8, "Not an angle expression in HSUB");
  85. vv := mkvect 7;
  86. for i:=0:7 do putv!.unsafe(vv,i,0);
  87. compile!-angle!-expression(v, vv);
  88. A := simp!* A;
  89. n := simp!* n;
  90. if null car n then n := 0 ./ 1
  91. else if not(fixp car n and cdr n = 1) then
  92. rerror(fourier, 9, "Non integer expansion in HSUB");
  93. n := car n;
  94. return (get('fourier, 'tag) .
  95. hsub1(x,get(u,'fourier!-angle),vv,A,n)) ./ 1;
  96. end;
  97. put('hsub, 'simpfn, 'simphsub);
  98. endmodule;
  99. end;