SPECFN.TST 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. %
  2. % Testing file for REDUCE Special Functions Package
  3. %
  4. % Chris Cannam, ZIB Berlin
  5. % October 1992 -> Feb 1993
  6. % (only some of the time, of course)
  7. %
  8. % Corrections and comments to neun@sc.zib-berlin.de
  9. %
  10. on savesfs; % just in case it's off for some reason
  11. off bfspace; % to provide more similarity between runs
  12. % with old & new bigfloats
  13. let {sinh (~x) => (exp(x) - exp (-x))/2 };
  14. % this will improve some results
  15. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  16. % 1. Bernoulli numbers
  17. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  18. off rounded;
  19. procedure do!*one!*bern(x);
  20. write ("Bernoulli ", x, " is ", bernoulli x);
  21. do!*one!*bern(1);
  22. do!*one!*bern(2);
  23. do!*one!*bern(3);
  24. do!*one!*bern(13);
  25. do!*one!*bern(14);
  26. do!*one!*bern(300);
  27. do!*one!*bern(-2);
  28. do!*one!*bern(0);
  29. for n := 2 step 2 until 100 do do!*one!*bern n;
  30. on rounded;
  31. precision 100;
  32. do!*one!*bern(1);
  33. do!*one!*bern(2);
  34. do!*one!*bern(3);
  35. do!*one!*bern(13);
  36. do!*one!*bern(14);
  37. do!*one!*bern(300);
  38. do!*one!*bern(-2);
  39. do!*one!*bern(0);
  40. do!*one!*bern(38);
  41. do!*one!*bern(400);
  42. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  43. % 2. Gamma function
  44. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  45. on rounded;
  46. off complex;
  47. precision 40;
  48. algebraic procedure wg(x);
  49. write ("gamma (", x, ") ==> ", gamma x);
  50. algebraic procedure wp(x);
  51. write ("-- precision ", x, ", from ", precision(x));
  52. wg (1/2);
  53. wg (3/2);
  54. write ("sqrt(pi)/2 ==> ", sqrt(pi)/2);
  55. wp(10);
  56. for x := 0 step 5 until 100 do
  57. << wg (1 + x/1000);
  58. wg (-1 - x/13);
  59. wp (8+floor(x/4)) >>;
  60. wg(1/1000000003);
  61. off rounded;
  62. gamma(17/2);
  63. gamma(-17/2);
  64. gamma(4);
  65. gamma(0);
  66. gamma(-4);
  67. gamma(-17/3);
  68. p := gamma(x**2) * gamma(x-y**gamma(y)) - (1/(gamma(4*(x-y))));
  69. y := 1/4;
  70. p;
  71. x := 3;
  72. p;
  73. y := -3/8;
  74. p;
  75. on rounded, complex;
  76. precision 50;
  77. p;
  78. off rounded, complex;
  79. clear y;
  80. p;
  81. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  82. % 3. Beta function. Not very interesting
  83. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  84. algebraic procedure do!*one!*beta(x,y);
  85. write ("Beta (", x, ",", y, ") = ", beta(x,y));
  86. do!*one!*beta(0,1);
  87. do!*one!*beta(2,-3);
  88. do!*one!*beta(3,2);
  89. do!*one!*beta(a+b,(c+d)**(b-a));
  90. do!*one!*beta(-3,4);
  91. do!*one!*beta(-3,2);
  92. do!*one!*beta(-3,-7.5);
  93. do!*one!*beta((pi * 10), exp(5));
  94. on rounded;
  95. precision 30;
  96. do!*one!*beta(0,1);
  97. do!*one!*beta(2,-3);
  98. do!*one!*beta(3,2);
  99. do!*one!*beta(a+b,(c+d)**(b-a));
  100. do!*one!*beta(-3,4);
  101. do!*one!*beta(-3,2);
  102. do!*one!*beta(-3,-7.5);
  103. do!*one!*beta((pi * 10), exp(5));
  104. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  105. % 4. Pochhammer notation
  106. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  107. off rounded;
  108. pochhammer(4,5);
  109. pochhammer(-4,5);
  110. pochhammer(4,-5);
  111. pochhammer(-4,-5);
  112. pochhammer(17/2,12);
  113. pochhammer(-17/2,12);
  114. pochhammer(1/3,14)*pochhammer(2/3,15);
  115. q := pochhammer(1/5,11)*pochhammer(2/5,11)*pochhammer(3/5,11)*
  116. pochhammer(1-1/5,11)*pochhammer(1,11)*pochhammer(6/5,11)*
  117. pochhammer(70/50,11)*pochhammer(8/5,11)*pochhammer(9/5,11);
  118. on complex;
  119. pochhammer(a+b*i,c)*pochhammer(a-b*i,c);
  120. a := 2;
  121. b := 3;
  122. c := 5;
  123. pochhammer(a+b*i,c)*pochhammer(a-b*i,c);
  124. off complex;
  125. on rounded;
  126. pochhammer(1/5,11)*pochhammer(2/5,11)*pochhammer(3/5,11)*
  127. pochhammer(1-1/5,11)*pochhammer(1,11)*pochhammer(6/5,11)*
  128. pochhammer(70/50,11)*pochhammer(8/5,11)*pochhammer(9/5,11);
  129. q;
  130. pochhammer(pi,floor (pi**8));
  131. pochhammer(-pi,floor (pi**7));
  132. pochhammer(1.5,floor (pi**8));
  133. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  134. % 5. Digamma function
  135. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  136. procedure do!*one!*psi(x);
  137. << precision (precision(0) + 4)$
  138. write("Psi of ", x, " is ", psi(x) ) >> ;
  139. clear x, y;
  140. z := x * ((x+y)**2 + (x**y));
  141. off rounded;
  142. do!*one!*psi(3);
  143. do!*one!*psi(pi);
  144. do!*one!*psi(1.005);
  145. do!*one!*psi(1.995);
  146. do!*one!*psi(74);
  147. do!*one!*psi(-1/2);
  148. do!*one!*psi(-3);
  149. do!*one!*psi(z);
  150. on rounded;
  151. precision 100;
  152. do!*one!*psi(3);
  153. do!*one!*psi(pi);
  154. do!*one!*psi(1.005);
  155. do!*one!*psi(1.995);
  156. do!*one!*psi(74);
  157. do!*one!*psi(-1/2);
  158. do!*one!*psi(-3);
  159. do!*one!*psi(z);
  160. precision 15;
  161. x := 8/3;
  162. y := 7/1000;
  163. do!*one!*psi(z);
  164. off rounded;
  165. clear x, y;
  166. df(psi(z), x);
  167. df(df(psi(z), y),x);
  168. int(psi(z), z);
  169. on rounded;
  170. for k := 1 step 0.1 until 2 do do!*one!*psi(k);
  171. off rounded;
  172. % PSI_SIMP.TST F.J.Wright, 2 July 1993
  173. on evallhseqp;
  174. factor psi; on rat, intstr, div; % for neater output
  175. % Do not try using "off mcd"!
  176. psi(x+m) - psi(x+m-1) = 1/(x+m-1);
  177. psi(x+2) - psi(x+1) + 2*psi(x) = 1/(x+1) + 2*psi(x);
  178. psi(x+2) + 3*psi(x) = 4*psi(x) + 1/x + 1/(x+1);
  179. psi(x + 1) = psi(x) + 1/x;
  180. psi(x + 3/2) = psi(x + 1/2) + 1/(x + 1/2);
  181. psi(x - 1/2) = psi(x + 1/2) - 1/(x - 1/2);
  182. psi((x + 3a)/a); psi(x/y + 3);
  183. off rat, intstr, div; on rational;
  184. psi(x+m) - psi(x+m-1) = 1/(x+m-1);
  185. psi(x+2) - psi(x+1) + 2*psi(x) = 1/(x+1) + 2*psi(x);
  186. psi(x+2) + 3*psi(x) = 4*psi(x) + 1/x + 1/(x+1);
  187. psi(x + 1) = psi(x) + 1/x;
  188. psi(x + 3/2) = psi(x + 1/2) + 1/(x + 1/2);
  189. psi(x - 1/2) = psi(x + 1/2) - 1/(x - 1/2);
  190. psi((x + 3a)/a); psi(x/y + 3);
  191. off rational;
  192. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  193. % 6. Polygamma functions
  194. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  195. procedure do!*one!*pg(n,x);
  196. write ("Polygamma (", n, ") of ", x, " is ", polygamma(n,x));
  197. off rounded;
  198. do!*one!*pg(1,1/2);
  199. do!*one!*pg(1,1);
  200. do!*one!*pg(1,3/2);
  201. do!*one!*pg(1,1.005);
  202. do!*one!*pg(1,1.995);
  203. do!*one!*pg(1,1e-10);
  204. do!*one!*pg(2,1.45);
  205. do!*one!*pg(3,1.99);
  206. do!*one!*pg(4,-8.2);
  207. do!*one!*pg(5,0);
  208. do!*one!*pg(6,-5);
  209. do!*one!*pg(7,200);
  210. on rounded;
  211. precision 100;
  212. do!*one!*pg(1,1/2);
  213. do!*one!*pg(1,1);
  214. do!*one!*pg(1,3/2);
  215. do!*one!*pg(1,1.005);
  216. do!*one!*pg(1,1.995);
  217. do!*one!*pg(1,1e-10);
  218. do!*one!*pg(2,1.45);
  219. do!*one!*pg(3,1.99);
  220. do!*one!*pg(4,-8.2);
  221. do!*one!*pg(5,0);
  222. do!*one!*pg(6,-5);
  223. do!*one!*pg(7,200);
  224. off rounded;
  225. clear x;
  226. % Polygamma differentiation has already
  227. % been tried a bit in the psi section
  228. df(int(int(int(polygamma(3,x),x),x),x),x);
  229. clear w, y, z;
  230. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  231. % 7. Zeta function
  232. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  233. procedure do!*one!*zeta(n);
  234. write ("Zeta of ", n, " is ", zeta n);
  235. off rounded;
  236. clear x, y, z;
  237. z := x * ((x+y)**5 + (x**y));
  238. do!*one!*zeta(0);
  239. for k := 4 step 2 until 35 do
  240. do!*one!*zeta(k);
  241. do!*one!*zeta(-17/3);
  242. do!*one!*zeta(190);
  243. do!*one!*zeta(300);
  244. do!*one!*zeta(0);
  245. do!*one!*zeta(-44);
  246. on rounded;
  247. clear x, y;
  248. for k := 3 step 3 until 36 do <<
  249. precision (31+k*3);
  250. do!*one!*zeta(k) >>;
  251. precision 20;
  252. do!*one!*zeta(-17/3);
  253. do!*one!*zeta(z);
  254. y := 3;
  255. x := pi;
  256. do!*one!*zeta(z);
  257. do!*one!*zeta(190);
  258. do!*one!*zeta(300);
  259. do!*one!*zeta(0);
  260. do!*one!*zeta(-44);
  261. off rounded;
  262. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  263. % 8. Kummer functions
  264. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  265. off rounded;
  266. t!*kummer!*a := { 1, 2.4, -1397/10 }$
  267. t!*kummer!*b := { 0, 1, pi, -pi, 26 }$
  268. for each a in t!*kummer!*a do
  269. for each b in t!*kummer!*a do
  270. for each z in t!*kummer!*a do
  271. << write "KummerM(", a, ",", b, ",", z, ") = ",
  272. kummerm(a,b,z);
  273. write "KummerU(", a, ",", b, ",", z, ") = ",
  274. kummeru(a,b,z) >>;
  275. on rounded;
  276. precision 30;
  277. t!*k!*c := 7;
  278. % To test each and every possible combination of
  279. % three arguments from t!*kummer!*b would take too
  280. % long, but we want the possibility of trying most
  281. % special cases. Compromise: test every seventh
  282. % possibility.
  283. for each a in t!*kummer!*b do
  284. for each b in t!*kummer!*b do
  285. for each z in t!*kummer!*b do
  286. << if t!*k!*c = 7
  287. then << write "KummerM(", a, ",", b, ",", z, ") = ",
  288. kummerm(a,b,z);
  289. write "KummerU(", a, ",", b, ",", z, ") = ",
  290. kummeru(a,b,z);
  291. t!*k!*c := 0 >>;
  292. t!*k!*c := t!*k!*c + 1 >>;
  293. off rounded;
  294. clear x, y, z, t!*k!*c;
  295. df(df(kummerM(a,b,z),z),z);
  296. df(kummerU(a,b,z),z);
  297. z := ((x^2 + y)^5) + (x^(x+y));
  298. df(df(kummerM(a,b,z),y),x);
  299. df(kummerU(a,b,z),x);
  300. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  301. % 9. Bessel functions
  302. % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  303. % Lengthy test of the Bessel functions. This isn't even
  304. % remotely exhaustive of the special cases -- though a
  305. % real person with lots of time could no doubt come up
  306. % with a better lot of tests than this automated rubbish.
  307. % Again, compromise by only actually doing one in five or
  308. % nine. If you want a really thorough test, you can
  309. % easily change this to get it; but it'll take hours to
  310. % run.
  311. clear p, q;
  312. hankel1(p,q);
  313. r := df(ws,q);
  314. on complex;
  315. r;
  316. p:=3/8;
  317. r;
  318. q := pi;
  319. r;
  320. on rounded;
  321. r;
  322. off complex, rounded;
  323. df(df(besselj(pp,qq)+rr * hankel1(pp*2,qq) *
  324. bessely(pp-qq,qq),qq),qq);
  325. % Possible values for real args
  326. t!*bes!*vr := { 1, pi, -pi, 26 }$
  327. % Possible values for real and imaginary parts of complex args
  328. t!*bes!*vc := { 0, 3, -41/2 }$
  329. array s!*bes(4)$
  330. s!*bes(1) := "BesselJ"$
  331. s!*bes(2) := "BesselY"$
  332. s!*bes(3) := "BesselI"$
  333. s!*bes(4) := "BesselK"$
  334. pre := 16;
  335. precision pre;
  336. preord := 10**pre;
  337. t!*b!*c := 3;
  338. algebraic procedure do!*one!*bessel(s,n,z);
  339. (if s = 1 then besselj(n,z)
  340. else if s = 2 then bessely(n,z)
  341. else if s = 3 then besseli(n,z)
  342. else besselk(n,z));
  343. algebraic procedure pr!*bessel(s,n,z,k);
  344. << if t!*b!*c = k
  345. then
  346. << on rounded;
  347. bes1 := do!*one!*bessel(s,n,z);
  348. precision(pre+5);
  349. bes2 := do!*one!*bessel(s,n,z);
  350. if bes1 neq 0
  351. then disc := floor abs(100*(bes2-bes1)*preord/bes1)
  352. else disc := 0;
  353. precision pre;
  354. write s!*bes(s), "(", n, ",", z, ") = ", bes1;
  355. if not numberp disc then
  356. << precom := !*complex;
  357. on complex;
  358. disc := disc;
  359. if not precom then off complex >>;
  360. if disc neq 0
  361. then write " (discrepancy ", disc, "% of one s.f.)";
  362. if numberp disc and disc > 200 then
  363. << write "***** WARNING Significant Inaccuracy.";
  364. write " Lower precision result:";
  365. write " ", bes1;
  366. write " Higher precision result:";
  367. precision(pre+5); write " ", bes2; precision pre >>;
  368. off rounded;
  369. t!*b!*c := 0 >>;
  370. t!*b!*c := t!*b!*c + 1 >>;
  371. % About to begin Bessel test. We have a list of possible
  372. % values, and we test every Bessel, with every value on the
  373. % list as both order and argument. Every Bessel is computed
  374. % twice, to different precisions (differing by 3), and any
  375. % discrepancy is reported. The value reported is the diff-
  376. % erence between the two computed values, expressed as a
  377. % percentage of the unit of the least significant displayed
  378. % digit. A discrepancy between 100% and 200% means that the
  379. % last digit of the displayed value was found to differ at
  380. % higher precision; values greater than 200% are cause for
  381. % concern. An ideal discrepancy would be between about 1%
  382. % and 20%; if the value is found to be zero, no discrepancy
  383. % is reported.
  384. off msg;
  385. for s := 1:4 do
  386. << write(" ... Testing ", s!*bes(s), " for real domains ... ");
  387. for each n in t!*bes!*vr do
  388. for each z in t!*bes!*vr do
  389. pr!*bessel(s, n, z, 5) >>;
  390. on complex;
  391. for s := 1:3 do
  392. << write (" ... Testing ", s!*bes(s), " for complex domains ... ");
  393. for each nr in t!*bes!*vc do
  394. for each ni in t!*bes!*vc do
  395. for each zr in t!*bes!*vc do
  396. for each zi in t!*bes!*vc do
  397. pr!*bessel(s, nr+ni*i, zr+zi*i, 9) >>;
  398. off complex;
  399. on msg;
  400. write (" ...");
  401. write ("Bessel test complete.");
  402. end;