chebysh.red 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. module chebysh; % Chebyshev approximation.
  2. % Literature: Press, Flannery, Teukolski, Vetterling: Numerical
  3. % Recipes, Cambridge University Press.
  4. % Author: Herbert Melenk
  5. % Copyright (c) 1993 ZIB Berlin, RAND. All rights reserved.
  6. put('chebyshev_fit,'psopfn,'(lambda(u)(chebysheveval u 'fit)));
  7. put('chebyshev_eval,'psopfn,'(lambda(u)(chebysheveval u 'eval)));
  8. put('chebyshev_int,'psopfn,'(lambda(u)(chebysheveval u 'int)));
  9. put('chebyshev_df,'psopfn,'(lambda(u)(chebysheveval u 'df)));
  10. symbolic procedure chebysheveval(u,mode);
  11. % interface function;
  12. begin scalar w,x,c,e,y,r,oldmode;
  13. integer n;
  14. u := for each x in u collect reval x;
  15. u := accuracycontrol(u,3,20);
  16. e :=car u; u :=cdr u;
  17. % variable and interval.
  18. w := car u;
  19. if not eqcar(w,'equal) then typerr(w,"interval bounds");
  20. oldmode:=switch!-mode!-rd nil;
  21. y:=revalnuminterval(caddr w,t);
  22. x:=cadr w;
  23. if mode = 'fit then
  24. <<
  25. n:=if cdr u then ieval cadr u else 20;
  26. c := chebcoeffs(e,x,car y,cadr y,n);
  27. r:= {'list,
  28. chebpol(c,x,car y,cadr y),
  29. 'list . c}; % for each q in c collect prepf q};
  30. >>
  31. else if mode = 'eval then
  32. <<
  33. if null cdr u or not eqcar(cadr u,'equal) then
  34. rederr("Chebyshev_eval: point missing");
  35. e:=cdr listeval(e,t);
  36. w:=numr simp caddr cadr u;
  37. r:= prepf chebeval(e,x,car y,cadr y,w);
  38. >>
  39. else if mode = 'int or mode = 'df then
  40. <<
  41. e:=cdr listeval(e,t);
  42. r:= if mode ='int then
  43. chebint(e,x,car y,cadr y)
  44. else chebdf (e,x,car y,cadr y);
  45. r:='list . for each q in r collect prepf q;
  46. >>;
  47. switch!-mode!-rd oldmode;
  48. return r;
  49. end;
  50. symbolic procedure chebcoeffs(func,x,a,b,n);
  51. begin
  52. integer k,j,n1;
  53. scalar fac,bpa,bma,f,!1pi,c,y,su,nn,half,w;
  54. x:={x};
  55. !1PI := rdpi!*();
  56. nn := dm!:(1/n);
  57. n1 := n-1;
  58. half := dm!:(1/2);
  59. dm!: <<bma:=(b-a)/2; bpa:=(b+a)/2>>;
  60. w := dm!:(!1PI*nn);
  61. f:=for k:=0:n1 collect
  62. <<y := dm!: (rdcos!*(w*(k+half))*bma+bpa);
  63. evaluate(func,x,{y})
  64. >>;
  65. dm!: <<fac:=2*nn>>;
  66. c:=for j:=0:n1 collect
  67. <<
  68. w:= dm!:(!1PI*j*nn);
  69. su:=nil;
  70. for k:=0:n1 do
  71. dm!:(su := su+nth(f,iadd1 k) *rdcos!*(w*(k+half)));
  72. dm!: (fac*su)
  73. >>;
  74. return c;
  75. end;
  76. symbolic procedure chebpol(c,x,a,b);
  77. begin scalar d,dd,sv,fac,cnst;
  78. integer n;
  79. n:=length c;
  80. d:=for i:=1:n collect nil;
  81. dd:=for i:=1:n collect nil;
  82. car dd := nth(c,n);
  83. for j:=(n-2) step -1 until 1 do
  84. <<
  85. for k:=(n-j) step -1 until 1 do
  86. << sv := nth(d,k+1);
  87. nth(d,k+1) := dm!:(2*nth(d,k) - nth(dd,add1 k));
  88. nth(dd,k+1) := sv
  89. >>;
  90. sv:=car d;
  91. car d := dm!:(- car dd + nth(c,add1 j));
  92. car dd := sv;
  93. >>;
  94. for j:=(n-1) step -1 until 1 do
  95. nth(d,j+1) := dm!:(nth(d,j) - nth(dd,add1 j));
  96. car d := dm!:(-car dd + car c/2);
  97. cnst:=dm!:(2/(b-a));
  98. fac :=cnst;
  99. for j:=1:(n-1) do
  100. <<nth(d,add1 j) := dm!:(nth(d,add1 j) * fac);
  101. fac := dm!:(fac*cnst);
  102. >>;
  103. cnst:=dm!:((a+b)/2);
  104. for j:=0:(n-2) do
  105. for k:=(n-2) step -1 until j do
  106. nth(d,add1 k) := dm!:(nth(d,add1 k) - cnst*nth(d,add1 add1 k));
  107. return reval ('plus. for i:=1:n collect
  108. {'times,nth(d,i),{'expt,x,i-1}});
  109. end;
  110. symbolic procedure chebeval(c,xx,a,b,x);
  111. begin scalar d,dd,y,y2,sv;
  112. integer m;
  113. xx := nil;
  114. c:=for each q in c collect numr simp q;
  115. m:=length c;
  116. y2 := dm!:(2*(y:=(2*x-a-b)/(b-a)));
  117. for j:=(m-1) step -1 until 1 do
  118. << sv:=d;
  119. d:= dm!:(y2*d-dd+nth(c,add1 j));
  120. dd := sv;
  121. >>;
  122. return dm!:(y*d-dd + car c/2);
  123. end;
  124. symbolic procedure chebint(c,xx,a,b);
  125. begin scalar su,fac,con,cint,w;
  126. integer n,jj;
  127. xx := nil;
  128. n := length c;
  129. c:=for each q in c collect numr simp q;
  130. fac := 1;
  131. con := dm!:((b-a)/4);
  132. cint := for j:=1:(n-2) collect
  133. << jj:=j+2;
  134. dm!:(w:= con*(nth(c,j)-nth(c,jj))/j );
  135. dm!:(su := su + fac*w);
  136. dm!:(fac := -fac);
  137. w
  138. >>;
  139. cint := append(cint,{dm!: (con*nth(c,sub1 n)/(n-1))});
  140. dm!:( su := su+fac*nth(c,n));
  141. cint := (dm!:(su+su)) . cint;
  142. return cint;
  143. end;
  144. symbolic procedure chebdf(c,xx,a,b);
  145. begin scalar con,cder;
  146. integer n,jj;
  147. xx := nil;
  148. n := length c;
  149. c:=for each q in c collect numr simp q;
  150. cder := for i:=1:n collect nil;
  151. nth(cder,n-1) := dm!:(2*(n-1)*nth(c,n));
  152. for j:=(n-3) step -1 until 0 do
  153. <<jj:=j+3;
  154. nth(cder,j+1):=
  155. dm!:(nth(cder,jj)+2*(j+1)*nth(c,add1 add1 j));
  156. >>;
  157. con := dm!:(2/(b-a));
  158. return for each q in cder collect dm!:(con * q);
  159. end;
  160. endmodule;
  161. end;