fourplus.red 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. module fourplus;
  2. %% ARITHMETIC
  3. %% Addition of Fourier expressionsis really a merge operation
  4. symbolic procedure fs!:plus!:(x,y);
  5. %% Top level addition of two fourier series
  6. if fs!:zerop!: y then x
  7. else if fs!:zerop!: x then y
  8. else get('fourier,'tag)
  9. . fs!:plus(copy!-tree cdr x, copy!-tree cdr y);
  10. % I cannot rely on the CAMAL selective copy, so I take the coward's way
  11. % out.
  12. symbolic procedure copy!-tree x;
  13. if null x then nil
  14. else begin scalar ans;
  15. ans := mkvect 3;
  16. fs!:set!-coeff(ans,fs!:coeff x);
  17. fs!:set!-fn(ans,fs!:fn x);
  18. fs!:set!-angle(ans,fs!:angle x);
  19. fs!:set!-next(ans, copy!-tree fs!:next x);
  20. return ans
  21. end;
  22. symbolic procedure fs!:plus(x, y);
  23. %% The real addition. x is a new tree to which y must be merged.
  24. if null y then x
  25. else if null x then y
  26. else if fs!:fn x = fs!:fn y
  27. and angles!-equal(fs!:angle x, fs!:angle y) then
  28. begin scalar coef;
  29. coef := addsq(fs!:coeff x, fs!:coeff y);
  30. % Really I should deal with the zero case here
  31. if null car coef
  32. then return fs!:plus(fs!:next x, fs!:next y);
  33. fs!:set!-coeff(x, coef);
  34. fs!:set!-next(x, fs!:plus(fs!:next x, fs!:next y));
  35. return x
  36. end
  37. else if fs!:angle!-order(x, y) then <<
  38. fs!:set!-next(x, fs!:plus(fs!:next x, y));
  39. x >>
  40. else <<
  41. fs!:set!-next(y, fs!:plus(fs!:next y,x));
  42. y >>;
  43. symbolic procedure angles!-equal(x, y);
  44. % Are all angles the same?
  45. begin scalar i;
  46. i := 0;
  47. top:
  48. if not(getv!.unsafe(x,i)=getv!.unsafe(y,i)) then return nil;
  49. i := i+1;
  50. if (i<8) then go to top;
  51. return t;
  52. end;
  53. symbolic procedure fs!:angle!-order(x, y);
  54. % Ordering function for angle expressions, also taking account of angle.
  55. begin scalar ans, i, xx, yy;
  56. i := 0;
  57. xx := fs!:angle x;
  58. yy := fs!:angle y;
  59. top:
  60. ans := (getv!.unsafe(xx,i)-getv!.unsafe(yy,i));
  61. if not(ans = 0) then return ans>0;
  62. i := i+1;
  63. if (i<8) then go to top;
  64. return
  65. if fs!:fn x = fs!:fn y then nil
  66. else if fs!:fn x = 'sin then nil else t;
  67. end;
  68. endmodule;
  69. end;