.# .# .# .CH "Testing" .# .# .MH "In General" It is important to test the standard mathematical functions which may be used in critical calculations. Not only will the tests measure the accuracy of the routines involved for use in later error estimations, but the testing helps provide information about the allowed domain and range of the functions. Many computer systems have quirks that require special case code for values near the extremes of precision {11}. .# .SH "The Source of the Tests" The tests were taken from {7}. The tests were altered somewhat to help automate a test suite and also to provide a slightly more consistent form of output for comparison purposes. All of the tests use a set of common routines for non-test calculations and invocation. Where appropriate, the tests have been coded in both Fortran 66 (FTN) and Fortran 77 (F77) so as to test 3 libraries: the SWT Math library, the standard FTN library used by Fortran 66 and Ratfor programs, and the new standard library used in Fortran 77, Pascal, and PL/I programs. .pp The source code for the tests and support routines is located in the directory along with the source to the SWT Math library. There is a separate set of tests for single precision and double precision. These have been provided in case you wish to verify your own software, or re-run the tests on your own machine. Instructions on how to build and run a test are given in Appendix IV. .# .SH "The Test Results" There are a number of error measures that could be used to describe these library routines. (For an involved discussion of some of the issues involved, see {7} ) The tests which will be described below were taken from {7} and involve a number of checks and comparisons. Each test involves some random accuracy checks in various argument domains. These checks are made against known identities or calculations; for instance, the square root function is checked by comparing a random X against the square root of X*X. .pp Each accuracy test was performed for 5000 random arguments in each domain. The results of each test are given below, listed as the number of exact matches against the expected value, the number of times less than, and the number of times greater than. Also given are the MRE (maximum relative error) and the point at which that error occurred, and the RMS (root mean square) error over all the tests in that domain. For those unfamiliar with these measures, the MRE can be thought of as a "worst case" error, and the RMS can be viewed as an "average case" measure of error. .pp The tests are given single precision first, then double precision. The tests with an asterisk ("*") after the CPU model are double precision test results. .pp Most of the routines have also been tested with special arguments at the limits of the argument domain or machine precision to help validate the entire range of possible input values. You will note that a few of the Prime standard library routines fail or return incorrect values at the extreme points of the domain. Other special tests are performed and described with each routine, as appropriate. The results given for some of these tests are worst-case results and not average-case; the average case performance was often much better with special arguments. .pp Finally, each routine was tested with values that would trigger an error (if appropriate). Again, some of the Prime library routines performed badly -- some of them returned incorrect values and never triggered an error. .# .SH "A Special Note on 550 Results" Each test was run on a 550 model cpu at Georgia Tech and on a 750 model cpu at the Atlanta office of Prime Computer, Inc. The results for the 550 are intended for comparison purposes and [ul should not] be taken as a strict measure of accuracy. This is due to the problem with truncation of bits in double precision multiplies discussed in the last chapter. The vast differences in accuracy results between the 550 and 750 may be a measure of improvement in the library routines due to increased accuracy, or they may be an artifact caused by a change in the values calculated by the test programs themselves. The figures given should still allow some comparison between the Prime libraries and the SWT Math library, however. .# .SH "Other Points of Interest" All of the tests invoke a special subroutine named 'machar' which determines machine characteristics to be used in the tests. The double precision version of this routine cannot be run unmodified on Prime machines due to their odd exponent structure. The double precision routine was modified by the author to return the results as defined by {7}. To recap the few most important points: a single precision value has 23 bits of mantissa and 8 bits of exponent, and rounds results. A double precision value has 47 bits of mantissa and 16 bits of exponent, and multiplication truncates results. .pp Since single precision arithmetic can include extra bits of accuracy if intermediate results are kept in the extended register, the test routines have been modified in places to force storage (and thus, truncation) of intermediate results. All of the single precision tests were compiled with the -FRN option set on. All of the tests were compiled with minimal optimizations enabled and full debugging. The debug option defeats register tracking optimizations and forces numerous stores. As an aside, this is often why erroneous numerical results disappear when a module is compiled with the debug option -- often to the amazement and indignation of the user. .pp The random number generator was not extensively tested since it was coded based on published, previous tests {8}. It should be noted, however, that a number of distribution and spectral tests were done locally to ensure that the implementation was not suspect. For comparison purposes, it should be noted that the multiplier used in the Prime APPLIB random number generator (16807) has been shown to be poor in performance on both spectral and lattice tests {8}. The Fortran intrinsic random number generators ('rnd' and 'irnd') behave very poorly in simple spectral tests. They are implemented as 16 bit generators rather than as 32 bit generators. .# .SH "Use of These Results" It should be noted that these results are general in nature and should not be taken as a complete measure of accuracy on Prime computers. The author has not had extensive training in numerical analysis. A few of the tests did not appear to work correctly, and I found what I believe to be at least one genuine bug in the logic of one of the published test programs. The unusual and inconsistent register structure also leads to problems in running the tests. .pp It should also be noted that the Primos 18.4 version of the libraries was used in these tests. Future releases of these libraries may demonstrate better performance. .pp These tests are to be used for general comparison purposes of the Software Tools Math Library routines and the standard Prime libraries. There appear to be a number of accuracy problems in the Prime library routines and floating point firmware and hopefully some of these problems have been indicated in the following tests. Any user wishing to use the Primes or the SWT Math library for any critical applications should make their own tests before placing any great confidence in the results. .# .# .de zh .ti [in] .sp .ne 20 .ul Test [1] .br .ti +3 [2] .sp .nf 5000 Comparisons Maximum Rel. Error Root Mean Sq. .ul CPU Library gt eq lt Bitloss At Bitloss .en zh .# .tc \ .ta 2 9 17 23 29 36 48 59 .# .# .de z5 .# z5 lib > = < MRE at RMS \550\[1]\[2]\[3]\[4]\[5] of 23\[6]\[7] of 23 .en z5 .# .# .de z7 .# z7 lib > = < MRE at RMS \750\[1]\[2]\[3]\[4]\[5] of 23\[6]\[7] of 23 .en z7 .# .# .de z6 .# z6 lib > = < MRE at RMS \550*\[1]\[2]\[3]\[4]\[5] of 47\[6]\[7] of 47 .en z6 .# .# .de z8 .# z8 lib > = < MRE at RMS \750*\[1]\[2]\[3]\[4]\[5] of 47\[6]\[7] of 47 .en z8 .# .# .de ze .sp .fi .en ze .# .# .# .# .# .de sh .# .bp .# [cc]ti [in] .# [cc]sp 2 .# [cc]ne 4 .# @[bf [1]] .# .sp .# .en sh .# .# .Mh "The Tests" .# .bp .SH "Inverse Sine and Cosine" There are no inverse sine or cosine functions in the Fortran 66 library, so these tests are for the other two libraries only. .# .zh 1 "ASIN(X) vs. Taylor Series in (-0.125, 0.125)" .z5 F77 1031 3227 " 742" 1.50 0.0110 0.00 .z5 SWT " 1" 4998 " 1" 0.63 -0.0808 0.00 .z7 F77 1041 3234 " 725" 1.50 0.0110 0.00 .z7 SWT " 1" 4998 " 1" 0.63 -0.0808 0.00 .sp .z6 F77 " 3" " 66" 4931 3.55 0.802E-2 2.15 .z6 SWT " 0" 2348 2652 2.00 -0.1247 0.05 .z8 F77 " 309" 1563 3128 2.58 -0.0157 0.72 .z8 SWT " 0" 2347 2653 2.00 -0.1247 0.05 .ze .zh 2 "ACOS(X) vs. Taylor Series in (-0.125, 0.125)" .z5 F77 " 0" 3320 1680 0.47 0.1249 0.00 .z5 SWT " 0" 4904 " 96" 0.47 0.1249 0.00 .z7 F77 " 0" 3319 1681 0.47 0.1249 0.00 .z7 SWT " 0" 4904 " 96" 0.47 0.1249 0.00 .sp .z6 F77 " 0" " 816" 4184 1.29 -0.0606 0.23 .z6 SWT " 0" 1796 3204 0.47 0.1250 0.01 .z8 F77 " 0" " 681" 4319 1.27 -0.0874 0.25 .z8 SWT " 0" 1795 3205 0.47 0.1250 0.01 .ze .zh 3 "ASIN(X) vs. Taylor Series in (0.75, 1.00)" .z5 F77 " 76" 1313 3611 2.00 0.84175 0.58 .z5 SWT " 237" 4123 " 640" 1.00 0.8416 0.00 .z7 F77 " 76" 1318 3606 2.00 0.84175 0.58 .z7 SWT " 237" 4123 " 640" 1.00 0.8416 0.00 .sp .z6 F77 " 0" " 6" 4994 6.95 1.0000 2.36 .z6 SWT " 0" " 446" 4554 1.24 0.7502 0.70 .z8 F77 " 125" 1413 3462 4.88 1.0000 0.86 .z8 SWT " 0" " 595" 4405 1.24 0.7500 0.66 .ze .zh 4 "ACOS(X) vs. Taylor Series in (0.75, 1.00)" .z5 F77 3210 1261 " 529" 2.95 0.9746 1.20 .z5 SWT " 593" 3785 " 622" 1.00 0.8773 0.00 .z7 F77 3193 1270 " 537" 2.92 0.9805 1.19 .z7 SWT " 593" 3785 " 622" 1.00 0.8773 0.00 .sp .z6 F77 4955 " 41" " 4" 14.43 1.0000 8.50 .z6 SWT 2656 2344 " 0" 2.00 0.8773 0.15 .z8 F77 2560 1267 1173 12.47 1.0000 6.52 .z8 SWT 2377 2623 " 0" 1.99 0.8762 0.07 .ze .zh 5 "ACOS(X) vs. Taylor Series in (-1.0,-0.75)" .z5 F77 " 0" 2287 2713 0.73 -0.7504 0.15 .z5 SWT " 0" 4571 " 429" 0.73 -0.7504 0.00 .z7 F77 " 0" 2286 2714 0.73 -0.7504 0.15 .z7 SWT " 0" 4572 " 428" 0.73 -0.7504 0.00 .sp .z6 F77 " 0" " 12" 4988 5.35 -1.0000 1.46 .z6 SWT " 0" " 547" 4453 0.73 -0.7500 0.51 .z8 F77 " 15" " 930" 4055 2.68 -1.0000 0.56 .z8 SWT " 0" " 608" 4392 0.73 -0.7500 0.50 .ze .pp Examining the test results shows that the standard Prime library routines are not as accurate as one might wish, especially in test 4. According to {7}, the MRE error should not exceed 1.5 on any of the tests, and the RMS error should be no more than 0.75 in all tests. With the exception of the MRE in the double precision test 2, the SWT Math library performs within these limits; even the error in test 2 is acceptable when the RMS error for the same test is noted. .pp The tests of special arguments and error returns showed no problems or unexpected results. .# .bp .SH "Inverse Tangent" .zh 1 "ATAN(X) vs. Taylor Series in (-0.0625, 0.0625)" .z5 FTN " 527" 4211 " 262" 1.00 -0.0039 0.00 .z5 F77 " 527" 4211 " 262" 1.00 -0.0039 0.00 .z5 SWT " 0" 4999 " 1" 0.32 0.0500 0.00 .z7 FTN " 529" 4213 " 258" 1.00 -0.0039 0.00 .z7 F77 " 529" 4213 " 258" 1.00 -0.0039 0.00 .z7 SWT " 0" 4999 " 1" 0.32 0.0500 0.00 .sp .z6 FTN " 0" " 0" 5000 3.32 0.0314 2.12 .z6 F77 " 0" " 47" 4953 3.20 -0.0043 1.95 .z6 SWT " 0" 2508 2492 1.59 0.0313 0.00 .z8 FTN " 0" " 3" 4997 2.00 -0.0156 1.11 .z8 F77 " 0" " 697" 4303 2.00 -0.0156 0.80 .z8 SWT " 0" 2530 2470 1.59 0.0313 0.00 .ze .zh 2 "ATAN(X) vs. ATAN(1/16)+ATAN((X-1/16)/(1+X/16)) in (0.0625, 0.2679)" .z5 FTN " 538" 2636 1826 2.34 0.2007 0.21 .z5 F77 " 664" 2482 1854 2.34 0.2007 0.35 .z5 SWT " 425" 3530 1045 1.40 0.1917 0.00 .z7 FTN " 543" 2626 1831 2.34 0.2007 0.21 .z7 F77 " 665" 2475 1860 2.34 0.2007 0.35 .z7 SWT " 423" 3530 1047 1.40 0.1917 0.00 .sp .z6 FTN " 372" 1454 3174 2.99 0.0631 1.27 .z6 F77 1774 " 723" 2503 3.28 0.2081 1.68 .z6 SWT " 947" 3933 " 120" 1.02 0.2523 0.00 .z8 FTN " 63" 2245 2692 1.70 0.0773 0.15 .z8 F77 1773 1656 1571 2.64 0.2033 0.94 .z8 SWT " 192" 4021 " 787" 1.03 0.2503 0.00 .ze .zh 3 "ATAN(X)*2 vs. ATAN(2X/(1-X*X)) in (0.2679, 0.4142)" .z5 FTN 1868 2729 " 403" 1.91 0.2717 0.05 .z5 F77 1531 2931 " 538" 1.91 0.2717 0.02 .z5 SWT " 882" 3678 " 440" 0.93 0.2680 0.00 .z7 FTN 1862 2734 " 404" 1.91 0.2717 0.05 .z7 F77 1526 2933 " 541" 1.91 0.2717 0.01 .z7 SWT " 878" 3679 " 443" 0.93 0.2680 0.00 .sp .z6 FTN " 158" " 175" 4667 4.81 0.2731 3.40 .z6 F77 1597 1506 1897 2.93 0.2693 1.05 .z6 SWT " 142" " 567" 4291 3.30 0.3155 1.83 .z8 FTN " 119" " 137" 4744 4.77 0.2817 3.43 .z8 F77 3576 1015 " 409" 2.76 0.3050 1.23 .z8 SWT " 146" 1017 3837 2.80 0.2952 1.22 .ze .zh 4 "ATAN(X)*2 vs. ATAN(2X/(1-X*X)) in (0.4142, 1.0)" .z5 FTN 1943 3010 " 47" 2.00 0.5483 0.07 .z5 F77 1970 2986 " 44" 2.00 0.5479 0.12 .z5 SWT " 453" 4386 " 161" 1.00 0.5465 0.00 .z7 FTN 1941 3012 " 47" 2.00 0.5483 0.08 .z7 F77 1968 2988 " 44" 2.00 0.5479 0.13 .z7 SWT " 452" 4387 " 161" 1.00 0.5465 0.00 .sp .z6 FTN " 188" " 576" 4236 4.12 0.4254 2.35 .z6 F77 " 939" 1521 2540 2.76 0.6689 0.99 .z6 SWT " 20" " 906" 4074 3.34 0.4166 1.94 .z8 FTN " 2" " 48" 4950 4.32 0.4246 2.78 .z8 F77 1913 1042 2045 2.35 0.6693 0.93 .z8 SWT " 872" 1859 2269 2.35 0.4145 0.64 .ze .pp Examining the test results leads to some interesting conclusions. The SWT Math Library routines are definitely better than either Prime library version, especially in test 2. The margin of error suggested in {7} is met only by the SWT routines. .pp In the testing of special arguments, the Prime FTN library ATAN had problems with the identities ATAN(-x) = - ATAN(x) and ATAN(x) = x for small x. Errors in both cases were about 10E-7 of the magnitude of x in both single and double precision. .# .bp .SH "Exponential" In the following tests, the double precision tests did not run to completion when testing the FTN library due to problems in the EXP function. Due to incorrect coding of the function, a floating to fixed conversion raised a SIZE error when taking the exponential of a value which was theoretically in range. Thus, only the results for the first test are available for the FTN exponential function in double precision. .zh 1 "EXP(X-0.0625) vs. EXP(X)/EXP(0.0625) in (-0.2841, 0.3466)" .z5 FTN " 624" 3537 " 839" 1.09 0.9069E-3 0.00 .z5 F77 1217 2173 1610 2.41 0.1815 0.39 .z5 SWT " 553" 3704 " 743" 1.00 0.0629 0.00 .z7 FTN " 636" 3525 " 839" 1.09 0.9069E-3 0.00 .z7 F77 1218 2172 1610 2.41 0.1815 0.39 .z7 SWT " 553" 3704 " 743" 1.00 0.0629 0.00 .sp .z6 FTN 1555 " 906" 2539 4.53 0.0150 2.51 .z6 F77 1619 " 711" 2670 3.74 0.2457 1.96 .z6 SWT " 325" 1759 2916 2.48 -0.2730 0.72 .z8 FTN " 479" 1762 2759 4.17 0.6161E-2 2.23 .z8 F77 1007 1597 2396 2.37 0.0293 0.78 .z8 SWT " 227" 2056 2717 2.08 -0.2777 0.42 .ze .zh 2 "EXP(X-2.8125) vs. EXP(X)/EXP(2.8125) in (-0.2277E+5, -0.3466E+1)" .z5 FTN 2838 " 23" 2139 6.42 -0.4405E+2 4.94 .z5 F77 1201 2287 1512 2.01 -0.6125E+2 0.32 .z5 SWT " 499" 3745 " 756" 1.02 -0.1799E+2 0.00 .z7 FTN 2838 " 23" 2139 6.42 -0.4405E+2 4.94 .z7 F77 1201 2285 1514 2.01 -0.6125E+2 0.32 .z7 SWT " 499" 3745 " 756" 1.02 -0.1799E+2 0.00 .sp .z6 F77 2638 " 426" 1936 47.00 -0.2268E+5 43.85 .z6 SWT 1034 " 205" 3761 13.95 -0.2264E+5 11.75 .z8 F77 2036 1426 1538 47.00 -0.2089E+2 43.85 .z8 SWT " 441" " 424" 4135 13.95 -0.2264E+5 11.75 .ze .zh 3 "EXP(X-2.8125) vs. EXP(X)/EXP(2.8125) in (6.931, 87.92)" .z5 FTN 2993 " 15" 1992 5.69 0.8669E+2 5.05 .z5 F77 1204 2311 1485 1.93 0.5069E+2 0.30 .z5 SWT " 489" 3704 " 807" 1.00 0.4371E+2 0.00 .z7 FTN 2993 " 15" 1992 5.69 0.8669E+2 5.05 .z7 F77 1204 2311 1485 1.93 0.5069E+2 0.30 .z7 SWT " 489" 3704 " 807" 1.00 0.4371E+2 0.00 .sp .z6 F77 2676 " 444" 1880 6.12 0.1571E+5 4.28 .z6 SWT 3082 " 899" 1019 4.28 0.1592E+5 2.07 .z8 F77 2078 1400 1522 5.08 0.1584E+5 2.65 .z8 SWT 1065 2205 1730 3.47 0.2018E+5 1.29 .ze .pp The results of test 2 are a bit surprising. After careful checking of the code and the test, it seems likely that there is a problem in the test since the routines from both libraries appear so bad. The MRE values appear to be close to the limit of what the routines can compute without underflow. Performing a check on the MRE error in each case reveals that there is no measurable error in the exponential function at this point in regard to the logarithm function. That is, the values of the exponential functions at the MRE point, when used as arguments to the SWT logarithm function (which is known to be fairly accurate; see below), produce the exact same value as the MRE point. This leads to the conclusion that the testing procedure is somehow faulty due to the unusual register structure of the Primes. It can be concluded that (in this domain) the functions are probably correct, but the measure of error cannot be determined by this test. .pp The results of the other tests indicate major differences in accuracy amongst the routines. The SWT routine seems much better in most cases. .pp The tests of special arguments revealed a number of interesting items. For instance, the single precision F77 EXP routine does not signal an error when given arguments very much out of range. Instead, it returns either zero (in the case of underflow) or a very large value (in the case of overflow). Also, all of the functions have some amount of error in the identity EXP(X)*EXP(-X) = 1.0, with single precision values of X near 1.0 producing errors of approximately 10E-6, and double precision values near 1.0 producing errors of near 10E-12. .# .bp .SH "Logarithms" .zh 1 "ALOG(X) vs. Taylor Series of ALOG(1+Y) in (1-.7813E-2, 1+.7813E-2)" .z5 FTN 2246 " 234" 2520 2.57 0.9961 1.35 .z5 F77 1392 2607 1001 1.89 1.0021 0.07 .z5 SWT " 1" 4996 " 3" 0.59 0.9948 0.00 .z7 FTN 2251 " 229" 2520 2.57 0.9961 1.36 .z7 F77 1389 2603 1008 1.89 1.0021 0.07 .z7 SWT " 1" 4996 " 3" 0.59 0.9948 0.00 .sp .z6 FTN 2449 " 315" 2236 25.55 1.000 19.52 .z6 F77 2038 " 996" 1966 2.98 1.000 1.42 .z6 SWT 1013 2493 1494 2.13 1.0000 0.19 .z8 FTN 1314 1603 2083 25.55 1.000 19.52 .z8 F77 1206 2507 1287 1.94 1.000 0.04 .z8 SWT 1206 2507 1287 1.94 1.000 0.04 .ze .zh 2 "ALOG(X) vs. ALOG(17X/16)-ALOG(17/16) in (0.7071, 0.9375)" .z5 FTN " 0" 1930 3070 2.01 0.8300 0.41 .z5 F77 " 0" 2753 2247 1.97 0.8253 0.07 .z5 SWT " 0" 3628 1372 1.00 0.7788 0.00 .z7 FTN " 0" 1936 3064 2.01 0.8300 0.41 .z7 F77 " 0" 2760 2240 1.97 0.8253 0.07 .z7 SWT " 0" 3628 1372 1.00 0.7788 0.00 .sp .z6 FTN " 0" " 54" 4946 4.24 0.9299 2.49 .z6 F77 " 0" " 132" 4868 3.00 0.7323 1.28 .z6 SWT " 0" 2053 2947 2.28 0.7347 0.51 .z8 FTN " 0" 1022 3978 4.26 0.9367 2.47 .z8 F77 " 0" 2067 2933 1.99 0.7779 0.46 .z8 SWT " 0" 2067 2933 1.99 0.7779 0.46 .ze .zh 3 "ALOG10(X) vs. ALOG10(11X/10)-ALOG(11/10) in (0.3162, 0.900)" .z5 FTN " 0" 1870 3130 2.58 0.8659 0.90 .z5 F77 " 0" 1986 3014 2.72 0.7045 0.74 .z5 SWT " 0" 2462 2538 2.06 0.8708 0.35 .z7 FTN " 0" 1867 3133 2.58 0.8659 0.90 .z7 F77 " 0" 1983 3017 2.72 0.7045 0.75 .z7 SWT " 0" 2462 2538 2.06 0.8708 0.35 .sp .z6 FTN " 0" " 924" 4076 4.44 0.8936 2.18 .z6 F77 " 0" 1029 3971 3.58 0.8974 1.66 .z6 SWT " 0" 1244 3756 3.73 0.8974 1.71 .z8 FTN " 0" 1383 3617 4.40 0.8963 2.27 .z8 F77 " 0" 1684 3316 3.37 0.8946 1.34 .z8 SWT " 0" 1499 3501 3.37 0.8943 1.29 .ze .zh 4 "ALOG(X*X) vs. 2*ALOG(X) in (16.00, 240.0)" .z5 FTN 2490 2510 " 0" 1.00 0.5473E+2 0.15 .z5 F77 2499 2501 " 0" 1.00 0.5473E+2 0.15 .z5 SWT " 127" 4873 " 0" 0.99 0.5575E+2 0.00 .z7 FTN 2499 2501 " 0" 1.00 0.5473E+2 0.15 .z7 F77 2491 2509 " 0" 1.00 0.5473E+2 0.15 .z7 SWT " 127" 4873 " 0" 0.99 0.5575E+2 0.00 .sp .z6 FTN 2911 2089 " 0" 2.36 0.2263E+2 0.98 .z6 F77 1195 3805 " 0" 3.00 0.5491E+2 1.58 .z6 SWT 1437 3563 " 0" 1.53 0.1604E+2 0.00 .z8 FTN 1548 3452 " 0" 1.44 0.1909E+2 0.00 .z8 F77 1537 3463 " 0" 1.44 0.1909E+2 0.00 .z8 SWT " 333" 4667 " 0" 1.06 0.4591E+2 0.00 .ze .pp These tests indicate that both the SWT Math library and the F77 library implementations of the logarithm functions are within acceptable error bounds (as defined in {7}), with the SWT version being somewhat better. The Fortran 66 version obviously has some points at which it behaves very poorly (see test 1). The similarity between the results for the SWT and F77 versions as shown in tests 1 and 2 can probably be explained by the fact that the same algorithm was used in each. .pp The SWT MRE errors in the double precision part of tests 1 and 2 are a bit large, but the corresponding error in the RMS indicates that the error is not systematic in nature. The error is of no major significance, although it could possibly be less. .pp The SWT routine performed very well in tests of the identity ALOG(X) = -ALOG(1/X), returning exactly the same values in every test. The FTN and F77 routines returned occasional matches, but were often in error by amounts close to 10E-6 (single precision) and 10E-12 (double precision). .pp What is most interesting is to note that both the F77 and FTN double precision routines are seriously flawed for very small arguments. Due to a rather obvious coding error, any double precision value whose exponent is less than -32640 will have its logarithm calculated as a large positive number -- just as if the sign of the exponent was reversed!! It would appear as if these routines were never tested at any values near the limits of their domains. The SWT routine does not suffer from this problem. .# .bp .SH "The POWR$M Function" The SWT 'powr$m' function was tested against the intrinsic "**" operation in these tests. That is, when testing the FTN and F77 libraries, the operation "x ** y" was used and the compilers were allowed to generate the calls to the appropriate library routines. .pp Although there is no single precision version of the SWT 'powr$m' function, it was tested within the range for single precision values and compared against the Prime power operation. Due to recurring problems in the division of very small values, and the multiplication of very large values caused by the faults in the hardware, tests 1 and 2 were the only double precision tests run to completion. .zh 1 "X ** 1.0 vs. X in (0.50, 1.00)" .z5 FTN 2399 2583 " 18" 0.99 0.5022 0.00 .z5 F77 2886 1935 " 179" 1.50 0.7072 0.37 .z5 SWT " 0" 5000 " 0" 0.00 ----- 0.00 .z7 FTN 2394 2586 " 20" 0.99 0.5022 0.00 .z7 F77 2888 1932 " 180" 1.50 0.7072 0.37 .z7 SWT " 0" 5000 " 0" 0.00 ----- 0.00 .sp .z6 FTN 5000 " 0" " 0" 4.76 0.8469 4.12 .z6 F77 4996 " 4" " 0" 4.19 0.6025 3.06 .z6 SWT 4997 " 3" " 0" 1.94 0.5222 0.69 .z8 FTN 4920 " 80" " 0" 4.28 0.7735 3.66 .z8 F77 4437 " 563" " 0" 2.62 0.6511 1.38 .z8 SWT 4837 " 163" " 0" 1.06 0.9578 0.50 .ze .zh 2 "(X*X)**1.5 vs. (X*X)*X in (0.50, 1.00)" .z5 FTN 3330 1394 " 276" 2.90 0.5118 0.98 .z5 F77 2047 2082 " 871" 1.87 0.5147 0.35 .z5 SWT " 332" 4359 " 319" 1.00 0.6300 0.00 .z7 FTN 3305 1410 " 285" 2.94 0.5068 0.98 .z7 F77 2086 2062 " 852" 1.98 0.9135 0.37 .z7 SWT " 317" 4349 " 334" 0.99 0.7954 0.00 .sp .z6 FTN 4939 " 55" " 6" 5.12 0.5712 4.03 .z6 F77 4869 " 131" " 0" 4.94 0.5466 3.30 .z6 SWT 1172 2051 1777 2.57 0.5012 0.66 .z8 FTN 4172 " 649" " 179" 4.23 0.7358 3.47 .z8 F77 3782 1010 " 208" 2.62 0.6875 1.20 .z8 SWT 2432 2566 " 2" 1.06 0.7833 0.07 .ze .zh 3 "(X*X)**1.5 vs. (X*X)*X in (1.00, 0.5541E+13)" .z5 FTN 5000 " 0" " 0" 8.51 0.1129E+13 7.80 .z5 F77 4950 " 0" " 50" 17.93 0.5487E+13 13.83 .z5 SWT " 315" 4362 " 323" 1.00 0.6928E+12 0.00 .z7 FTN 5000 " 0" " 0" 8.53 0.2676E+12 7.80 .z7 F77 4950 " 0" " 50" 17.93 0.5487E+13 13.83 .z7 SWT " 337" 4313 " 350" 0.99 0.4407E+13 0.00 .ze .pp In test 4, the point given at which the MRE was recorded is the value of X. The Y value is available on request. .zh 4 "X**Y vs. (X*X)**(Y/2), X in (0.01, 10.0), Y in (-19.42, 19.42)" .z5 FTN 1006 3052 " 942" 6.49 9.8692 4.20 .z5 F77 2266 " 518" 2216 5.46 0.0120 3.43 .z5 SWT 1700 1604 1696 3.25 2.0541 1.28 .z7 FTN " 958" 3104 " 938" 6.49 7.7463 4.20 .z7 F77 2251 " 514" 2235 5.46 0.0120 3.47 .z7 SWT 1644 1591 1765 3.20 2.8599 1.30 .ze .pp It seems fairly obvious from the above test results that the Prime library routines are rather sadly lacking in precision. Test 3 alone shows a RME loss of nearly 18 out of 23 bits. Conclusions about tests 3 and 4 can possibly (with a cautionary warning!) be extrapolated to the double precision cases, at least for the SWT routine, since the routine is the same for both precisions. The tests of special arguments indicate that the 'powr$m' routine does behave well in the double precision case. Running small portions of the test to avoid some of the firmware arithmetic problems tends to support these conclusions. .# .bp .SH "Sine and Cosine" .zh 1 "SIN(X) vs. 3*SIN(X/3)-4*SIN(X/3)**3 in (0.0, 1.571)" .z5 FTN 3047 " 32" 1921 1.41 0.8183 0.00 .z5 F77 " 466" 2204 2330 1.49 0.7910 0.00 .z5 SWT " 498" 3979 " 523" 1.00 0.5243 0.00 .z7 FTN 3095 " 0" 1905 1.41 0.8183 0.00 .z7 F77 " 466" 2202 2332 1.61 0.3330 0.00 .z7 SWT " 498" 3979 " 523" 1.00 0.5243 0.00 .sp .z6 FTN " 31" " 233" 4736 4.50 0.7888 3.17 .z6 F77 3204 1276 " 520" 4.07 0.3021 2.09 .z6 SWT 2880 1207 " 913" 3.41 0.1898 1.51 .z8 FTN " 130" " 679" 4191 2.81 0.1495 1.44 .z8 F77 " 863" 1773 2364 2.30 0.6557 0.46 .z8 SWT " 494" 2459 2047 2.04 1.3513 0.21 .ze .zh 2 "SIN(X) vs. 3*SIN(X/3)-4*SIN(X/3)**3 in (18.85, 20.42)" .z5 FTN 3546 " 12" 1442 18.00 18.850 11.87 .z5 F77 " 431" 2267 2302 1.73 19.001 0.00 .z5 SWT " 510" 3939 " 551" 1.00 19.103 0.00 .z7 FTN 3560 " 0" 1440 18.00 18.850 11.87 .z7 F77 " 431" 2267 2302 1.73 19.001 0.00 .z7 SWT " 511" 3938 " 551" 1.00 19.103 0.00 .sp .z6 FTN " 394" " 118" 4488 18.98 18.850 12.87 .z6 F77 1800 " 660" 2540 19.33 18.850 13.20 .z6 SWT 1776 " 491" 2733 19.33 18.850 13.20 .z8 FTN 1852 " 160" 2988 18.98 18.850 12.84 .z8 F77 " 891" 1803 2306 6.93 18.850 1.14 .z8 SWT " 699" 2463 1838 2.02 20.242 0.14 .ze .zh 3 "COS(X) vs. 4*COS(X/3)**3-3*COS(X/3) in (21.99, 23.56)" .z5 FTN 1911 " 13" 3076 11.83 23.555 7.14 .z5 F77 1850 " 24" 3126 1.36 23.150 0.00 .z5 SWT 2470 " 33" 2497 0.70 23.529 0.00 .z7 FTN 1923 " 0" 3077 11.83 23.555 7.14 .z7 F77 1845 " 0" 3155 1.37 23.150 0.00 .z7 SWT 2471 " 0" 2529 0.70 23.530 0.00 .sp .z6 FTN 1470 " 658" 2872 17.42 23.562 11.44 .z6 F77 4978 " 20" " 2" 17.77 23.562 11.70 .z6 SWT 4657 " 291" " 52" 17.77 23.562 11.70 .z8 FTN " 855" " 564" 3581 15.33 23.561 9.78 .z8 F77 4490 " 464" " 46" 2.85 23.353 1.46 .z8 SWT 1334 2614 1052 1.63 22.237 0.00 .ze .pp This is another test which illustrates how the multiplication bug in the 550 firmware can affect critical results. Observe the differences in double precision results in test 2 and 3. It is also fairly obvious that the FTN library sine and cosine functions have severe accuracy problems. The SWT library routines perform well within error limits {7} and are much better than the F77 routines. .pp When testing special arguments it is found that both the F77 and FTN routines have difficulty with the identities SIN(-X)=-SIN(X) and COS(-X)=COS(X). The ratio of the calculated difference to X is about 10E-8 for single precision, and 10E-12 to 10E-28 for double precision (the F77 library is more accurate). The SWT Library routines calculate no differences in these identities. .pp When special values are tested for error checking, it is discovered that the Prime routines trigger a SIZE error in float to fixed conversion when presented with a large argument rather than checking for (and reporting) the actual problem of an error of excessive magnitude. The SWT routine properly traps the error. .# .bp .SH "Hyperbolic Sine and Cosine" There are no hyperbolic sine (sinh) or hyperbolic cosine (cosh) routines in the FTN library, so the tests below are only for the F77 and SWT libraries. .zh 1 "SINH(X) vs. Taylor Series in (0.00, 0.50)" .z5 F77 " 1" 2418 2581 1.38 0.1908 0.17 .z5 SWT " 8" 4965 " 27" 1.00 0.4827 0.00 .z7 F77 " 1" 2430 2569 1.38 0.1908 0.17 .z7 SWT " 7" 4966 " 27" 1.00 0.4827 0.00 .sp .z6 F77 " 87" " 754" 4159 3.00 0.0156 1.69 .z6 SWT " 360" 2597 2043 1.99 0.4855 0.06 .z8 F77 " 343" 2643 2033 1.99 0.4833 0.06 .z8 SWT " 370" 2643 1987 2.00 0.4822 0.06 .ze .zh 2 "COSH(X) vs. Taylor Series in (0.00, 0.50)" .z5 F77 " 0" 3547 1453 1.00 0.0348 0.03 .z5 SWT " 6" 4905 " 89" 0.98 0.1599 0.00 .z7 F77 " 1" 3548 1451 1.00 0.3937E-2 0.03 .z7 SWT " 6" 4905 " 89" 0.98 0.1599 0.00 .sp .z6 F77 " 0" " 143" 4857 4.15 0.4906 2.74 .z6 SWT " 0" 1442 3558 3.41 0.4997 1.28 .z8 F77 " 0" 2098 2902 3.41 0.4955 1.30 .z8 SWT " 0" 2809 2191 3.15 0.4919 1.04 .ze .zh 3 "SINH(X) vs. C*(SINH(X+1)+SINH(X-1)) in (3.00, LOG(XMAX))" .z5 F77 2051 1879 1070 16.53 87.017 10.43 .z5 SWT 1618 3303 " 79" 1.24 43.500 0.00 .z7 F77 2051 1881 1068 16.53 87.017 10.43 .z7 SWT 1618 3303 " 79" 1.24 43.500 0.00 .sp .z6 F77 3615 " 388" " 997" 5.92 0.2124E+5 4.19 .z6 SWT 4579 " 262" " 159" 4.45 0.2067E+5 3.17 .z8 F77 3937 " 337" " 726" 4.85 0.1669E+5 2.73 .z8 SWT 4498 " 303" " 199" 3.03 0.1304E+5 1.49 .ze .pp In test 4, the double precision COSH routine in the F77 library generated numerous errors for large values that should have been in range. These errors aborted the test and therefore there are no results for the double precision F77 COSH. .zh 4 "COSH(X) vs. C*(COSH(X+1)+COSH(X-1)) in (3.00, LOG(XMAX))" .z5 F77 2051 1903 1046 17.75 87.000 11.74 .z5 SWT 1558 3341 " 101" 1.00 49.214 0.00 .z7 F77 2051 1904 1045 17.75 87.000 11.74 .z7 SWT 1558 3341 " 101" 1.00 49.214 0.00 .sp .z6 SWT 4566 " 263" " 171" 4.53 0.1794E+5 3.16 .z8 SWT 4522 " 284" " 194" 3.06 0.1281E+5 1.49 .ze .pp The results of tests 3 and 4 show that the F77 routines are rather inaccurate at the extremes of range. The RME measures for the SWT routines are a bit large, but the corresponding RMS error is small. According to the figures given in {7}, the SWT routines perform within the range of acceptable error. .pp As with many of the other tests, fundamental identities involving negated arguments were not calculated quite correctly in the Prime routines. Another interesting(?) result occurred when the F77 SINH routine was called with a very large positive value. The SINH routine did not signal an error, but rather returned the maximum floating point value -- an incorrect result. .# .bp .SH "Square Root" The square root function is one of the easiest to code and the accuracy of such a routine should be very, very good if done correctly. Newton's method converges quickly and requires only a few iterations on a reduced argument to reach a solution. Due to the nature of the square root function and its use, the random arguments are logarithmically distributed over the sample interval; all the other tests use a uniform distribution. .zh 1 "SQRT(X*X) vs. X in (0.7071, 1.00)" .z5 FTN " 0" 5000 " 0" 0.00 ----- 0.00 .z5 F77 " 1" 4999 " 0" 0.42 0.7500 0.00 .z5 SWT " 0" 5000 " 0" 0.00 ----- 0.00 .z7 FTN " 0" 5000 " 0" 0.00 ----- 0.00 .z7 F77 " 1" 4999 " 0" 0.42 0.7500 0.00 .z7 SWT " 0" 5000 " 0" 0.00 ----- 0.00 .sp .z6 FTN " 0" " 0" 5000 2.50 0.7095 1.33 .z6 F77 " 0" " 1" 4999 2.08 0.7074 1.13 .z6 SWT " 0" " 0" 5000 2.49 0.7114 1.31 .z8 FTN " 0" 2403 2597 0.50 0.7072 0.00 .z8 F77 " 0" 4481 " 519" 0.50 0.7072 0.00 .z8 SWT " 0" 2493 2507 0.50 0.7072 0.00 .ze .zh 2 "SQRT(X*X) vs. X in (1.00, 1.414)" .z5 FTN " 0" 5000 " 0" 0.00 ----- 0.00 .z5 F77 " 77" 4923 " 0" 1.00 1.0004 0.00 .z5 SWT " 0" 5000 " 0" 0.00 ----- 0.00 .z7 FTN " 0" 5000 " 0" 0.00 ----- 0.00 .z7 F77 " 80" 4920 " 0" 1.00 1.0004 0.00 .z7 SWT " 0" 5000 " 0" 0.00 ----- 0.00 .sp .z6 FTN " 0" " 0" 5000 3.00 1.0003 2.00 .z6 F77 " 0" " 6" 4994 3.00 1.0003 1.97 .z6 SWT " 0" " 0" 5000 3.00 1.0003 2.00 .z8 FTN " 0" 3384 1616 1.00 1.0001 0.00 .z8 F77 " 1" 3766 1233 1.00 1.0001 0.00 .z8 SWT " 0" 3387 1613 1.00 1.0001 0.00 .ze .pp All of the routines perform well in these tests, and all have results within acceptable margins of error. Test 2 readily illustrates how results can change due to the double precision multiply bug on 550 machines. Nothing in these tests would particularly recommend one routine against any other, although the SWT and FTN routines appear to be marginally more accurate than the F77 version. .pp Tests of special arguments, however, reveal some difficulties. The FTN and F77 double precision functions generate overflow faults when presented with a large enough argument. There is no valid mathematical reason for this to occur. Additionally, the Prime double precision functions calculated incorrect square roots for selected small values near the limits of storage precision. The SWT library routine behaved correctly for all special arguments. .# .bp .SH "Tangent and Cotangent" There is no tangent routine in the standard FTN library, so the results of the tests below apply to only the F77 and SWT libraries. .zh 1 "TAN(X) vs. 2*TAN(X/2)/(1-TAN(X/2)**2) in (0.00, 0.7854)" .z5 F77 1978 2361 " 661" 1.99 0.2458 0.22 .z5 SWT 2054 2518 " 428" 1.97 0.1273 0.11 .z7 F77 1968 2369 " 663" 1.99 0.2458 0.21 .z7 SWT 2044 2525 " 431" 1.79 0.5237 0.11 .sp .z6 F77 " 191" 1085 3724 3.43 0.7483 1.93 .z6 SWT " 190" " 996" 3814 3.62 0.7734 2.03 .z8 F77 " 439" 2565 1996 2.79 0.2815 0.99 .z8 SWT " 542" 2384 2074 2.87 0.2678 1.11 .ze .zh 2 "TAN(X) vs. 2*TAN(X/2)/(1-TAN(X/2)**2) in (2.749, 3.534)" .z5 F77 2318 2018 " 664" 2.21 2.9813 0.48 .z5 SWT " 991" 3178 " 831" 1.17 3.0306 0.00 .z7 F77 2340 2009 " 651" 2.09 2.8026 0.49 .z7 SWT " 987" 3176 " 837" 1.17 3.0306 0.00 .sp .z6 F77 3715 " 815" " 470" 3.88 3.1342 2.09 .z6 SWT 3827 " 868" " 305" 3.87 3.1116 2.00 .z8 F77 2197 1870 " 933" 2.79 2.9978 1.07 .z8 SWT 2131 2213 " 656" 2.60 3.4601 0.83 .ze .zh 3 "TAN(X) vs. 2*TAN(X/2)/(1-TAN(X/2)**2) in (18.85, 19.63)" .z5 F77 1933 2374 " 693" 1.93 19.332 0.20 .z5 SWT 2074 2467 " 459" 1.94 19.104 0.14 .z7 F77 1934 2374 " 692" 1.96 19.102 0.20 .z7 SWT 2071 2470 " 459" 1.94 19.104 0.14 .sp .z6 F77 " 193" 1136 3671 3.55 19.448 1.93 .z6 SWT " 178" 1076 3746 3.59 19.541 2.03 .z8 F77 " 399" 2583 2018 2.94 19.104 0.99 .z8 SWT " 499" 2403 2098 2.92 18.981 1.10 .ze .zh 4 "COT(X) vs. (COT(X/2)**2-1)/(2*COT(X/2)) in (18.85, 19.63)" .z5 F77 2602 " 16" 2382 2.16 19.377 0.18 .z5 SWT 2311 " 32" 2657 1.36 19.086 0.00 .z7 F77 2593 " 8" 2399 2.16 19.377 0.18 .z7 SWT 2307 " 13" 2680 1.35 19.086 0.00 .sp .z6 F77 " 261" " 818" 3921 3.91 18.857 2.20 .z6 SWT " 335" " 772" 3893 3.79 19.455 1.95 .z8 F77 " 973" 1843 2184 3.00 19.439 1.13 .z8 SWT " 989" 1794 2217 2.53 19.616 0.73 .ze .pp These tests show that both implementations are correct to within a reasonable error bound. Tests on special arguments revealed that the double precision F77 tangent routine signals an error for a large input value that should be well within the range that can be dealt with. .# .bp .SH "Hyperbolic Tangent" There does not appear to be a double precision hyperbolic tangent routine in the FTN library, although there is a single precision version. The following test results reflect that fact. .zh 1 "TANH(X) vs. (TANH(X-1/8)*TANH(1/8))/(1+TANH(X-1/8)*TANH(1/8)) in (0.125, 0.5493)" .z5 FTN 1396 1788 1816 2.99 0.1268 0.72 .z5 F77 1860 1253 1887 3.71 0.1347 1.41 .z5 SWT 1203 2833 " 964" 1.77 0.1479 0.00 .z7 FTN 1401 1782 1817 2.99 0.1268 0.73 .z7 F77 1863 1248 1889 3.71 0.1347 1.41 .z7 SWT 1200 2832 " 968" 1.77 0.1479 0.00 .sp .z6 F77 2731 " 230" 2039 6.64 0.1315 4.08 .z6 SWT 4624 " 348" " 28" 3.55 0.1288 1.98 .z8 F77 2380 " 605" 2015 4.83 0.1328 2.58 .z8 SWT 3966 " 957" " 77" 2.99 0.1270 1.33 .ze .zh 2 "TANH(X) vs. (TANH(X-1/8)*TANH(1/8))/(1+TANH(X-1/8)*TANH(1/8)) in (0.6743, 17.33)" .z5 FTN 1103 2707 1190 1.69 0.7217 0.00 .z5 F77 1288 2316 1396 1.91 1.0990 0.00 .z5 SWT 1204 2324 1472 1.73 0.6974 0.00 .z7 FTN 1100 2704 1196 1.69 0.7217 0.00 .z7 F77 1281 2324 1395 1.91 1.0990 0.00 .z7 SWT 1198 2328 1474 1.73 0.6974 0.00 .sp .z6 F77 1846 2234 " 920" 3.34 0.8543 0.86 .z6 SWT 2676 2258 " 66" 2.11 1.6430 0.62 .z8 F77 " 974" 3464 " 562" 2.26 0.7330 0.14 .z8 SWT 1185 3442 " 373" 1.76 1.3987 0.14 .ze .pp The above tests show that any of the three routines is acceptable for use in single precision, but the error in the double precision F77 routine in test 1 is rather large. The SWT routine is once again the best. .pp Tests of special arguments indicate a definite problem in the Prime single precision library routines when calculating various identity operations such as TANH(-X) = -TANH(X). The difference in calculated values is about 10E-6; the SWT routine calculates no differences. .# .so =fmac=/ugm