ltstd.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /* ltstd.c */
  2. /* Function test routine.
  3. * Requires long double type check routine and double precision function
  4. * under test. Indicate function name and range in #define statements
  5. * below. Modifications for two argument functions and absolute
  6. * rather than relative accuracy report are indicated.
  7. */
  8. #include <stdio.h>
  9. /* int printf(), gets(), sscanf(); */
  10. #include <math.h>
  11. #ifdef ANSIPROT
  12. int drand ( void );
  13. int dprec ( void );
  14. int ldprec ( void );
  15. double exp ( double );
  16. double sqrt ( double );
  17. double fabs ( double );
  18. double floor ( double );
  19. long double sqrtl ( long double );
  20. long double fabsl ( long double );
  21. #else
  22. int drand();
  23. int dprec(), ldprec();
  24. double exp(), sqrt(), fabs(), floor();
  25. long double sqrtl(), fabsl();
  26. #endif
  27. #define RELERR 1
  28. #define ONEARG 0
  29. #define ONEINT 0
  30. #define TWOARG 0
  31. #define TWOINT 0
  32. #define THREEARG 1
  33. #define THREEINT 0
  34. #define FOURARG 0
  35. #define VECARG 0
  36. #define FOURANS 0
  37. #define TWOANS 0
  38. #define PROB 0
  39. #define EXPSCALE 0
  40. #define EXPSC2 0
  41. /* insert function to be tested here: */
  42. #define FUNC hyperg
  43. double FUNC();
  44. #define QFUNC hypergl
  45. long double QFUNC();
  46. /*extern int aiconf;*/
  47. extern double MAXLOG;
  48. extern double MINLOG;
  49. extern double MAXNUM;
  50. #define LTS 3.258096538
  51. /* insert low end and width of test interval */
  52. #define LOW 0.0
  53. #define WIDTH 30.0
  54. #define LOWA 0.0
  55. #define WIDTHA 30.0
  56. /* 1.073741824e9 */
  57. /* 2.147483648e9 */
  58. long double qone = 1.0L;
  59. static long double q1, q2, q3, qa, qb, qc, qz, qy1, qy2, qy3, qy4;
  60. static double y2, y3, y4, a, b, c, x, y, z, e;
  61. static long double qe, qmax, qrmsa, qave;
  62. volatile double v;
  63. static long double lp[3], lq[3];
  64. static double dp[3], dq[3];
  65. char strave[20];
  66. char strrms[20];
  67. char strmax[20];
  68. double underthresh = 2.22507385850720138309E-308; /* 2^-1022 */
  69. void main()
  70. {
  71. char s[80];
  72. int i, j, k;
  73. long m, n;
  74. merror = 0;
  75. ldprec(); /* set up coprocessor. */
  76. /*aiconf = -1;*/ /* configure Airy function */
  77. x = 1.0;
  78. z = x * x;
  79. qmax = 0.0L;
  80. sprintf(strmax, "%.4Le", qmax );
  81. qrmsa = 0.0L;
  82. qave = 0.0L;
  83. #if 1
  84. printf(" Start at random number #:" );
  85. gets( s );
  86. sscanf( s, "%ld", &n );
  87. printf("%ld\n", n );
  88. #else
  89. n = 0;
  90. #endif
  91. for( m=0; m<n; m++ )
  92. drand( &x );
  93. n = 0;
  94. m = 0;
  95. x = floor( x );
  96. loop:
  97. for( i=0; i<500; i++ )
  98. {
  99. n++;
  100. m++;
  101. #if ONEARG || TWOARG || THREEARG || FOURARG
  102. /*ldprec();*/ /* set up floating point coprocessor */
  103. /* make random number in desired range */
  104. drand( &x );
  105. x = WIDTH * ( x - 1.0 ) + LOW;
  106. #if EXPSCALE
  107. x = exp(x);
  108. drand( &a );
  109. a = 1.0e-13 * x * a;
  110. if( x > 0.0 )
  111. x -= a;
  112. else
  113. x += a;
  114. #endif
  115. #if ONEINT
  116. k = x;
  117. x = k;
  118. #endif
  119. v = x;
  120. q1 = v; /* double number to q type */
  121. #endif
  122. /* do again if second argument required */
  123. #if TWOARG || THREEARG || FOURARG
  124. drand( &a );
  125. a = WIDTHA * ( a - 1.0 ) + LOWA;
  126. /*a /= 50.0;*/
  127. #if EXPSC2
  128. a = exp(a);
  129. drand( &y2 );
  130. y2 = 1.0e-13 * y2 * a;
  131. if( a > 0.0 )
  132. a -= y2;
  133. else
  134. a += y2;
  135. #endif
  136. #if TWOINT || THREEINT
  137. k = a + 0.25;
  138. a = k;
  139. #endif
  140. v = a;
  141. qy4 = v;
  142. #endif
  143. #if THREEARG || FOURARG
  144. drand( &b );
  145. #if PROB
  146. /*
  147. b = b - 1.0;
  148. b = a * b;
  149. */
  150. #if 1
  151. /* This makes b <= a, for bdtr. */
  152. b = (a - LOWA) * ( b - 1.0 ) + LOWA;
  153. if( b > 1.0 && a > 1.0 )
  154. b -= 1.0;
  155. else
  156. {
  157. a += 1.0;
  158. k = a;
  159. a = k;
  160. v = a;
  161. qy4 = v;
  162. }
  163. #else
  164. b = WIDTHA * ( b - 1.0 ) + LOWA;
  165. #endif
  166. /* Half-integer a and b */
  167. /*
  168. a = 0.5*floor(2.0*a+1.0);
  169. b = 0.5*floor(2.0*b+1.0);
  170. */
  171. v = a;
  172. qy4 = v;
  173. /*x = (a / (a+b));*/
  174. #else
  175. b = WIDTHA * ( b - 1.0 ) + LOWA;
  176. #endif
  177. #if THREEINT
  178. j = b + 0.25;
  179. b = j;
  180. #endif
  181. v = b;
  182. qb = v;
  183. #endif
  184. #if FOURARG
  185. drand( &c );
  186. c = WIDTHA * ( c - 1.0 ) + LOWA;
  187. /* for hyp2f1 to ensure c-a-b > -1 */
  188. /*
  189. z = c-a-b;
  190. if( z < -1.0 )
  191. c -= 1.6 * z;
  192. */
  193. v = c;
  194. qc = v;
  195. #endif
  196. #if VECARG
  197. for( j=0; j<3; j++)
  198. {
  199. drand( &x );
  200. x = WIDTH * ( x - 1.0 ) + LOW;
  201. v = x;
  202. dp[j] = v;
  203. q1 = v; /* double number to q type */
  204. lp[j] = q1;
  205. drand( &x );
  206. x = WIDTH * ( x - 1.0 ) + LOW;
  207. v = x;
  208. dq[j] = v;
  209. q1 = v; /* double number to q type */
  210. lq[j] = q1;
  211. }
  212. #endif /* VECARG */
  213. /*printf("%.16E %.16E\n", a, x);*/
  214. /* compute function under test */
  215. /* Set to double precision */
  216. /*dprec();*/
  217. #if ONEARG
  218. #if FOURANS
  219. /*FUNC( x, &z, &y2, &y3, &y4 );*/
  220. FUNC( x, &y4, &y2, &y3, &z );
  221. #else
  222. #if TWOANS
  223. FUNC( x, &z, &y2 );
  224. /*FUNC( x, &y2, &z );*/
  225. #else
  226. #if ONEINT
  227. z = FUNC( k );
  228. #else
  229. z = FUNC( x );
  230. #endif
  231. #endif
  232. #endif
  233. #endif
  234. #if TWOARG
  235. #if TWOINT
  236. z = FUNC( k, x );
  237. /*z = FUNC( x, k );*/
  238. /*z = FUNC( a, x );*/
  239. #else
  240. #if FOURANS
  241. FUNC( a, x, &z, &y2, &y3, &y4 );
  242. #else
  243. z = FUNC( a, x );
  244. #endif
  245. #endif
  246. #endif
  247. #if THREEARG
  248. #if THREEINT
  249. z = FUNC( j, k, x );
  250. #else
  251. z = FUNC( a, b, x );
  252. #endif
  253. #endif
  254. #if FOURARG
  255. z = FUNC( a, b, c, x );
  256. #endif
  257. #if VECARG
  258. z = FUNC( dp, dq );
  259. #endif
  260. q2 = z;
  261. /* handle detected overflow */
  262. if( (z == MAXNUM) || (z == -MAXNUM) )
  263. {
  264. printf("detected overflow ");
  265. #if FOURARG
  266. printf("%.4E %.4E %.4E %.4E %.4E %6ld \n",
  267. a, b, c, x, y, n);
  268. #else
  269. printf("%.16E %.4E %.4E %6ld \n", x, a, z, n);
  270. #endif
  271. e = 0.0;
  272. m -= 1;
  273. goto endlup;
  274. }
  275. /* Skip high precision if underflow. */
  276. if( merror == UNDERFLOW )
  277. goto underf;
  278. /* compute high precision function */
  279. /*ldprec();*/
  280. #if ONEARG
  281. #if FOURANS
  282. /*qy4 = QFUNC( q1, qz, qy2, qy3 );*/
  283. qz = QFUNC( q1, qy4, qy2, qy3 );
  284. #else
  285. #if TWOANS
  286. qy2 = QFUNC( q1, qz );
  287. /*qz = QFUNC( q1, qy2 );*/
  288. #else
  289. /* qy4 = 0.0L;*/
  290. /* qy4 = 1.0L;*/
  291. /*qz = QFUNC( qy4, q1 );*/
  292. /*qz = QFUNC( 1, q1 );*/
  293. qz = QFUNC( q1 ); /* normal */
  294. #endif
  295. #endif
  296. #endif
  297. #if TWOARG
  298. #if TWOINT
  299. qz = QFUNC( k, q1 );
  300. /*qz = QFUNC( q1, qy4 );*/
  301. /*qz = QFUNC( qy4, q1 );*/
  302. #else
  303. #if FOURANS
  304. qc = QFUNC( qy4, q1, qz, qy2, qy3 );
  305. #else
  306. /*qy4 = 0.0L;;*/
  307. /*qy4 = 1.0L );*/
  308. qz = QFUNC( qy4, q1 );
  309. #endif
  310. #endif
  311. #endif
  312. #if THREEARG
  313. #if THREEINT
  314. qz = QFUNC( j, k, q1 );
  315. #else
  316. qz = QFUNC( qy4, qb, q1 );
  317. #endif
  318. #endif
  319. #if FOURARG
  320. qz = QFUNC( qy4, qb, qc, q1 );
  321. #endif
  322. #if VECARG
  323. qz = QFUNC( lp, lq );
  324. #endif
  325. y = qz; /* correct answer, in double precision */
  326. /* get absolute error, in extended precision */
  327. qe = q2 - qz;
  328. e = qe; /* the error in double precision */
  329. /* handle function result equal to zero
  330. or underflowed. */
  331. if( qz == 0.0L || merror == UNDERFLOW || fabs(z) < underthresh )
  332. {
  333. underf:
  334. merror = 0;
  335. /* Don't bother to print anything. */
  336. #if 0
  337. printf("ans 0 ");
  338. #if ONEARG
  339. printf("%.8E %.8E %.4E %6ld \n", x, y, e, n);
  340. #endif
  341. #if TWOARG
  342. #if TWOINT
  343. printf("%d %.8E %.8E %.4E %6ld \n", k, x, y, e, n);
  344. #else
  345. printf("%.6E %.6E %.6E %.4E %6ld \n", a, x, y, e, n);
  346. #endif
  347. #endif
  348. #if THREEARG
  349. printf("%.6E %.6E %.6E %.6E %.4E %6ld \n", a, b, x, y, e, n);
  350. #endif
  351. #if FOURARG
  352. printf("%.4E %.4E %.4E %.4E %.4E %.4E %6ld \n",
  353. a, b, c, x, y, e, n);
  354. #endif
  355. #endif /* 0 */
  356. qe = 0.0L;
  357. e = 0.0;
  358. m -= 1;
  359. goto endlup;
  360. }
  361. else
  362. /* relative error */
  363. /* comment out the following two lines if absolute accuracy report */
  364. #if RELERR
  365. qe = qe / qz;
  366. #else
  367. {
  368. q2 = qz;
  369. q2 = fabsl(q2);
  370. if( q2 > 1.0L )
  371. qe = qe / qz;
  372. }
  373. #endif
  374. qave = qave + qe;
  375. /* absolute value of error */
  376. qe = fabs(qe);
  377. /* peak detect the error */
  378. if( qe > qmax )
  379. {
  380. qmax = qe;
  381. sprintf(strmax, "%.4Le", qmax );
  382. #if ONEARG
  383. printf("%.8E %.8E %s %6ld \n", x, y, strmax, n);
  384. #endif
  385. #if TWOARG
  386. #if TWOINT
  387. printf("%d %.8E %.8E %s %6ld \n", k, x, y, strmax, n);
  388. #else
  389. printf("%.6E %.6E %.6E %s %6ld \n", a, x, y, strmax, n);
  390. #endif
  391. #endif
  392. #if THREEARG
  393. printf("%.6E %.6E %.6E %.6E %s %6ld \n", a, b, x, y, strmax, n);
  394. #endif
  395. #if FOURARG
  396. printf("%.4E %.4E %.4E %.4E %.4E %s %6ld \n",
  397. a, b, c, x, y, strmax, n);
  398. #endif
  399. #if VECARG
  400. printf("%.8E %s %6ld \n", y, strmax, n);
  401. #endif
  402. }
  403. /* accumulate rms error */
  404. /* rmsa += e * e; accumulate the square of the error */
  405. q2 = qe * qe;
  406. qrmsa = qrmsa + q2;
  407. endlup: ;
  408. /*ldprec();*/
  409. }
  410. /* report every 500 trials */
  411. /* rms = sqrt( rmsa/m ); */
  412. q1 = m;
  413. q2 = qrmsa / q1;
  414. q2 = sqrtl(q2);
  415. sprintf(strrms, "%.4Le", q2 );
  416. q2 = qave / q1;
  417. sprintf(strave, "%.4Le", q2 );
  418. /*
  419. printf("%6ld max = %s rms = %s ave = %s \n", m, strmax, strrms, strave );
  420. */
  421. printf("%6ld max = %s rms = %s ave = %s \r", m, strmax, strrms, strave );
  422. fflush(stdout);
  423. goto loop;
  424. }