defintd.red 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. module defintd;
  2. fluid '(mellincoef mellin!-coefficients!* mellin!-transforms!*);
  3. % The following are needed by GAMMA.
  4. load_package specfn,sfgamma;
  5. symbolic procedure simpintgggg (u);
  6. begin scalar ff1,ff2,alpha,var,chosen_num,coef,temp,const,result;
  7. u := defint_reform(u);
  8. const := car u;
  9. if const = 0 then result := nil . 1
  10. else
  11. << u := cdr u;
  12. if length u neq 4 then rederr "Integration failed";
  13. if (car u) = 0 then ff1 := '(0 0 x)
  14. else ff1 := prepsq simp car u;
  15. if (cadr u) = 0 then ff2 := '(0 0 x)
  16. else ff2 := prepsq simp cadr u;
  17. if (ff1 = 'UNKNOWN) then return simp 'unknown;
  18. if (ff2 = 'UNKNOWN) then return simp 'unknown;
  19. alpha := caddr u;
  20. var := cadddr u;
  21. if car ff1 = 'f31 or car ff1 = 'f32 then
  22. << put('f1,'g,spec_log(ff1)); MELLINCOEF :=1>>
  23. else
  24. << chosen_num := cadr ff1;
  25. put('f1,'g,getv(mellin!-transforms!*,chosen_num));
  26. coef := getv(mellin!-coefficients!*,chosen_num);
  27. if coef then MELLINCOEF:= coef else MELLINCOEF :=1>>;
  28. if car ff2 = 'f31 or car ff2 = 'f32 then
  29. put('f2,'g,spec_log(ff2))
  30. else
  31. << chosen_num := cadr ff2;
  32. put('f2,'g,getv(mellin!-transforms!*,chosen_num));
  33. coef := getv(mellin!-coefficients!*,chosen_num);
  34. if coef then MELLINCOEF:= coef * MELLINCOEF >>;
  35. temp := simp list('intgg,'f1 . cddr ff1,
  36. 'f2 . cddr ff2,alpha,var);
  37. temp := prepsq temp;
  38. if temp neq 'unknown then
  39. result := reval algebraic(const*temp)
  40. else result := temp;
  41. result := simp!* result; >>;
  42. return result;
  43. end;
  44. symbolic procedure spec_log(ls);
  45. begin scalar n,num,denom,mellin;
  46. n := cadr ls;
  47. num := for i:= 0 :n collect 1;
  48. denom := for i:= 0 :n collect 0;
  49. if car ls = 'f31 then
  50. mellin := {{}, {n+1,0,n+1,n+1},num,denom, (-1)^n*factorial(n),'x}
  51. else mellin := {{}, {0,n+1,n+1,n+1},num,denom, factorial(n),'x};
  52. return mellin;
  53. end;
  54. % some rules which let the results look more convenient ...
  55. algebraic <<
  56. for all z let sinh(z) = (exp (z) - exp(-z))/2;
  57. for all z let cosh(z) = (exp (z) + exp(-z))/2;
  58. operator laplace2,Y_transform2,K_transform2,struveh_transform2,
  59. fourier_sin2,fourier_cos2;
  60. gamma_rules :=
  61. { gamma(~n/2+1/2) => gamma(n)/(2^(n-1)*gamma(n/2))*gamma(1/2),
  62. gamma(~n/2+1) => n/2*gamma(1/2*n),
  63. gamma(3/4)*gamma(1/4) => pi*sqrt(2),
  64. gamma(~n)*~n/gamma(~n+1) => 1
  65. };
  66. let gamma_rules;
  67. factorial_rules := {factorial(~a) => gamma(a+1) };
  68. let factorial_rules;
  69. >>;
  70. % A function to calculate laplace transforms of given functions via
  71. % integration of Meijer G-functions.
  72. put('laplace_transform,'psopfn,'new_laplace);
  73. symbolic procedure new_laplace(lst);
  74. begin scalar new_lst;
  75. lst := product_test(lst);
  76. new_lst := {'laplace2,lst};
  77. return defint_trans(new_lst);
  78. end;
  79. % A function to calculate hankel transforms of given functions via
  80. % integration of Meijer G-functions.
  81. put('hankel_transform,'psopfn,'new_hankel);
  82. symbolic procedure new_hankel(lst);
  83. begin scalar new_lst;
  84. lst := product_test(lst);
  85. new_lst := {'hankel2,lst};
  86. return defint_trans(new_lst);
  87. end;
  88. % A function to calculate Y transforms of given functions via
  89. % integration of Meijer G-functions.
  90. put('Y_transform,'psopfn,'new_Y_transform);
  91. symbolic procedure new_Y_transform(lst);
  92. begin scalar new_lst;
  93. lst := product_test(lst);
  94. new_lst := {'Y_transform2,lst};
  95. return defint_trans(new_lst);
  96. end;
  97. % A function to calculate K-transforms of given functions via
  98. % integration of Meijer G-functions.
  99. put('K_transform,'psopfn,'new_K_transform);
  100. symbolic procedure new_K_transform(lst);
  101. begin scalar new_lst;
  102. lst := product_test(lst);
  103. new_lst := {'K_transform2,lst};
  104. return defint_trans(new_lst);
  105. end;
  106. % A function to calculate struveh transforms of given functions via
  107. % integration of Meijer G-functions.
  108. put('struveh_transform,'psopfn,'new_struveh);
  109. symbolic procedure new_struveh(lst);
  110. begin scalar new_lst,temp;
  111. lst := product_test(lst);
  112. new_lst := {'struveh2,lst};
  113. temp:=defint_trans(new_lst);
  114. return defint_trans(new_lst);
  115. end;
  116. % A function to calculate fourier sin transforms of given functions via
  117. % integration of Meijer G-functions.
  118. put('fourier_sin,'psopfn,'new_fourier_sin);
  119. symbolic procedure new_fourier_sin(lst);
  120. begin scalar new_lst;
  121. lst := product_test(lst);
  122. new_lst := {'fourier_sin2,lst};
  123. return defint_trans(new_lst);
  124. end;
  125. % A function to calculate fourier cos transforms of given functions via
  126. % integration of Meijer G-functions.
  127. put('fourier_cos,'psopfn,'new_fourier_cos);
  128. symbolic procedure new_fourier_cos(lst);
  129. begin scalar new_lst;
  130. lst := product_test(lst);
  131. new_lst := {'fourier_cos2,lst};
  132. return defint_trans(new_lst);
  133. end;
  134. % A function to test whether the input is in a product form and if so
  135. % to rearrange it into a list form.
  136. % e.g. defint(x*cos(x)*sin(x),x) => defint(x,cos(x),sin(x),x);
  137. symbolic procedure product_test(lst);
  138. begin scalar temp;
  139. product_tst := nil;
  140. if listp car lst then
  141. << temp := caar lst;
  142. if temp = 'times and length cdar lst <= 3 then
  143. << lst := append(cdar lst,cdr lst); product_tst := t>>;
  144. >>;
  145. return lst;
  146. end;
  147. % A function to call the relevant transform's rule-set
  148. symbolic procedure defint_trans(lst);
  149. begin scalar type,temp_lst,new_lst,var,n1,n2,result;
  150. % Set a test to indicate that the relevant conditions for validity
  151. % should not be tested
  152. algebraic(transform_tst := t);
  153. spec_cond := '();
  154. type := car lst; % obtain the transform type
  155. temp_lst := cadr lst;
  156. var := nth(temp_lst,length temp_lst);
  157. new_lst := hyperbolic_test(temp_lst);
  158. if length temp_lst = 3 then
  159. << n1 := car new_lst;
  160. n2 := cadr new_lst;
  161. result := reval list(type,n1,n2,var)>>
  162. % Call the relevant rule-set
  163. else if length temp_lst = 2 then
  164. << n1 := car new_lst;
  165. result := reval list(type,n1,var)>> % Call the relevant rule-set
  166. else if length temp_lst = 4 and product_tst = 't then
  167. << n1 := {'times,car new_lst,cadr new_lst};
  168. n2 := caddr new_lst;
  169. result := reval list(type,n1,n2,var)>>
  170. else << algebraic(transform_tst := nil);
  171. rederr "Wrong number of arguments">>;
  172. return result;
  173. end;
  174. % A function to test for hyperbolic functions and rename them
  175. % in order to avoid their transformation into combinations of
  176. % the exponenetial function
  177. %symbolic procedure hyperbolic_test(lst);
  178. % begin scalar temp,new_lst,lth;
  179. % lth := length lst;
  180. % for i:=1 :lth do
  181. % << temp := car lst;
  182. % if listp temp and (car temp = 'difference or car temp = 'plus) then
  183. % temp := hyperbolic_test(temp)
  184. % else if listp temp and car temp = 'sinh then car temp := 'mysinh
  185. % else if listp temp and car temp = 'cosh then car temp := 'mycosh;
  186. % new_lst := append(new_lst,{temp});
  187. % lst := cdr lst>>;
  188. %return new_lst;
  189. %end;
  190. symbolic procedure hyperbolic_test lst;
  191. for each u in lst collect
  192. if atom u then u
  193. else if car u memq '(difference plus) then hyperbolic_test u
  194. else if car u eq 'sinh then 'mysinh . cdr u
  195. else if car u eq 'cosh then 'mycosh . cdr u
  196. else u;
  197. endmodule;
  198. end;