fptest.red 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. % Floating point tests. A C Norman and Codemist Ltd. 1994
  2. %
  3. % The code here is for use by people who have read and
  4. % enjoyed "Software manual for the elementary functions" by
  5. % Cody and Waite (Prentice Hall, 1980). It attempts to
  6. % measure the accuracy of some of the elementary functions
  7. % in the implementation of REDUCE that it is run on. Good
  8. % implementations should show maximum errors of only a few
  9. % units in the last place, and errors reasonably evenly
  10. % distributed between +ve and -ve. Various special cases are
  11. % tested too. The layout for presenting results from this code
  12. % is somewhat crude at present.
  13. %
  14. % call fptest() to perform complete set of tests;
  15. symbolic;
  16. on comp;
  17. fluid '(ibeta it irnd ngrd machep negep iexp minexp
  18. maxexp eps epsneg xmin xmax iy one zero x);
  19. symbolic procedure fptest();
  20. begin
  21. scalar ibeta,it,irnd,ngrd,machep,negep,iexp,minexp,
  22. maxexp,eps,epsneg,xmin,xmax;
  23. iy:=100001; % seed for random number gereration;
  24. machar();
  25. % only expt is left after this lot. hurrah;
  26. test!-arcsin();
  27. test!-atan();
  28. test!-tan();
  29. test!-sin();
  30. test!-sqrt();
  31. test!-log();
  32. test!-exp();
  33. princ "fp tests over";
  34. terpri()
  35. end;
  36. symbolic procedure machar();
  37. begin
  38. scalar one,zero,a,b,beta,betam1,betain,i,k,x,y,z,mx;
  39. one:=float 1;
  40. zero:=float 0;
  41. a:=one;
  42. repeat a:=a+a until not (((a+one)-a)-one = zero);
  43. b:=one;
  44. repeat b:=b+b until not ((a+b)-a = zero);
  45. ibeta:=fix((a+b)-a);
  46. princ list("ibeta = ",ibeta); terpri();
  47. beta:=float ibeta;
  48. it:=0;
  49. b:=one;
  50. repeat << it:=it+1; b:=b*beta >> until not (((b+one)-b)-one = zero);
  51. irnd:=0;
  52. betam1:=beta-one;
  53. if ((a+betam1)-a) neq zero then irnd:=1;
  54. princ list("it=",it,"irnd=",irnd); terpri();
  55. negep:=it+3;
  56. betain:=one/beta;
  57. a:=one;
  58. for i:=1:negep do a:=a*betain;
  59. b:=a;
  60. while ((one-a)-one) = zero do << a:=a*beta; negep:=negep-1 >>;
  61. negep:=-negep;
  62. epsneg:=a;
  63. if not ((ibeta=2) or (irnd=0)) then <<
  64. a := (a*(one+a))/(one+one);
  65. if ((one-a)-one) neq zero then epsneg:=a >>;
  66. princ list("negep=",negep,"epsneg=",epsneg); terpri();
  67. machep:=-it-3;
  68. a:=b;
  69. while ((one+a)-one) = zero do <<
  70. a:=a*beta;
  71. machep:=machep+1 >>;
  72. eps:=a;
  73. if not (ibeta=2 or irnd=0) then <<
  74. a:=(a*(one+a))/(one+one);
  75. if (one+a)-one neq zero then eps:=a >>;
  76. princ list("machep=",machep,"eps=",eps); terpri();
  77. ngrd:=0;
  78. if irnd=0 and ((one+eps)*one-one) neq zero then ngrd:=1;
  79. princ list("ngrd=",ngrd); terpri();
  80. i:=0;
  81. k:=1;
  82. z:=betain;
  83. l400: y:=z;
  84. z:=y*y;
  85. a:=z*one;
  86. if (a+a=zero) or (abs z >= y) then go to l410;
  87. i:=i+1;
  88. k:=k+k;
  89. goto l400;
  90. l410: % assume it is not a decimal machine! ;
  91. iexp:=i+1;
  92. mx:=k+k;
  93. l450: xmin:=y;
  94. y:=y*betain;
  95. a:=y*one;
  96. if (a+a=zero) or (abs y >= xmin) or
  97. ((a * (one + eps)) = a) then goto l460;
  98. k:=k+1;
  99. goto l450;
  100. l460: minexp:=-k;
  101. princ list("iexp=",iexp,"minexp=",minexp,"xmin=",xmin); terpri();
  102. if not (mx>k+k-3 or ibeta=10) then <<
  103. mx:=mx+mx;
  104. iexp:=iexp+1 >>;
  105. maxexp:=mx+minexp;
  106. maxexp:=maxexp-2; % allow for 2 reserved exponents in ieee format;
  107. i:=maxexp+minexp;
  108. if (ibeta=2) and (i=0) then maxexp:=maxexp-1;
  109. if i>20 then maxexp:=maxexp-1;
  110. if a neq y then maxexp:=maxexp-2;
  111. princ list("maxexp=",maxexp); terpri();
  112. xmax:=one-epsneg;
  113. if xmax*one neq xmax then xmax:=one-beta*epsneg;
  114. xmax:=xmax/(beta*beta*beta*xmin);
  115. i:=maxexp+minexp+3;
  116. if i>0 then <<
  117. for j:=1:i do
  118. if ibeta=2 then xmax:=xmax+xmax else xmax:=xmax*beta >>;
  119. princ list("xmax=",xmax); terpri();
  120. princ "end of machar"; terpri()
  121. end;
  122. symbolic procedure rnd();
  123. % random floating point number in range 0 to 1;
  124. begin
  125. iy:=iy*125;
  126. iy:=remainder(iy,2796203);
  127. return float(iy)/2796203.0
  128. end;
  129. symbolic procedure randl(x);
  130. exp(x*rnd());
  131. symbolic procedure tab_to_column n;
  132. while posn() < n do princ " ";
  133. symbolic procedure heading(name,trials,from,to);
  134. << terpri();
  135. princ name;
  136. tab_to_column 20; princ trials; princ " trials";
  137. tab_to_column 40; princ "from "; princ from;
  138. princ " to "; princ to; terpri()
  139. >>;
  140. symbolic procedure errsigns(k1,k2,k3);
  141. << princ "+ve: "; princ k1;
  142. tab_to_column 20; princ "zero: "; princ k2;
  143. tab_to_column 40; princ "-ve: "; princ k3; terpri()
  144. >>;
  145. symbolic procedure maxrel(w,x1,d);
  146. << princ "mre was "; princ w;
  147. princ " at "; princ x1;
  148. princ " lost "; princ d; princ " digits"; terpri();
  149. >>;
  150. symbolic procedure rmserr(w,d);
  151. << princ "rms was "; princ w;
  152. princ " lost "; princ d; princ " digits"; terpri()
  153. >>;
  154. symbolic procedure specials(a,b,c);
  155. << princ a;
  156. princ b;
  157. princ " ";
  158. princ c; terpri()
  159. >>;
  160. symbolic procedure errortest u;
  161. begin
  162. scalar w;
  163. w := errorset(u, t, t);
  164. if atom w then <<
  165. princ "Evaluation of "; prin1 u; princ " failed"; terpri() >>
  166. else <<
  167. prin1 u; princ " = "; print car w >>;
  168. end;
  169. symbolic procedure test!-arcsin();
  170. begin
  171. scalar a,ait,albeta,b,beta,betap,c1,c2,del,half,pi,r6,r7,one,xsq,two,l,
  172. k,em,ob32,w,x,xl,xn,x1,y,z,zero,zz,i,i1,j,k1,k2,k3,n,expon,zsum,
  173. ysq,xm,s;
  174. beta:=float ibeta;
  175. albeta:=log beta;
  176. ait:=float it;
  177. zero:=float 0;
  178. one:=float 1;
  179. half:=0.5;
  180. two:=float 2;
  181. k:=fix(log10(beta**it))+1;
  182. c1:=201.0/128.0;
  183. c2:=4.8382679489661923132e-4;
  184. a:=-0.125;
  185. b:=-a;
  186. n:=2000;
  187. xn:=float n;
  188. i1:=0;
  189. l:=-1;
  190. for j:=1:5 do <<
  191. princ list("start of test ",j," of arcsin/arccos"); terpri();
  192. k1:=0;
  193. k3:=0;
  194. l:=-l;
  195. x1:=zero;
  196. r6:=zero;
  197. r7:=zero;
  198. del:=(b-a)/xn;
  199. xl:=a;
  200. for i:=1:n do <<
  201. x:=del*rnd()+xl;
  202. if j>2 then <<
  203. ysq := half - half*abs x;
  204. x:=(half-(ysq+ysq)) + half;
  205. if j=5 then x:=-x;
  206. y:=sqrt(ysq);
  207. y:=y+y >>
  208. else << y:=x; ysq:=y*y >>;
  209. zsum:=zero;
  210. xm:=float(k+k+1);
  211. if l>0 then z:=asin x else z:=acos x;
  212. for m:=1:k do <<
  213. zsum:=ysq*(zsum+1.0/xm);
  214. xm:=xm-2.0;
  215. zsum:=zsum*(xm/(xm+1.0)) >>;
  216. zsum:=zsum*y;
  217. if j=1 or j=4 then <<
  218. zz:=y+zsum;
  219. zsum:=(y-zz)+zsum;
  220. if irnd neq 1 then zz:=zz + (zsum+zsum) >>
  221. else <<
  222. s:=c1+c2;
  223. zsum:=((c1-s) + c2) - zsum;
  224. zz:=s+zsum;
  225. zsum:=((s-zz)+zsum)-y;
  226. s:=zz;
  227. zz:=s+zsum;
  228. zsum:=(s-zz)+zsum;
  229. if irnd neq 1 then zz:=zz+(zsum+zsum)>>;
  230. w:=1.0;
  231. if z neq zero then w:=(z-zz)/z;
  232. if w>zero then k1:=k1+1;
  233. if w<zero then k3:=k3+1;
  234. w:=abs w;
  235. if w>r6 then << r6:=w; x1:=x >>;
  236. r7:=r7+w*w;
  237. xl:=xl+del >>;
  238. k2:=n-k1-k3;
  239. r7:=sqrt(r7/xn);
  240. heading("arcsin/arccos",n,a,b);
  241. errsigns(k1,k2,k3);
  242. w:=-999.0;
  243. if r6 neq zero then w:=log abs r6/albeta;
  244. maxrel(w,x1,max(ait+w,zero));
  245. w:=-999.0;
  246. if r7 neq zero then w:=log abs r7/albeta;
  247. rmserr(w,max(ait+w,zero));
  248. if j=2 then << a:=0.75; b:=1.0 >>
  249. else if j=4 then << b:=-a; a:=-1.0; c1:=c1+c1; c2:=c2+c2; l:=-l >> >>;
  250. for i:=1:5 do <<
  251. x:=rnd()*a;
  252. z:=asin x + asin(-x);
  253. specials("asin(x)+asin(-x) ",x,z) >>;
  254. betap:=beta**it;
  255. x:=rnd()/betap;
  256. for i:=1:5 do <<
  257. z:=x-asin x;
  258. specials("small args to asin ",x,z);
  259. x := x/beta >>;
  260. expon:=float minexp * 0.75;
  261. x:=beta**expon;
  262. y:=asin x;
  263. specials("tiny arg ",x,y);
  264. x:=1.2;
  265. errortest list('asin, x);
  266. princ "end of test on arcsin/arccos"; terpri()
  267. end;
  268. symbolic procedure test!-atan();
  269. begin
  270. scalar a,ait,albeta,b,beta,betap,c1,c2,del,half,pi,r6,r7,one,xsq,two,
  271. em,ob32,w,x,xl,xn,x1,y,z,zero,zz,i,i1,j,k1,k2,k3,n,expon,zsum;
  272. beta:=float ibeta;
  273. albeta:=log beta;
  274. ait:=float it;
  275. zero:=float 0;
  276. one:=float 1;
  277. half:=0.5;
  278. two:=float 2;
  279. a:=-0.0625;
  280. b:=-a;
  281. ob32:=b*half;
  282. n:=2000;
  283. xn:=float n;
  284. i1:=0;
  285. for j:=1:4 do <<
  286. princ list("start of test ",j," of atan"); terpri();
  287. k1:=0;
  288. k3:=0;
  289. x1:=zero;
  290. r6:=zero;
  291. r7:=zero;
  292. del:=(b-a)/xn;
  293. xl:=a;
  294. for i:=1:n do <<
  295. x:=del*rnd()+xl;
  296. if j=2 then x:=((one+x*a)-one)*16.0;
  297. z:=atan x;
  298. if j=1 then <<
  299. xsq:=x*x;
  300. em:=17.0;
  301. zsum:=xsq/em;
  302. for i1:=1:7 do <<
  303. em := em-two;
  304. zsum:=(one/em - zsum)*xsq >>;
  305. zsum:=-x*zsum;
  306. zz:=x+zsum;
  307. zsum:=(x-zz)+zsum;
  308. if irnd=0 then zz:=zz+(zsum+zsum) >>
  309. else if j=2 then <<
  310. y:=x-0.0625;
  311. y:=y/(one+x*a);
  312. zz:=(atan y - 8.1190004042651526021/100000.0)+ob32;
  313. zz:=zz+ob32 >>
  314. else <<
  315. z:=z+z;
  316. y:=x/((half+x*half)*((half-x)+half));
  317. zz := atan y >>;
  318. w:=1.0;
  319. if z neq zero then w:=(z-zz)/z;
  320. if w>zero then k1:=k1+1;
  321. if w<zero then k3:=k3+1;
  322. w:=abs w;
  323. if w>r6 then << r6:=w; x1:=x >>;
  324. r7:=r7+w*w;
  325. xl:=xl+del >>;
  326. k2:=n-k1-k3;
  327. r7:=sqrt(r7/xn);
  328. heading("atan",n,a,b);
  329. errsigns(k1,k2,k3);
  330. w:=-999.0;
  331. if r6 neq zero then w:=log abs r6/albeta;
  332. maxrel(w,x1,max(ait+w,zero));
  333. w:=-999.0;
  334. if r7 neq zero then w:=log abs r7/albeta;
  335. rmserr(w,max(ait+w,zero));
  336. a:=b;
  337. if j=1 then b:=two-sqrt(3.0);
  338. if j=2 then b:=sqrt(two)-one;
  339. if j=3 then b:=one >>;
  340. a:=5.0;
  341. for i:=1:5 do <<
  342. x:=rnd()*a;
  343. z:=atan x + atan(-x);
  344. specials("atan(x)+atan(-x) ",x,z) >>;
  345. betap:=beta**it;
  346. x:=rnd()/betap;
  347. for i:=1:5 do <<
  348. z:=x-atan x;
  349. specials("small args to atan ",x,z);
  350. x := x/beta >>;
  351. a:=-two;
  352. b:=4.0;
  353. for i:=1:5 do <<
  354. x:=rnd()*b+a;
  355. y:=rnd();
  356. w:=-y;
  357. z:=atan(x/y) - atan2(x,y);
  358. zz:=atan(x/w) - atan2(x,w);
  359. princ list("atan vs atan2 ",x,y,w," ",z,zz); terpri() >>;
  360. expon:=float minexp * 0.75;
  361. x:=beta**expon;
  362. y:=atan x;
  363. specials("tiny arg ",x,y);
  364. specials("xmax ",xmax,atan xmax);
  365. specials("atan(xmax,xmin) ",xmax,atan2(xmax,xmin));
  366. princ "end of test on atan"; terpri();
  367. end;
  368. symbolic procedure test!-sqrt();
  369. begin
  370. scalar beta,sqbeta,albeta,ait,one,zero,n,xn,c,k1,k2,k3,
  371. x1,r6,r7,a,b,x,y,z,w,w1;
  372. princ "start of tests on sqrt"; terpri();
  373. beta:=float(ibeta);
  374. sqbeta:=sqrt(beta);
  375. albeta:=log(beta);
  376. ait:=float(it);
  377. one:=float(1);
  378. zero:=float(0);
  379. a:=one/sqbeta;
  380. b:=one;
  381. n:=2000;
  382. xn:=float(n);
  383. for j:=1:2 do <<
  384. c:=log(b/a);
  385. k1:=0;
  386. k3:=0;
  387. x1:=zero;
  388. r6:=zero;
  389. r7:=zero;
  390. for i:=1:n do <<
  391. x:=a*randl(c);
  392. y:=x*x;
  393. z:=sqrt(y);
  394. w:=(z-x)/x;
  395. if w>zero then k1:=k1+1;
  396. if w<zero then k3:=k3+1;
  397. w:=abs w;
  398. if w>=r6 then << r6:=w; x1:=x >>;
  399. r7:=r7+w*w >>;
  400. k2:=n-k1-k3;
  401. heading("sqrt",n,a,b);
  402. errsigns(k1,k2,k3);
  403. r7:=sqrt(r7/xn);
  404. w:=-999.0;
  405. if r6 neq zero then w:=log(abs r6)/albeta;
  406. maxrel(w,x1,max(ait+w,zero));
  407. w:=-999.0;
  408. if r7 neq zero then w:=log(r7)/albeta;
  409. rmserr(w,max(ait+w,zero));
  410. a:=one;
  411. b:=sqbeta >>;
  412. specials("sqrt(xmin)",xmin,sqrt(xmin));
  413. specials("1-epsneg ",one-epsneg,sqrt(one-epsneg));
  414. specials("1 ",one,sqrt(one));
  415. specials("1+eps ",one+eps,sqrt(one+eps));
  416. specials("xmax ",xmax,sqrt(xmax));
  417. specials("zero ",zero,sqrt(zero));
  418. errortest list('sqrt, - one);
  419. end;
  420. symbolic procedure sign(a,b);
  421. if minusp b then if minusp a then a else -a
  422. else if minusp a then -a else a;
  423. symbolic procedure test!-log();
  424. begin
  425. scalar a,ait,albeta,b,beta,c,del,eight,half,one,
  426. r6,r7,tenth,w,x,xl,xn,x1,y,z,zero,zz,i,i1,j,k1,k2,k3,n;
  427. princ "start of tests on log"; terpri();
  428. beta:=float ibeta;
  429. albeta:=log beta;
  430. ait:=float it;
  431. j:=it/3;
  432. zero:=float 0;
  433. one:=float 1;
  434. eight:=float 8;
  435. half:=one/float 2;
  436. tenth:=one/float 10;
  437. c:=one;
  438. for i:=1:j do c:=c/beta;
  439. b:=one+c;
  440. a:=one-c;
  441. n:=2000;
  442. xn:=float n;
  443. i1:=0;
  444. for j:=1:4 do <<
  445. princ list("start of test ",j); terpri();
  446. k1:=0;
  447. k3:=0;
  448. x1:=zero;
  449. r6:=zero;
  450. r7:=zero;
  451. del:=(b-a)/xn;
  452. xl:=a;
  453. for i:=1:n do <<
  454. x:=del*rnd()+xl;
  455. if j=1 then <<
  456. y:=(x-half)-half;
  457. zz:=log x;
  458. z:=one/3.0;
  459. z:=y*(z-y/4.0);
  460. z:=(z-half)*y*y+y >>
  461. else if j=2 then <<
  462. x:=(x+eight)-eight;
  463. y:=x+x/16.0;
  464. z:=log x;
  465. zz:=log y - 7.7746816434842581/100000.0;
  466. zz:=zz-31.0/512.0 >>
  467. else if j=3 then <<
  468. x:=(x+eight)-eight;
  469. y:=x+x*tenth;
  470. z:=log10 x;
  471. zz:=log10 y-3.7706015822504075/10000.0;
  472. zz:=zz-21.0/512.0 >>
  473. else <<
  474. z:=log(x*x);
  475. zz:=log x;
  476. zz:=zz+zz >>;
  477. w:=one;
  478. if z neq zero then w:=(z-zz)/z;
  479. z:=sign(w,z);
  480. if z>zero then k1:=k1+1;
  481. if z<zero then k3:=k3+1;
  482. w:=abs w;
  483. if w>=r6 then << r6:=w; x1:=x >>;
  484. r7:=r7+w*w;
  485. xl:=xl+del >>;
  486. k2:=n-k1-k3;
  487. r7:=sqrt(r7/xn);
  488. if j=1 then princ "log vs taylor expansion"
  489. else if j=2 then princ "log vs 17/16 on"
  490. else if j=3 then princ "log10 vs 11/10 on"
  491. else princ "log vs squared arg";
  492. terpri();
  493. if not (j=1) then heading("log",n,a,b)
  494. else << princ list("c=",c); terpri() >>;
  495. errsigns(k1,k2,k3);
  496. w:=-999.0;
  497. if r6 neq zero then w:=log(abs r6)/albeta;
  498. maxrel(w,x1,max(ait+w,zero));
  499. w:=-999.0;
  500. if r7 neq zero then w:=log(abs r7)/albeta;
  501. rmserr(w,max(ait+w,zero));
  502. if j=1 then << a:=sqrt(half); b:=15.0/16.0 >>
  503. else if j=2 then << a:=sqrt(tenth); b:=0.9 >>
  504. else << a:=16.0; b:=240.0 >> >>;
  505. for i:=1:5 do <<
  506. x:=rnd();
  507. x:=x+x+15.0;
  508. y:=one/x;
  509. z:=log x+log y;
  510. specials("log(1/x)+log(x) ",x,z) >>;
  511. specials( "log(1) ",one,log(one));
  512. specials( "xmin ",xmin,log(xmin));
  513. specials( "xmax ",xmax,log(xmax));
  514. errortest list('log, -2.0);
  515. errortest list('log, zero);
  516. princ "end of tests on log"; terpri()
  517. end;
  518. symbolic procedure test!-exp();
  519. begin
  520. scalar a,ait,albeta,b,beta,d,del,one,r6,r7,two,ten,v,w,
  521. x,xl,xn,x1,y,z,zero,zz,i1,j,k1,k2,k3,n;
  522. beta:=float ibeta;
  523. albeta:=log beta;
  524. ait:=float it;
  525. one:=float 1;
  526. two:=float 2;
  527. ten:=float 10;
  528. zero:=float 0;
  529. v:=0.0625;
  530. a:=two;
  531. b:=log(a)*0.5;
  532. a:=-b+v;
  533. d:=log(0.9*xmax);
  534. n:=2000;
  535. xn:=float n;
  536. i1:=0;
  537. for j:=1:3 do <<
  538. k1:=0;
  539. k3:=0;
  540. x1:=zero;
  541. r6:=zero;
  542. r7:=zero;
  543. del:=(b-a)/xn;
  544. xl:=a;
  545. for i:=1:n do <<
  546. x:=del*rnd()+xl;
  547. y:=x-v;
  548. if y<zero then x:=y+v;
  549. z:=exp x;
  550. zz:=exp y;
  551. if j neq 1 then
  552. z:=z*0.0625 - z*2.4453321046920570389/1000.0
  553. else z:=z-z*6.058693718652421388/100.0;
  554. w:=one;
  555. if zz neq zero then w:=(z-zz)/zz;
  556. if w < zero then k1:=k1+1;
  557. if w>zero then k3:=k3+1;
  558. w:=abs w;
  559. if w>r6 then << r6:=w; x1:=x >>;
  560. r7:=r7+w*w;
  561. xl:=xl+del >>;
  562. k2:=n-k1-k3;
  563. r7:=sqrt(r7/xn);
  564. princ list("exp with v=",v); terpri();
  565. heading("exp",n,a,b);
  566. errsigns(k1,k2,k3);
  567. w:=-999.0;
  568. if r6 neq zero then w:=log abs r6/albeta;
  569. maxrel(w,x1,max(ait+w,zero));
  570. w:=-999.0;
  571. if r7 neq zero then w:=log abs r7/albeta;
  572. rmserr(w,max(ait+w,zero));
  573. if j neq 2 then <<
  574. v:=45.0 / 16.0;
  575. a:=-10*b;
  576. b:=4.0 * xmin * (beta**it);
  577. b:=log b >>
  578. else << a:=-two * a;
  579. b:=ten * a;
  580. if b<d then b:=d >> >>;
  581. for i:=1:5 do <<
  582. x:=rnd()*beta;
  583. y:=-x;
  584. z:=exp x * exp y - one;
  585. specials("exp(x)*exp(-x)-1 ",x,z) >>;
  586. specials("exp(0)-1 ",zero,exp(zero)-one);
  587. x:=float fix log xmin;
  588. specials("xmin ",x,exp(x));
  589. x:=float fix log xmax;
  590. specials("xmax ",x,exp x);
  591. x:=x / two;
  592. v:=x/two;
  593. y:=exp x;
  594. z:=exp v;
  595. z:=z*z;
  596. princ list(x,y,v,z); terpri();
  597. x:=-one/sqrt(xmin);
  598. errortest list('exp, x);
  599. x:=-x;
  600. errortest list('exp, x);
  601. princ "end of test on exp"; terpri()
  602. end;
  603. symbolic procedure test!-sin();
  604. begin
  605. scalar a,ait,albeta,b,beta,betap,c,del,one,r6,r7,three,w,
  606. x,xl,xn,x1,y,z,zero,zz,expon,i1,j,k1,k2,k3,n;
  607. beta:=float ibeta;
  608. albeta:=log beta;
  609. ait:=float it;
  610. one:=float 1;
  611. three:=float 3;
  612. zero:=float 0;
  613. a:=zero;
  614. b:=1.570796327;
  615. c:=b;
  616. n:=2000;
  617. xn:=float n;
  618. i1:=0;
  619. for j:=1:3 do <<
  620. princ list("start of test ",j," of sin/cos"); terpri();
  621. k1:=0;
  622. k3:=0;
  623. x1:=zero;
  624. r6:=zero;
  625. r7:=zero;
  626. del:=(b-a)/xn;
  627. xl:=a;
  628. for i:=1:n do <<
  629. x:=del*rnd()+xl;
  630. y:=x/three;
  631. y:=(x+y)-x;
  632. x:=three*y;
  633. if j neq 3 then <<
  634. z:=sin x;
  635. zz:=sin y;
  636. w:=one;
  637. if z neq zero then w:=(z-zz*(three-4.0*zz*zz))/z >>
  638. else <<
  639. z:=cos x;
  640. zz:=cos y;
  641. w:=one;
  642. if z neq zero then w:=(z+zz*(three-4.0*zz*zz))/z >>;
  643. if w < zero then k1:=k1+1;
  644. if w>zero then k3:=k3+1;
  645. w:=abs w;
  646. if w>r6 then << r6:=w; x1:=x >>;
  647. r7:=r7+w*w;
  648. xl:=xl+del >>;
  649. k2:=n-k1-k3;
  650. r7:=sqrt(r7/xn);
  651. heading("sin/cos",n,a,b);
  652. errsigns(k1,k2,k3);
  653. w:=-999.0;
  654. if r6 neq zero then w:=log abs r6/albeta;
  655. maxrel(w,x1,max(ait+w,zero));
  656. w:=-999.0;
  657. if r7 neq zero then w:=log abs r7/albeta;
  658. rmserr(w,max(ait+w,zero));
  659. a:=18.84955592;
  660. if j=2 then a:=b+c;
  661. b:=a+c >>;
  662. c:=one/beta**(it/2);
  663. z:=(sin(a+c)-sin(a-c))/(c+c);
  664. princ list("this should be about 1.0 ",z); terpri();
  665. for i:=1:5 do <<
  666. x:=rnd()*a;
  667. z:=sin x + sin(-x);
  668. specials("sin(x)+sin(-x) ",x,z) >>;
  669. betap:=beta**it;
  670. x:=rnd()/betap;
  671. for i:=1:5 do <<
  672. z:=x-sin x;
  673. specials("small args to sin ",x,z);
  674. x := x/beta >>;
  675. for i:=1:5 do <<
  676. x:=rnd()*a;
  677. z:=cos(x)-cos(-x);
  678. specials("cos(x)-cos(-x) ",x,z) >>;
  679. expon:=float minexp * 0.75;
  680. x:=beta**expon;
  681. y:=sin x;
  682. specials("tiny arg ",x,y);
  683. %-- z:=sqrt betap;
  684. %-- x:=z*(one-epsneg);
  685. %-- y:=sin x;
  686. %-- specials("?? ",x,y);
  687. %-- y:=sin z;
  688. %-- specials("??+ ",z,y);
  689. %-- x:=z*(one+eps);
  690. %-- y:=sin x;
  691. %-- specials("??++",x,y);
  692. x:=betap;
  693. errortest list('sin, x);
  694. princ "end of test on sin/cos"; terpri()
  695. end;
  696. symbolic procedure test!-tan();
  697. begin
  698. scalar a,ait,albeta,b,beta,betap,c1,c2,del,half,pi,r6,r7,
  699. w,x,xl,xn,x1,y,z,zero,zz,i,i1,j,k1,k2,k3,n,expon;
  700. beta:=float ibeta;
  701. albeta:=log beta;
  702. ait:=float it;
  703. zero:=float 0;
  704. half:=0.5;
  705. pi:=3.1415926;
  706. a:=zero;
  707. b:=pi*0.25;
  708. n:=2000;
  709. xn:=float n;
  710. i1:=0;
  711. for j:=1:4 do <<
  712. princ list("start of test ",j," of tan/cot"); terpri();
  713. k1:=0;
  714. k3:=0;
  715. x1:=zero;
  716. r6:=zero;
  717. r7:=zero;
  718. del:=(b-a)/xn;
  719. xl:=a;
  720. for i:=1:n do <<
  721. x:=del*rnd()+xl;
  722. y:=x*half;
  723. x:=y+y;
  724. if not (j=4) then <<
  725. z:=tan x;
  726. zz:=tan y;
  727. w:=1.0;
  728. if z neq zero then <<
  729. w:=((half-zz)+half)*((half+zz)+half);
  730. w:=(z-(zz+zz)/w)/z >> >>
  731. else <<
  732. z:=cot x;
  733. zz:=cot y;
  734. w:=1.0;
  735. if z neq zero then <<
  736. w:=((half-zz)+half)*((half+zz)+half);
  737. w:=(z+(w/(zz+zz)))/z >> >>;
  738. if w>zero then k1:=k1+1;
  739. if w<zero then k3:=k3+1;
  740. w:=abs w;
  741. if w>r6 then << r6:=w; x1:=x >>;
  742. r7:=r7+w*w;
  743. xl:=xl+del >>;
  744. k2:=n-k1-k3;
  745. r7:=sqrt(r7/xn);
  746. heading("tan/cot",n,a,b);
  747. errsigns(k1,k2,k3);
  748. w:=-999.0;
  749. if r6 neq zero then w:=log abs r6/albeta;
  750. maxrel(w,x1,max(ait+w,zero));
  751. w:=-999.0;
  752. if r7 neq zero then w:=log abs r7/albeta;
  753. rmserr(w,max(ait+w,zero));
  754. if j=1 then <<
  755. a:=pi*0.875;
  756. b:=pi*1.125 >>
  757. else <<
  758. a:=6.0*pi;
  759. b:=a+pi*0.25 >> >>;
  760. for i:=1:5 do <<
  761. x:=rnd()*a;
  762. z:=tan x + tan(-x);
  763. specials("tan(x)+tan(-x) ",x,z) >>;
  764. betap:=beta**it;
  765. x:=rnd()/betap;
  766. for i:=1:5 do <<
  767. z:=x-tan x;
  768. specials("small args to tan ",x,z);
  769. x := x/beta >>;
  770. expon:=float minexp * 0.75;
  771. x:=beta**expon;
  772. y:=tan x;
  773. specials("tiny arg ",x,y);
  774. c1:=-225.0;
  775. c2:=-0.950846454195142026;
  776. x:=11.0;
  777. y:=tan x;
  778. w:=((c1-y)+c2)/(c1+c2);
  779. z:=log abs w/albeta;
  780. princ list("the relative error in tan 11 is ",z,max(ait+z,zero));
  781. terpri();
  782. x:=beta**(it/2);
  783. errortest list('tan, x);
  784. x:=betap;
  785. errortest list('tan, x);
  786. princ "end of test on tan/cot"; terpri()
  787. end;
  788. on echo, time;
  789. out "fptest.log";
  790. fptest();
  791. out t;
  792. end;