|
ScaLAPACK
2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
|
00001 * ================================================================ 00002 * This file contains the following LAPACK routines, for use by the 00003 * BLACS tester: LSAME, SLAMCH, DLAMCH, DLARND, ZLARND, DLARAN, 00004 * and ZLARAN. If you have ScaLAPACK or LAPACK, all of these files 00005 * are present in your library, and you may discard this file and 00006 * point to the appropriate archive instead. 00007 * ================================================================ 00008 00009 DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) 00010 * 00011 * -- LAPACK auxiliary routine (version 2.0) -- 00012 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 00013 * Courant Institute, Argonne National Lab, and Rice University 00014 * October 31, 1992 00015 * 00016 * .. Scalar Arguments .. 00017 CHARACTER CMACH 00018 * .. 00019 * 00020 * Purpose 00021 * ======= 00022 * 00023 * DLAMCH determines double precision machine parameters. 00024 * 00025 * Arguments 00026 * ========= 00027 * 00028 * CMACH (input) CHARACTER*1 00029 * Specifies the value to be returned by DLAMCH: 00030 * = 'E' or 'e', DLAMCH := eps 00031 * = 'S' or 's , DLAMCH := sfmin 00032 * = 'B' or 'b', DLAMCH := base 00033 * = 'P' or 'p', DLAMCH := eps*base 00034 * = 'N' or 'n', DLAMCH := t 00035 * = 'R' or 'r', DLAMCH := rnd 00036 * = 'M' or 'm', DLAMCH := emin 00037 * = 'U' or 'u', DLAMCH := rmin 00038 * = 'L' or 'l', DLAMCH := emax 00039 * = 'O' or 'o', DLAMCH := rmax 00040 * 00041 * where 00042 * 00043 * eps = relative machine precision 00044 * sfmin = safe minimum, such that 1/sfmin does not overflow 00045 * base = base of the machine 00046 * prec = eps*base 00047 * t = number of (base) digits in the mantissa 00048 * rnd = 1.0 when rounding occurs in addition, 0.0 otherwise 00049 * emin = minimum exponent before (gradual) underflow 00050 * rmin = underflow threshold - base**(emin-1) 00051 * emax = largest exponent before overflow 00052 * rmax = overflow threshold - (base**emax)*(1-eps) 00053 * 00054 * ===================================================================== 00055 * 00056 * .. Parameters .. 00057 DOUBLE PRECISION ONE, ZERO 00058 PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) 00059 * .. 00060 * .. Local Scalars .. 00061 LOGICAL FIRST, LRND 00062 INTEGER BETA, IMAX, IMIN, IT 00063 DOUBLE PRECISION BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN, 00064 $ RND, SFMIN, SMALL, T 00065 * .. 00066 * .. External Functions .. 00067 LOGICAL LSAME 00068 EXTERNAL LSAME 00069 * .. 00070 * .. External Subroutines .. 00071 EXTERNAL DLAMC2 00072 * .. 00073 * .. Save statement .. 00074 SAVE FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN, 00075 $ EMAX, RMAX, PREC 00076 * .. 00077 * .. Data statements .. 00078 DATA FIRST / .TRUE. / 00079 * .. 00080 * .. Executable Statements .. 00081 * 00082 IF( FIRST ) THEN 00083 FIRST = .FALSE. 00084 CALL DLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX ) 00085 BASE = BETA 00086 T = IT 00087 IF( LRND ) THEN 00088 RND = ONE 00089 EPS = ( BASE**( 1-IT ) ) / 2 00090 ELSE 00091 RND = ZERO 00092 EPS = BASE**( 1-IT ) 00093 END IF 00094 PREC = EPS*BASE 00095 EMIN = IMIN 00096 EMAX = IMAX 00097 SFMIN = RMIN 00098 SMALL = ONE / RMAX 00099 IF( SMALL.GE.SFMIN ) THEN 00100 * 00101 * Use SMALL plus a bit, to avoid the possibility of rounding 00102 * causing overflow when computing 1/sfmin. 00103 * 00104 SFMIN = SMALL*( ONE+EPS ) 00105 END IF 00106 END IF 00107 * 00108 IF( LSAME( CMACH, 'E' ) ) THEN 00109 RMACH = EPS 00110 ELSE IF( LSAME( CMACH, 'S' ) ) THEN 00111 RMACH = SFMIN 00112 ELSE IF( LSAME( CMACH, 'B' ) ) THEN 00113 RMACH = BASE 00114 ELSE IF( LSAME( CMACH, 'P' ) ) THEN 00115 RMACH = PREC 00116 ELSE IF( LSAME( CMACH, 'N' ) ) THEN 00117 RMACH = T 00118 ELSE IF( LSAME( CMACH, 'R' ) ) THEN 00119 RMACH = RND 00120 ELSE IF( LSAME( CMACH, 'M' ) ) THEN 00121 RMACH = EMIN 00122 ELSE IF( LSAME( CMACH, 'U' ) ) THEN 00123 RMACH = RMIN 00124 ELSE IF( LSAME( CMACH, 'L' ) ) THEN 00125 RMACH = EMAX 00126 ELSE IF( LSAME( CMACH, 'O' ) ) THEN 00127 RMACH = RMAX 00128 END IF 00129 * 00130 DLAMCH = RMACH 00131 RETURN 00132 * 00133 * End of DLAMCH 00134 * 00135 END 00136 * 00137 ************************************************************************ 00138 * 00139 SUBROUTINE DLAMC1( BETA, T, RND, IEEE1 ) 00140 * 00141 * -- LAPACK auxiliary routine (version 2.0) -- 00142 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 00143 * Courant Institute, Argonne National Lab, and Rice University 00144 * October 31, 1992 00145 * 00146 * .. Scalar Arguments .. 00147 LOGICAL IEEE1, RND 00148 INTEGER BETA, T 00149 * .. 00150 * 00151 * Purpose 00152 * ======= 00153 * 00154 * DLAMC1 determines the machine parameters given by BETA, T, RND, and 00155 * IEEE1. 00156 * 00157 * Arguments 00158 * ========= 00159 * 00160 * BETA (output) INTEGER 00161 * The base of the machine. 00162 * 00163 * T (output) INTEGER 00164 * The number of ( BETA ) digits in the mantissa. 00165 * 00166 * RND (output) LOGICAL 00167 * Specifies whether proper rounding ( RND = .TRUE. ) or 00168 * chopping ( RND = .FALSE. ) occurs in addition. This may not 00169 * be a reliable guide to the way in which the machine performs 00170 * its arithmetic. 00171 * 00172 * IEEE1 (output) LOGICAL 00173 * Specifies whether rounding appears to be done in the IEEE 00174 * 'round to nearest' style. 00175 * 00176 * Further Details 00177 * =============== 00178 * 00179 * The routine is based on the routine ENVRON by Malcolm and 00180 * incorporates suggestions by Gentleman and Marovich. See 00181 * 00182 * Malcolm M. A. (1972) Algorithms to reveal properties of 00183 * floating-point arithmetic. Comms. of the ACM, 15, 949-951. 00184 * 00185 * Gentleman W. M. and Marovich S. B. (1974) More on algorithms 00186 * that reveal properties of floating point arithmetic units. 00187 * Comms. of the ACM, 17, 276-277. 00188 * 00189 * ===================================================================== 00190 * 00191 * .. Local Scalars .. 00192 LOGICAL FIRST, LIEEE1, LRND 00193 INTEGER LBETA, LT 00194 DOUBLE PRECISION A, B, C, F, ONE, QTR, SAVEC, T1, T2 00195 * .. 00196 * .. External Functions .. 00197 DOUBLE PRECISION DLAMC3 00198 EXTERNAL DLAMC3 00199 * .. 00200 * .. Save statement .. 00201 SAVE FIRST, LIEEE1, LBETA, LRND, LT 00202 * .. 00203 * .. Data statements .. 00204 DATA FIRST / .TRUE. / 00205 * .. 00206 * .. Executable Statements .. 00207 * 00208 IF( FIRST ) THEN 00209 FIRST = .FALSE. 00210 ONE = 1 00211 * 00212 * LBETA, LIEEE1, LT and LRND are the local values of BETA, 00213 * IEEE1, T and RND. 00214 * 00215 * Throughout this routine we use the function DLAMC3 to ensure 00216 * that relevant values are stored and not held in registers, or 00217 * are not affected by optimizers. 00218 * 00219 * Compute a = 2.0**m with the smallest positive integer m such 00220 * that 00221 * 00222 * fl( a + 1.0 ) = a. 00223 * 00224 A = 1 00225 C = 1 00226 * 00227 *+ WHILE( C.EQ.ONE )LOOP 00228 10 CONTINUE 00229 IF( C.EQ.ONE ) THEN 00230 A = 2*A 00231 C = DLAMC3( A, ONE ) 00232 C = DLAMC3( C, -A ) 00233 GO TO 10 00234 END IF 00235 *+ END WHILE 00236 * 00237 * Now compute b = 2.0**m with the smallest positive integer m 00238 * such that 00239 * 00240 * fl( a + b ) .gt. a. 00241 * 00242 B = 1 00243 C = DLAMC3( A, B ) 00244 * 00245 *+ WHILE( C.EQ.A )LOOP 00246 20 CONTINUE 00247 IF( C.EQ.A ) THEN 00248 B = 2*B 00249 C = DLAMC3( A, B ) 00250 GO TO 20 00251 END IF 00252 *+ END WHILE 00253 * 00254 * Now compute the base. a and c are neighbouring floating point 00255 * numbers in the interval ( beta**t, beta**( t + 1 ) ) and so 00256 * their difference is beta. Adding 0.25 to c is to ensure that it 00257 * is truncated to beta and not ( beta - 1 ). 00258 * 00259 QTR = ONE / 4 00260 SAVEC = C 00261 C = DLAMC3( C, -A ) 00262 LBETA = C + QTR 00263 * 00264 * Now determine whether rounding or chopping occurs, by adding a 00265 * bit less than beta/2 and a bit more than beta/2 to a. 00266 * 00267 B = LBETA 00268 F = DLAMC3( B / 2, -B / 100 ) 00269 C = DLAMC3( F, A ) 00270 IF( C.EQ.A ) THEN 00271 LRND = .TRUE. 00272 ELSE 00273 LRND = .FALSE. 00274 END IF 00275 F = DLAMC3( B / 2, B / 100 ) 00276 C = DLAMC3( F, A ) 00277 IF( ( LRND ) .AND. ( C.EQ.A ) ) 00278 $ LRND = .FALSE. 00279 * 00280 * Try and decide whether rounding is done in the IEEE 'round to 00281 * nearest' style. B/2 is half a unit in the last place of the two 00282 * numbers A and SAVEC. Furthermore, A is even, i.e. has last bit 00283 * zero, and SAVEC is odd. Thus adding B/2 to A should not change 00284 * A, but adding B/2 to SAVEC should change SAVEC. 00285 * 00286 T1 = DLAMC3( B / 2, A ) 00287 T2 = DLAMC3( B / 2, SAVEC ) 00288 LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND 00289 * 00290 * Now find the mantissa, t. It should be the integer part of 00291 * log to the base beta of a, however it is safer to determine t 00292 * by powering. So we find t as the smallest positive integer for 00293 * which 00294 * 00295 * fl( beta**t + 1.0 ) = 1.0. 00296 * 00297 LT = 0 00298 A = 1 00299 C = 1 00300 * 00301 *+ WHILE( C.EQ.ONE )LOOP 00302 30 CONTINUE 00303 IF( C.EQ.ONE ) THEN 00304 LT = LT + 1 00305 A = A*LBETA 00306 C = DLAMC3( A, ONE ) 00307 C = DLAMC3( C, -A ) 00308 GO TO 30 00309 END IF 00310 *+ END WHILE 00311 * 00312 END IF 00313 * 00314 BETA = LBETA 00315 T = LT 00316 RND = LRND 00317 IEEE1 = LIEEE1 00318 RETURN 00319 * 00320 * End of DLAMC1 00321 * 00322 END 00323 * 00324 ************************************************************************ 00325 * 00326 SUBROUTINE DLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX ) 00327 * 00328 * -- LAPACK auxiliary routine (version 2.0) -- 00329 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 00330 * Courant Institute, Argonne National Lab, and Rice University 00331 * October 31, 1992 00332 * 00333 * .. Scalar Arguments .. 00334 LOGICAL RND 00335 INTEGER BETA, EMAX, EMIN, T 00336 DOUBLE PRECISION EPS, RMAX, RMIN 00337 * .. 00338 * 00339 * Purpose 00340 * ======= 00341 * 00342 * DLAMC2 determines the machine parameters specified in its argument 00343 * list. 00344 * 00345 * Arguments 00346 * ========= 00347 * 00348 * BETA (output) INTEGER 00349 * The base of the machine. 00350 * 00351 * T (output) INTEGER 00352 * The number of ( BETA ) digits in the mantissa. 00353 * 00354 * RND (output) LOGICAL 00355 * Specifies whether proper rounding ( RND = .TRUE. ) or 00356 * chopping ( RND = .FALSE. ) occurs in addition. This may not 00357 * be a reliable guide to the way in which the machine performs 00358 * its arithmetic. 00359 * 00360 * EPS (output) DOUBLE PRECISION 00361 * The smallest positive number such that 00362 * 00363 * fl( 1.0 - EPS ) .LT. 1.0, 00364 * 00365 * where fl denotes the computed value. 00366 * 00367 * EMIN (output) INTEGER 00368 * The minimum exponent before (gradual) underflow occurs. 00369 * 00370 * RMIN (output) DOUBLE PRECISION 00371 * The smallest normalized number for the machine, given by 00372 * BASE**( EMIN - 1 ), where BASE is the floating point value 00373 * of BETA. 00374 * 00375 * EMAX (output) INTEGER 00376 * The maximum exponent before overflow occurs. 00377 * 00378 * RMAX (output) DOUBLE PRECISION 00379 * The largest positive number for the machine, given by 00380 * BASE**EMAX * ( 1 - EPS ), where BASE is the floating point 00381 * value of BETA. 00382 * 00383 * Further Details 00384 * =============== 00385 * 00386 * The computation of EPS is based on a routine PARANOIA by 00387 * W. Kahan of the University of California at Berkeley. 00388 * 00389 * ===================================================================== 00390 * 00391 * .. Local Scalars .. 00392 LOGICAL FIRST, IEEE, IWARN, LIEEE1, LRND 00393 INTEGER GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT, 00394 $ NGNMIN, NGPMIN 00395 DOUBLE PRECISION A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE, 00396 $ SIXTH, SMALL, THIRD, TWO, ZERO 00397 * .. 00398 * .. External Functions .. 00399 DOUBLE PRECISION DLAMC3 00400 EXTERNAL DLAMC3 00401 * .. 00402 * .. External Subroutines .. 00403 EXTERNAL DLAMC1, DLAMC4, DLAMC5 00404 * .. 00405 * .. Intrinsic Functions .. 00406 INTRINSIC ABS, MAX, MIN 00407 * .. 00408 * .. Save statement .. 00409 SAVE FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX, 00410 $ LRMIN, LT 00411 * .. 00412 * .. Data statements .. 00413 DATA FIRST / .TRUE. / , IWARN / .FALSE. / 00414 * .. 00415 * .. Executable Statements .. 00416 * 00417 IF( FIRST ) THEN 00418 FIRST = .FALSE. 00419 ZERO = 0 00420 ONE = 1 00421 TWO = 2 00422 * 00423 * LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of 00424 * BETA, T, RND, EPS, EMIN and RMIN. 00425 * 00426 * Throughout this routine we use the function DLAMC3 to ensure 00427 * that relevant values are stored and not held in registers, or 00428 * are not affected by optimizers. 00429 * 00430 * DLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1. 00431 * 00432 CALL DLAMC1( LBETA, LT, LRND, LIEEE1 ) 00433 * 00434 * Start to find EPS. 00435 * 00436 B = LBETA 00437 A = B**( -LT ) 00438 LEPS = A 00439 * 00440 * Try some tricks to see whether or not this is the correct EPS. 00441 * 00442 B = TWO / 3 00443 HALF = ONE / 2 00444 SIXTH = DLAMC3( B, -HALF ) 00445 THIRD = DLAMC3( SIXTH, SIXTH ) 00446 B = DLAMC3( THIRD, -HALF ) 00447 B = DLAMC3( B, SIXTH ) 00448 B = ABS( B ) 00449 IF( B.LT.LEPS ) 00450 $ B = LEPS 00451 * 00452 LEPS = 1 00453 * 00454 *+ WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP 00455 10 CONTINUE 00456 IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN 00457 LEPS = B 00458 C = DLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) ) 00459 C = DLAMC3( HALF, -C ) 00460 B = DLAMC3( HALF, C ) 00461 C = DLAMC3( HALF, -B ) 00462 B = DLAMC3( HALF, C ) 00463 GO TO 10 00464 END IF 00465 *+ END WHILE 00466 * 00467 IF( A.LT.LEPS ) 00468 $ LEPS = A 00469 * 00470 * Computation of EPS complete. 00471 * 00472 * Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)). 00473 * Keep dividing A by BETA until (gradual) underflow occurs. This 00474 * is detected when we cannot recover the previous A. 00475 * 00476 RBASE = ONE / LBETA 00477 SMALL = ONE 00478 DO 20 I = 1, 3 00479 SMALL = DLAMC3( SMALL*RBASE, ZERO ) 00480 20 CONTINUE 00481 A = DLAMC3( ONE, SMALL ) 00482 CALL DLAMC4( NGPMIN, ONE, LBETA ) 00483 CALL DLAMC4( NGNMIN, -ONE, LBETA ) 00484 CALL DLAMC4( GPMIN, A, LBETA ) 00485 CALL DLAMC4( GNMIN, -A, LBETA ) 00486 IEEE = .FALSE. 00487 * 00488 IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN 00489 IF( NGPMIN.EQ.GPMIN ) THEN 00490 LEMIN = NGPMIN 00491 * ( Non twos-complement machines, no gradual underflow; 00492 * e.g., VAX ) 00493 ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN 00494 LEMIN = NGPMIN - 1 + LT 00495 IEEE = .TRUE. 00496 * ( Non twos-complement machines, with gradual underflow; 00497 * e.g., IEEE standard followers ) 00498 ELSE 00499 LEMIN = MIN( NGPMIN, GPMIN ) 00500 * ( A guess; no known machine ) 00501 IWARN = .TRUE. 00502 END IF 00503 * 00504 ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN 00505 IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN 00506 LEMIN = MAX( NGPMIN, NGNMIN ) 00507 * ( Twos-complement machines, no gradual underflow; 00508 * e.g., CYBER 205 ) 00509 ELSE 00510 LEMIN = MIN( NGPMIN, NGNMIN ) 00511 * ( A guess; no known machine ) 00512 IWARN = .TRUE. 00513 END IF 00514 * 00515 ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND. 00516 $ ( GPMIN.EQ.GNMIN ) ) THEN 00517 IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN 00518 LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT 00519 * ( Twos-complement machines with gradual underflow; 00520 * no known machine ) 00521 ELSE 00522 LEMIN = MIN( NGPMIN, NGNMIN ) 00523 * ( A guess; no known machine ) 00524 IWARN = .TRUE. 00525 END IF 00526 * 00527 ELSE 00528 LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN ) 00529 * ( A guess; no known machine ) 00530 IWARN = .TRUE. 00531 END IF 00532 *** 00533 * Comment out this if block if EMIN is ok 00534 IF( IWARN ) THEN 00535 FIRST = .TRUE. 00536 WRITE( 6, FMT = 9999 )LEMIN 00537 END IF 00538 *** 00539 * 00540 * Assume IEEE arithmetic if we found denormalised numbers above, 00541 * or if arithmetic seems to round in the IEEE style, determined 00542 * in routine DLAMC1. A true IEEE machine should have both things 00543 * true; however, faulty machines may have one or the other. 00544 * 00545 IEEE = IEEE .OR. LIEEE1 00546 * 00547 * Compute RMIN by successive division by BETA. We could compute 00548 * RMIN as BASE**( EMIN - 1 ), but some machines underflow during 00549 * this computation. 00550 * 00551 LRMIN = 1 00552 DO 30 I = 1, 1 - LEMIN 00553 LRMIN = DLAMC3( LRMIN*RBASE, ZERO ) 00554 30 CONTINUE 00555 * 00556 * Finally, call DLAMC5 to compute EMAX and RMAX. 00557 * 00558 CALL DLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX ) 00559 END IF 00560 * 00561 BETA = LBETA 00562 T = LT 00563 RND = LRND 00564 EPS = LEPS 00565 EMIN = LEMIN 00566 RMIN = LRMIN 00567 EMAX = LEMAX 00568 RMAX = LRMAX 00569 * 00570 RETURN 00571 * 00572 9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-', 00573 $ ' EMIN = ', I8, / 00574 $ ' If, after inspection, the value EMIN looks', 00575 $ ' acceptable please comment out ', 00576 $ / ' the IF block as marked within the code of routine', 00577 $ ' DLAMC2,', / ' otherwise supply EMIN explicitly.', / ) 00578 * 00579 * End of DLAMC2 00580 * 00581 END 00582 * 00583 ************************************************************************ 00584 * 00585 DOUBLE PRECISION FUNCTION DLAMC3( A, B ) 00586 * 00587 * -- LAPACK auxiliary routine (version 2.0) -- 00588 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 00589 * Courant Institute, Argonne National Lab, and Rice University 00590 * October 31, 1992 00591 * 00592 * .. Scalar Arguments .. 00593 DOUBLE PRECISION A, B 00594 * .. 00595 * 00596 * Purpose 00597 * ======= 00598 * 00599 * DLAMC3 is intended to force A and B to be stored prior to doing 00600 * the addition of A and B , for use in situations where optimizers 00601 * might hold one of these in a register. 00602 * 00603 * Arguments 00604 * ========= 00605 * 00606 * A, B (input) DOUBLE PRECISION 00607 * The values A and B. 00608 * 00609 * ===================================================================== 00610 * 00611 * .. Executable Statements .. 00612 * 00613 DLAMC3 = A + B 00614 * 00615 RETURN 00616 * 00617 * End of DLAMC3 00618 * 00619 END 00620 * 00621 ************************************************************************ 00622 * 00623 SUBROUTINE DLAMC4( EMIN, START, BASE ) 00624 * 00625 * -- LAPACK auxiliary routine (version 2.0) -- 00626 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 00627 * Courant Institute, Argonne National Lab, and Rice University 00628 * October 31, 1992 00629 * 00630 * .. Scalar Arguments .. 00631 INTEGER BASE, EMIN 00632 DOUBLE PRECISION START 00633 * .. 00634 * 00635 * Purpose 00636 * ======= 00637 * 00638 * DLAMC4 is a service routine for DLAMC2. 00639 * 00640 * Arguments 00641 * ========= 00642 * 00643 * EMIN (output) EMIN 00644 * The minimum exponent before (gradual) underflow, computed by 00645 * setting A = START and dividing by BASE until the previous A 00646 * can not be recovered. 00647 * 00648 * START (input) DOUBLE PRECISION 00649 * The starting point for determining EMIN. 00650 * 00651 * BASE (input) INTEGER 00652 * The base of the machine. 00653 * 00654 * ===================================================================== 00655 * 00656 * .. Local Scalars .. 00657 INTEGER I 00658 DOUBLE PRECISION A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO 00659 * .. 00660 * .. External Functions .. 00661 DOUBLE PRECISION DLAMC3 00662 EXTERNAL DLAMC3 00663 * .. 00664 * .. Executable Statements .. 00665 * 00666 A = START 00667 ONE = 1 00668 RBASE = ONE / BASE 00669 ZERO = 0 00670 EMIN = 1 00671 B1 = DLAMC3( A*RBASE, ZERO ) 00672 C1 = A 00673 C2 = A 00674 D1 = A 00675 D2 = A 00676 *+ WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND. 00677 * $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP 00678 10 CONTINUE 00679 IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND. 00680 $ ( D2.EQ.A ) ) THEN 00681 EMIN = EMIN - 1 00682 A = B1 00683 B1 = DLAMC3( A / BASE, ZERO ) 00684 C1 = DLAMC3( B1*BASE, ZERO ) 00685 D1 = ZERO 00686 DO 20 I = 1, BASE 00687 D1 = D1 + B1 00688 20 CONTINUE 00689 B2 = DLAMC3( A*RBASE, ZERO ) 00690 C2 = DLAMC3( B2 / RBASE, ZERO ) 00691 D2 = ZERO 00692 DO 30 I = 1, BASE 00693 D2 = D2 + B2 00694 30 CONTINUE 00695 GO TO 10 00696 END IF 00697 *+ END WHILE 00698 * 00699 RETURN 00700 * 00701 * End of DLAMC4 00702 * 00703 END 00704 * 00705 ************************************************************************ 00706 * 00707 SUBROUTINE DLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX ) 00708 * 00709 * -- LAPACK auxiliary routine (version 2.0) -- 00710 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 00711 * Courant Institute, Argonne National Lab, and Rice University 00712 * October 31, 1992 00713 * 00714 * .. Scalar Arguments .. 00715 LOGICAL IEEE 00716 INTEGER BETA, EMAX, EMIN, P 00717 DOUBLE PRECISION RMAX 00718 * .. 00719 * 00720 * Purpose 00721 * ======= 00722 * 00723 * DLAMC5 attempts to compute RMAX, the largest machine floating-point 00724 * number, without overflow. It assumes that EMAX + abs(EMIN) sum 00725 * approximately to a power of 2. It will fail on machines where this 00726 * assumption does not hold, for example, the Cyber 205 (EMIN = -28625, 00727 * EMAX = 28718). It will also fail if the value supplied for EMIN is 00728 * too large (i.e. too close to zero), probably with overflow. 00729 * 00730 * Arguments 00731 * ========= 00732 * 00733 * BETA (input) INTEGER 00734 * The base of floating-point arithmetic. 00735 * 00736 * P (input) INTEGER 00737 * The number of base BETA digits in the mantissa of a 00738 * floating-point value. 00739 * 00740 * EMIN (input) INTEGER 00741 * The minimum exponent before (gradual) underflow. 00742 * 00743 * IEEE (input) LOGICAL 00744 * A logical flag specifying whether or not the arithmetic 00745 * system is thought to comply with the IEEE standard. 00746 * 00747 * EMAX (output) INTEGER 00748 * The largest exponent before overflow 00749 * 00750 * RMAX (output) DOUBLE PRECISION 00751 * The largest machine floating-point number. 00752 * 00753 * ===================================================================== 00754 * 00755 * .. Parameters .. 00756 DOUBLE PRECISION ZERO, ONE 00757 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) 00758 * .. 00759 * .. Local Scalars .. 00760 INTEGER EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP 00761 DOUBLE PRECISION OLDY, RECBAS, Y, Z 00762 * .. 00763 * .. External Functions .. 00764 DOUBLE PRECISION DLAMC3 00765 EXTERNAL DLAMC3 00766 * .. 00767 * .. Intrinsic Functions .. 00768 INTRINSIC MOD 00769 * .. 00770 * .. Executable Statements .. 00771 * 00772 * First compute LEXP and UEXP, two powers of 2 that bound 00773 * abs(EMIN). We then assume that EMAX + abs(EMIN) will sum 00774 * approximately to the bound that is closest to abs(EMIN). 00775 * (EMAX is the exponent of the required number RMAX). 00776 * 00777 LEXP = 1 00778 EXBITS = 1 00779 10 CONTINUE 00780 TRY = LEXP*2 00781 IF( TRY.LE.( -EMIN ) ) THEN 00782 LEXP = TRY 00783 EXBITS = EXBITS + 1 00784 GO TO 10 00785 END IF 00786 IF( LEXP.EQ.-EMIN ) THEN 00787 UEXP = LEXP 00788 ELSE 00789 UEXP = TRY 00790 EXBITS = EXBITS + 1 00791 END IF 00792 * 00793 * Now -LEXP is less than or equal to EMIN, and -UEXP is greater 00794 * than or equal to EMIN. EXBITS is the number of bits needed to 00795 * store the exponent. 00796 * 00797 IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN 00798 EXPSUM = 2*LEXP 00799 ELSE 00800 EXPSUM = 2*UEXP 00801 END IF 00802 * 00803 * EXPSUM is the exponent range, approximately equal to 00804 * EMAX - EMIN + 1 . 00805 * 00806 EMAX = EXPSUM + EMIN - 1 00807 NBITS = 1 + EXBITS + P 00808 * 00809 * NBITS is the total number of bits needed to store a 00810 * floating-point number. 00811 * 00812 IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN 00813 * 00814 * Either there are an odd number of bits used to store a 00815 * floating-point number, which is unlikely, or some bits are 00816 * not used in the representation of numbers, which is possible, 00817 * (e.g. Cray machines) or the mantissa has an implicit bit, 00818 * (e.g. IEEE machines, Dec Vax machines), which is perhaps the 00819 * most likely. We have to assume the last alternative. 00820 * If this is true, then we need to reduce EMAX by one because 00821 * there must be some way of representing zero in an implicit-bit 00822 * system. On machines like Cray, we are reducing EMAX by one 00823 * unnecessarily. 00824 * 00825 EMAX = EMAX - 1 00826 END IF 00827 * 00828 IF( IEEE ) THEN 00829 * 00830 * Assume we are on an IEEE machine which reserves one exponent 00831 * for infinity and NaN. 00832 * 00833 EMAX = EMAX - 1 00834 END IF 00835 * 00836 * Now create RMAX, the largest machine number, which should 00837 * be equal to (1.0 - BETA**(-P)) * BETA**EMAX . 00838 * 00839 * First compute 1.0 - BETA**(-P), being careful that the 00840 * result is less than 1.0 . 00841 * 00842 RECBAS = ONE / BETA 00843 Z = BETA - ONE 00844 Y = ZERO 00845 DO 20 I = 1, P 00846 Z = Z*RECBAS 00847 IF( Y.LT.ONE ) 00848 $ OLDY = Y 00849 Y = DLAMC3( Y, Z ) 00850 20 CONTINUE 00851 IF( Y.GE.ONE ) 00852 $ Y = OLDY 00853 * 00854 * Now multiply by BETA**EMAX to get RMAX. 00855 * 00856 DO 30 I = 1, EMAX 00857 Y = DLAMC3( Y*BETA, ZERO ) 00858 30 CONTINUE 00859 * 00860 RMAX = Y 00861 RETURN 00862 * 00863 * End of DLAMC5 00864 * 00865 END 00866 REAL FUNCTION SLAMCH( CMACH ) 00867 * 00868 * -- LAPACK auxiliary routine (version 2.0) -- 00869 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 00870 * Courant Institute, Argonne National Lab, and Rice University 00871 * October 31, 1992 00872 * 00873 * .. Scalar Arguments .. 00874 CHARACTER CMACH 00875 * .. 00876 * 00877 * Purpose 00878 * ======= 00879 * 00880 * SLAMCH determines single precision machine parameters. 00881 * 00882 * Arguments 00883 * ========= 00884 * 00885 * CMACH (input) CHARACTER*1 00886 * Specifies the value to be returned by SLAMCH: 00887 * = 'E' or 'e', SLAMCH := eps 00888 * = 'S' or 's , SLAMCH := sfmin 00889 * = 'B' or 'b', SLAMCH := base 00890 * = 'P' or 'p', SLAMCH := eps*base 00891 * = 'N' or 'n', SLAMCH := t 00892 * = 'R' or 'r', SLAMCH := rnd 00893 * = 'M' or 'm', SLAMCH := emin 00894 * = 'U' or 'u', SLAMCH := rmin 00895 * = 'L' or 'l', SLAMCH := emax 00896 * = 'O' or 'o', SLAMCH := rmax 00897 * 00898 * where 00899 * 00900 * eps = relative machine precision 00901 * sfmin = safe minimum, such that 1/sfmin does not overflow 00902 * base = base of the machine 00903 * prec = eps*base 00904 * t = number of (base) digits in the mantissa 00905 * rnd = 1.0 when rounding occurs in addition, 0.0 otherwise 00906 * emin = minimum exponent before (gradual) underflow 00907 * rmin = underflow threshold - base**(emin-1) 00908 * emax = largest exponent before overflow 00909 * rmax = overflow threshold - (base**emax)*(1-eps) 00910 * 00911 * ===================================================================== 00912 * 00913 * .. Parameters .. 00914 REAL ONE, ZERO 00915 PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 ) 00916 * .. 00917 * .. Local Scalars .. 00918 LOGICAL FIRST, LRND 00919 INTEGER BETA, IMAX, IMIN, IT 00920 REAL BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN, 00921 $ RND, SFMIN, SMALL, T 00922 * .. 00923 * .. External Functions .. 00924 LOGICAL LSAME 00925 EXTERNAL LSAME 00926 * .. 00927 * .. External Subroutines .. 00928 EXTERNAL SLAMC2 00929 * .. 00930 * .. Save statement .. 00931 SAVE FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN, 00932 $ EMAX, RMAX, PREC 00933 * .. 00934 * .. Data statements .. 00935 DATA FIRST / .TRUE. / 00936 * .. 00937 * .. Executable Statements .. 00938 * 00939 IF( FIRST ) THEN 00940 FIRST = .FALSE. 00941 CALL SLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX ) 00942 BASE = BETA 00943 T = IT 00944 IF( LRND ) THEN 00945 RND = ONE 00946 EPS = ( BASE**( 1-IT ) ) / 2 00947 ELSE 00948 RND = ZERO 00949 EPS = BASE**( 1-IT ) 00950 END IF 00951 PREC = EPS*BASE 00952 EMIN = IMIN 00953 EMAX = IMAX 00954 SFMIN = RMIN 00955 SMALL = ONE / RMAX 00956 IF( SMALL.GE.SFMIN ) THEN 00957 * 00958 * Use SMALL plus a bit, to avoid the possibility of rounding 00959 * causing overflow when computing 1/sfmin. 00960 * 00961 SFMIN = SMALL*( ONE+EPS ) 00962 END IF 00963 END IF 00964 * 00965 IF( LSAME( CMACH, 'E' ) ) THEN 00966 RMACH = EPS 00967 ELSE IF( LSAME( CMACH, 'S' ) ) THEN 00968 RMACH = SFMIN 00969 ELSE IF( LSAME( CMACH, 'B' ) ) THEN 00970 RMACH = BASE 00971 ELSE IF( LSAME( CMACH, 'P' ) ) THEN 00972 RMACH = PREC 00973 ELSE IF( LSAME( CMACH, 'N' ) ) THEN 00974 RMACH = T 00975 ELSE IF( LSAME( CMACH, 'R' ) ) THEN 00976 RMACH = RND 00977 ELSE IF( LSAME( CMACH, 'M' ) ) THEN 00978 RMACH = EMIN 00979 ELSE IF( LSAME( CMACH, 'U' ) ) THEN 00980 RMACH = RMIN 00981 ELSE IF( LSAME( CMACH, 'L' ) ) THEN 00982 RMACH = EMAX 00983 ELSE IF( LSAME( CMACH, 'O' ) ) THEN 00984 RMACH = RMAX 00985 END IF 00986 * 00987 SLAMCH = RMACH 00988 RETURN 00989 * 00990 * End of SLAMCH 00991 * 00992 END 00993 * 00994 ************************************************************************ 00995 * 00996 SUBROUTINE SLAMC1( BETA, T, RND, IEEE1 ) 00997 * 00998 * -- LAPACK auxiliary routine (version 2.0) -- 00999 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 01000 * Courant Institute, Argonne National Lab, and Rice University 01001 * October 31, 1992 01002 * 01003 * .. Scalar Arguments .. 01004 LOGICAL IEEE1, RND 01005 INTEGER BETA, T 01006 * .. 01007 * 01008 * Purpose 01009 * ======= 01010 * 01011 * SLAMC1 determines the machine parameters given by BETA, T, RND, and 01012 * IEEE1. 01013 * 01014 * Arguments 01015 * ========= 01016 * 01017 * BETA (output) INTEGER 01018 * The base of the machine. 01019 * 01020 * T (output) INTEGER 01021 * The number of ( BETA ) digits in the mantissa. 01022 * 01023 * RND (output) LOGICAL 01024 * Specifies whether proper rounding ( RND = .TRUE. ) or 01025 * chopping ( RND = .FALSE. ) occurs in addition. This may not 01026 * be a reliable guide to the way in which the machine performs 01027 * its arithmetic. 01028 * 01029 * IEEE1 (output) LOGICAL 01030 * Specifies whether rounding appears to be done in the IEEE 01031 * 'round to nearest' style. 01032 * 01033 * Further Details 01034 * =============== 01035 * 01036 * The routine is based on the routine ENVRON by Malcolm and 01037 * incorporates suggestions by Gentleman and Marovich. See 01038 * 01039 * Malcolm M. A. (1972) Algorithms to reveal properties of 01040 * floating-point arithmetic. Comms. of the ACM, 15, 949-951. 01041 * 01042 * Gentleman W. M. and Marovich S. B. (1974) More on algorithms 01043 * that reveal properties of floating point arithmetic units. 01044 * Comms. of the ACM, 17, 276-277. 01045 * 01046 * ===================================================================== 01047 * 01048 * .. Local Scalars .. 01049 LOGICAL FIRST, LIEEE1, LRND 01050 INTEGER LBETA, LT 01051 REAL A, B, C, F, ONE, QTR, SAVEC, T1, T2 01052 * .. 01053 * .. External Functions .. 01054 REAL SLAMC3 01055 EXTERNAL SLAMC3 01056 * .. 01057 * .. Save statement .. 01058 SAVE FIRST, LIEEE1, LBETA, LRND, LT 01059 * .. 01060 * .. Data statements .. 01061 DATA FIRST / .TRUE. / 01062 * .. 01063 * .. Executable Statements .. 01064 * 01065 IF( FIRST ) THEN 01066 FIRST = .FALSE. 01067 ONE = 1 01068 * 01069 * LBETA, LIEEE1, LT and LRND are the local values of BETA, 01070 * IEEE1, T and RND. 01071 * 01072 * Throughout this routine we use the function SLAMC3 to ensure 01073 * that relevant values are stored and not held in registers, or 01074 * are not affected by optimizers. 01075 * 01076 * Compute a = 2.0**m with the smallest positive integer m such 01077 * that 01078 * 01079 * fl( a + 1.0 ) = a. 01080 * 01081 A = 1 01082 C = 1 01083 * 01084 *+ WHILE( C.EQ.ONE )LOOP 01085 10 CONTINUE 01086 IF( C.EQ.ONE ) THEN 01087 A = 2*A 01088 C = SLAMC3( A, ONE ) 01089 C = SLAMC3( C, -A ) 01090 GO TO 10 01091 END IF 01092 *+ END WHILE 01093 * 01094 * Now compute b = 2.0**m with the smallest positive integer m 01095 * such that 01096 * 01097 * fl( a + b ) .gt. a. 01098 * 01099 B = 1 01100 C = SLAMC3( A, B ) 01101 * 01102 *+ WHILE( C.EQ.A )LOOP 01103 20 CONTINUE 01104 IF( C.EQ.A ) THEN 01105 B = 2*B 01106 C = SLAMC3( A, B ) 01107 GO TO 20 01108 END IF 01109 *+ END WHILE 01110 * 01111 * Now compute the base. a and c are neighbouring floating point 01112 * numbers in the interval ( beta**t, beta**( t + 1 ) ) and so 01113 * their difference is beta. Adding 0.25 to c is to ensure that it 01114 * is truncated to beta and not ( beta - 1 ). 01115 * 01116 QTR = ONE / 4 01117 SAVEC = C 01118 C = SLAMC3( C, -A ) 01119 LBETA = C + QTR 01120 * 01121 * Now determine whether rounding or chopping occurs, by adding a 01122 * bit less than beta/2 and a bit more than beta/2 to a. 01123 * 01124 B = LBETA 01125 F = SLAMC3( B / 2, -B / 100 ) 01126 C = SLAMC3( F, A ) 01127 IF( C.EQ.A ) THEN 01128 LRND = .TRUE. 01129 ELSE 01130 LRND = .FALSE. 01131 END IF 01132 F = SLAMC3( B / 2, B / 100 ) 01133 C = SLAMC3( F, A ) 01134 IF( ( LRND ) .AND. ( C.EQ.A ) ) 01135 $ LRND = .FALSE. 01136 * 01137 * Try and decide whether rounding is done in the IEEE 'round to 01138 * nearest' style. B/2 is half a unit in the last place of the two 01139 * numbers A and SAVEC. Furthermore, A is even, i.e. has last bit 01140 * zero, and SAVEC is odd. Thus adding B/2 to A should not change 01141 * A, but adding B/2 to SAVEC should change SAVEC. 01142 * 01143 T1 = SLAMC3( B / 2, A ) 01144 T2 = SLAMC3( B / 2, SAVEC ) 01145 LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND 01146 * 01147 * Now find the mantissa, t. It should be the integer part of 01148 * log to the base beta of a, however it is safer to determine t 01149 * by powering. So we find t as the smallest positive integer for 01150 * which 01151 * 01152 * fl( beta**t + 1.0 ) = 1.0. 01153 * 01154 LT = 0 01155 A = 1 01156 C = 1 01157 * 01158 *+ WHILE( C.EQ.ONE )LOOP 01159 30 CONTINUE 01160 IF( C.EQ.ONE ) THEN 01161 LT = LT + 1 01162 A = A*LBETA 01163 C = SLAMC3( A, ONE ) 01164 C = SLAMC3( C, -A ) 01165 GO TO 30 01166 END IF 01167 *+ END WHILE 01168 * 01169 END IF 01170 * 01171 BETA = LBETA 01172 T = LT 01173 RND = LRND 01174 IEEE1 = LIEEE1 01175 RETURN 01176 * 01177 * End of SLAMC1 01178 * 01179 END 01180 * 01181 ************************************************************************ 01182 * 01183 SUBROUTINE SLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX ) 01184 * 01185 * -- LAPACK auxiliary routine (version 2.0) -- 01186 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 01187 * Courant Institute, Argonne National Lab, and Rice University 01188 * October 31, 1992 01189 * 01190 * .. Scalar Arguments .. 01191 LOGICAL RND 01192 INTEGER BETA, EMAX, EMIN, T 01193 REAL EPS, RMAX, RMIN 01194 * .. 01195 * 01196 * Purpose 01197 * ======= 01198 * 01199 * SLAMC2 determines the machine parameters specified in its argument 01200 * list. 01201 * 01202 * Arguments 01203 * ========= 01204 * 01205 * BETA (output) INTEGER 01206 * The base of the machine. 01207 * 01208 * T (output) INTEGER 01209 * The number of ( BETA ) digits in the mantissa. 01210 * 01211 * RND (output) LOGICAL 01212 * Specifies whether proper rounding ( RND = .TRUE. ) or 01213 * chopping ( RND = .FALSE. ) occurs in addition. This may not 01214 * be a reliable guide to the way in which the machine performs 01215 * its arithmetic. 01216 * 01217 * EPS (output) REAL 01218 * The smallest positive number such that 01219 * 01220 * fl( 1.0 - EPS ) .LT. 1.0, 01221 * 01222 * where fl denotes the computed value. 01223 * 01224 * EMIN (output) INTEGER 01225 * The minimum exponent before (gradual) underflow occurs. 01226 * 01227 * RMIN (output) REAL 01228 * The smallest normalized number for the machine, given by 01229 * BASE**( EMIN - 1 ), where BASE is the floating point value 01230 * of BETA. 01231 * 01232 * EMAX (output) INTEGER 01233 * The maximum exponent before overflow occurs. 01234 * 01235 * RMAX (output) REAL 01236 * The largest positive number for the machine, given by 01237 * BASE**EMAX * ( 1 - EPS ), where BASE is the floating point 01238 * value of BETA. 01239 * 01240 * Further Details 01241 * =============== 01242 * 01243 * The computation of EPS is based on a routine PARANOIA by 01244 * W. Kahan of the University of California at Berkeley. 01245 * 01246 * ===================================================================== 01247 * 01248 * .. Local Scalars .. 01249 LOGICAL FIRST, IEEE, IWARN, LIEEE1, LRND 01250 INTEGER GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT, 01251 $ NGNMIN, NGPMIN 01252 REAL A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE, 01253 $ SIXTH, SMALL, THIRD, TWO, ZERO 01254 * .. 01255 * .. External Functions .. 01256 REAL SLAMC3 01257 EXTERNAL SLAMC3 01258 * .. 01259 * .. External Subroutines .. 01260 EXTERNAL SLAMC1, SLAMC4, SLAMC5 01261 * .. 01262 * .. Intrinsic Functions .. 01263 INTRINSIC ABS, MAX, MIN 01264 * .. 01265 * .. Save statement .. 01266 SAVE FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX, 01267 $ LRMIN, LT 01268 * .. 01269 * .. Data statements .. 01270 DATA FIRST / .TRUE. / , IWARN / .FALSE. / 01271 * .. 01272 * .. Executable Statements .. 01273 * 01274 IF( FIRST ) THEN 01275 FIRST = .FALSE. 01276 ZERO = 0 01277 ONE = 1 01278 TWO = 2 01279 * 01280 * LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of 01281 * BETA, T, RND, EPS, EMIN and RMIN. 01282 * 01283 * Throughout this routine we use the function SLAMC3 to ensure 01284 * that relevant values are stored and not held in registers, or 01285 * are not affected by optimizers. 01286 * 01287 * SLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1. 01288 * 01289 CALL SLAMC1( LBETA, LT, LRND, LIEEE1 ) 01290 * 01291 * Start to find EPS. 01292 * 01293 B = LBETA 01294 A = B**( -LT ) 01295 LEPS = A 01296 * 01297 * Try some tricks to see whether or not this is the correct EPS. 01298 * 01299 B = TWO / 3 01300 HALF = ONE / 2 01301 SIXTH = SLAMC3( B, -HALF ) 01302 THIRD = SLAMC3( SIXTH, SIXTH ) 01303 B = SLAMC3( THIRD, -HALF ) 01304 B = SLAMC3( B, SIXTH ) 01305 B = ABS( B ) 01306 IF( B.LT.LEPS ) 01307 $ B = LEPS 01308 * 01309 LEPS = 1 01310 * 01311 *+ WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP 01312 10 CONTINUE 01313 IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN 01314 LEPS = B 01315 C = SLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) ) 01316 C = SLAMC3( HALF, -C ) 01317 B = SLAMC3( HALF, C ) 01318 C = SLAMC3( HALF, -B ) 01319 B = SLAMC3( HALF, C ) 01320 GO TO 10 01321 END IF 01322 *+ END WHILE 01323 * 01324 IF( A.LT.LEPS ) 01325 $ LEPS = A 01326 * 01327 * Computation of EPS complete. 01328 * 01329 * Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)). 01330 * Keep dividing A by BETA until (gradual) underflow occurs. This 01331 * is detected when we cannot recover the previous A. 01332 * 01333 RBASE = ONE / LBETA 01334 SMALL = ONE 01335 DO 20 I = 1, 3 01336 SMALL = SLAMC3( SMALL*RBASE, ZERO ) 01337 20 CONTINUE 01338 A = SLAMC3( ONE, SMALL ) 01339 CALL SLAMC4( NGPMIN, ONE, LBETA ) 01340 CALL SLAMC4( NGNMIN, -ONE, LBETA ) 01341 CALL SLAMC4( GPMIN, A, LBETA ) 01342 CALL SLAMC4( GNMIN, -A, LBETA ) 01343 IEEE = .FALSE. 01344 * 01345 IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN 01346 IF( NGPMIN.EQ.GPMIN ) THEN 01347 LEMIN = NGPMIN 01348 * ( Non twos-complement machines, no gradual underflow; 01349 * e.g., VAX ) 01350 ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN 01351 LEMIN = NGPMIN - 1 + LT 01352 IEEE = .TRUE. 01353 * ( Non twos-complement machines, with gradual underflow; 01354 * e.g., IEEE standard followers ) 01355 ELSE 01356 LEMIN = MIN( NGPMIN, GPMIN ) 01357 * ( A guess; no known machine ) 01358 IWARN = .TRUE. 01359 END IF 01360 * 01361 ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN 01362 IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN 01363 LEMIN = MAX( NGPMIN, NGNMIN ) 01364 * ( Twos-complement machines, no gradual underflow; 01365 * e.g., CYBER 205 ) 01366 ELSE 01367 LEMIN = MIN( NGPMIN, NGNMIN ) 01368 * ( A guess; no known machine ) 01369 IWARN = .TRUE. 01370 END IF 01371 * 01372 ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND. 01373 $ ( GPMIN.EQ.GNMIN ) ) THEN 01374 IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN 01375 LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT 01376 * ( Twos-complement machines with gradual underflow; 01377 * no known machine ) 01378 ELSE 01379 LEMIN = MIN( NGPMIN, NGNMIN ) 01380 * ( A guess; no known machine ) 01381 IWARN = .TRUE. 01382 END IF 01383 * 01384 ELSE 01385 LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN ) 01386 * ( A guess; no known machine ) 01387 IWARN = .TRUE. 01388 END IF 01389 *** 01390 * Comment out this if block if EMIN is ok 01391 IF( IWARN ) THEN 01392 FIRST = .TRUE. 01393 WRITE( 6, FMT = 9999 )LEMIN 01394 END IF 01395 *** 01396 * 01397 * Assume IEEE arithmetic if we found denormalised numbers above, 01398 * or if arithmetic seems to round in the IEEE style, determined 01399 * in routine SLAMC1. A true IEEE machine should have both things 01400 * true; however, faulty machines may have one or the other. 01401 * 01402 IEEE = IEEE .OR. LIEEE1 01403 * 01404 * Compute RMIN by successive division by BETA. We could compute 01405 * RMIN as BASE**( EMIN - 1 ), but some machines underflow during 01406 * this computation. 01407 * 01408 LRMIN = 1 01409 DO 30 I = 1, 1 - LEMIN 01410 LRMIN = SLAMC3( LRMIN*RBASE, ZERO ) 01411 30 CONTINUE 01412 * 01413 * Finally, call SLAMC5 to compute EMAX and RMAX. 01414 * 01415 CALL SLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX ) 01416 END IF 01417 * 01418 BETA = LBETA 01419 T = LT 01420 RND = LRND 01421 EPS = LEPS 01422 EMIN = LEMIN 01423 RMIN = LRMIN 01424 EMAX = LEMAX 01425 RMAX = LRMAX 01426 * 01427 RETURN 01428 * 01429 9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-', 01430 $ ' EMIN = ', I8, / 01431 $ ' If, after inspection, the value EMIN looks', 01432 $ ' acceptable please comment out ', 01433 $ / ' the IF block as marked within the code of routine', 01434 $ ' SLAMC2,', / ' otherwise supply EMIN explicitly.', / ) 01435 * 01436 * End of SLAMC2 01437 * 01438 END 01439 * 01440 ************************************************************************ 01441 * 01442 REAL FUNCTION SLAMC3( A, B ) 01443 * 01444 * -- LAPACK auxiliary routine (version 2.0) -- 01445 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 01446 * Courant Institute, Argonne National Lab, and Rice University 01447 * October 31, 1992 01448 * 01449 * .. Scalar Arguments .. 01450 REAL A, B 01451 * .. 01452 * 01453 * Purpose 01454 * ======= 01455 * 01456 * SLAMC3 is intended to force A and B to be stored prior to doing 01457 * the addition of A and B , for use in situations where optimizers 01458 * might hold one of these in a register. 01459 * 01460 * Arguments 01461 * ========= 01462 * 01463 * A, B (input) REAL 01464 * The values A and B. 01465 * 01466 * ===================================================================== 01467 * 01468 * .. Executable Statements .. 01469 * 01470 SLAMC3 = A + B 01471 * 01472 RETURN 01473 * 01474 * End of SLAMC3 01475 * 01476 END 01477 * 01478 ************************************************************************ 01479 * 01480 SUBROUTINE SLAMC4( EMIN, START, BASE ) 01481 * 01482 * -- LAPACK auxiliary routine (version 2.0) -- 01483 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 01484 * Courant Institute, Argonne National Lab, and Rice University 01485 * October 31, 1992 01486 * 01487 * .. Scalar Arguments .. 01488 INTEGER BASE, EMIN 01489 REAL START 01490 * .. 01491 * 01492 * Purpose 01493 * ======= 01494 * 01495 * SLAMC4 is a service routine for SLAMC2. 01496 * 01497 * Arguments 01498 * ========= 01499 * 01500 * EMIN (output) EMIN 01501 * The minimum exponent before (gradual) underflow, computed by 01502 * setting A = START and dividing by BASE until the previous A 01503 * can not be recovered. 01504 * 01505 * START (input) REAL 01506 * The starting point for determining EMIN. 01507 * 01508 * BASE (input) INTEGER 01509 * The base of the machine. 01510 * 01511 * ===================================================================== 01512 * 01513 * .. Local Scalars .. 01514 INTEGER I 01515 REAL A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO 01516 * .. 01517 * .. External Functions .. 01518 REAL SLAMC3 01519 EXTERNAL SLAMC3 01520 * .. 01521 * .. Executable Statements .. 01522 * 01523 A = START 01524 ONE = 1 01525 RBASE = ONE / BASE 01526 ZERO = 0 01527 EMIN = 1 01528 B1 = SLAMC3( A*RBASE, ZERO ) 01529 C1 = A 01530 C2 = A 01531 D1 = A 01532 D2 = A 01533 *+ WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND. 01534 * $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP 01535 10 CONTINUE 01536 IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND. 01537 $ ( D2.EQ.A ) ) THEN 01538 EMIN = EMIN - 1 01539 A = B1 01540 B1 = SLAMC3( A / BASE, ZERO ) 01541 C1 = SLAMC3( B1*BASE, ZERO ) 01542 D1 = ZERO 01543 DO 20 I = 1, BASE 01544 D1 = D1 + B1 01545 20 CONTINUE 01546 B2 = SLAMC3( A*RBASE, ZERO ) 01547 C2 = SLAMC3( B2 / RBASE, ZERO ) 01548 D2 = ZERO 01549 DO 30 I = 1, BASE 01550 D2 = D2 + B2 01551 30 CONTINUE 01552 GO TO 10 01553 END IF 01554 *+ END WHILE 01555 * 01556 RETURN 01557 * 01558 * End of SLAMC4 01559 * 01560 END 01561 * 01562 ************************************************************************ 01563 * 01564 SUBROUTINE SLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX ) 01565 * 01566 * -- LAPACK auxiliary routine (version 2.0) -- 01567 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 01568 * Courant Institute, Argonne National Lab, and Rice University 01569 * October 31, 1992 01570 * 01571 * .. Scalar Arguments .. 01572 LOGICAL IEEE 01573 INTEGER BETA, EMAX, EMIN, P 01574 REAL RMAX 01575 * .. 01576 * 01577 * Purpose 01578 * ======= 01579 * 01580 * SLAMC5 attempts to compute RMAX, the largest machine floating-point 01581 * number, without overflow. It assumes that EMAX + abs(EMIN) sum 01582 * approximately to a power of 2. It will fail on machines where this 01583 * assumption does not hold, for example, the Cyber 205 (EMIN = -28625, 01584 * EMAX = 28718). It will also fail if the value supplied for EMIN is 01585 * too large (i.e. too close to zero), probably with overflow. 01586 * 01587 * Arguments 01588 * ========= 01589 * 01590 * BETA (input) INTEGER 01591 * The base of floating-point arithmetic. 01592 * 01593 * P (input) INTEGER 01594 * The number of base BETA digits in the mantissa of a 01595 * floating-point value. 01596 * 01597 * EMIN (input) INTEGER 01598 * The minimum exponent before (gradual) underflow. 01599 * 01600 * IEEE (input) LOGICAL 01601 * A logical flag specifying whether or not the arithmetic 01602 * system is thought to comply with the IEEE standard. 01603 * 01604 * EMAX (output) INTEGER 01605 * The largest exponent before overflow 01606 * 01607 * RMAX (output) REAL 01608 * The largest machine floating-point number. 01609 * 01610 * ===================================================================== 01611 * 01612 * .. Parameters .. 01613 REAL ZERO, ONE 01614 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 ) 01615 * .. 01616 * .. Local Scalars .. 01617 INTEGER EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP 01618 REAL OLDY, RECBAS, Y, Z 01619 * .. 01620 * .. External Functions .. 01621 REAL SLAMC3 01622 EXTERNAL SLAMC3 01623 * .. 01624 * .. Intrinsic Functions .. 01625 INTRINSIC MOD 01626 * .. 01627 * .. Executable Statements .. 01628 * 01629 * First compute LEXP and UEXP, two powers of 2 that bound 01630 * abs(EMIN). We then assume that EMAX + abs(EMIN) will sum 01631 * approximately to the bound that is closest to abs(EMIN). 01632 * (EMAX is the exponent of the required number RMAX). 01633 * 01634 LEXP = 1 01635 EXBITS = 1 01636 10 CONTINUE 01637 TRY = LEXP*2 01638 IF( TRY.LE.( -EMIN ) ) THEN 01639 LEXP = TRY 01640 EXBITS = EXBITS + 1 01641 GO TO 10 01642 END IF 01643 IF( LEXP.EQ.-EMIN ) THEN 01644 UEXP = LEXP 01645 ELSE 01646 UEXP = TRY 01647 EXBITS = EXBITS + 1 01648 END IF 01649 * 01650 * Now -LEXP is less than or equal to EMIN, and -UEXP is greater 01651 * than or equal to EMIN. EXBITS is the number of bits needed to 01652 * store the exponent. 01653 * 01654 IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN 01655 EXPSUM = 2*LEXP 01656 ELSE 01657 EXPSUM = 2*UEXP 01658 END IF 01659 * 01660 * EXPSUM is the exponent range, approximately equal to 01661 * EMAX - EMIN + 1 . 01662 * 01663 EMAX = EXPSUM + EMIN - 1 01664 NBITS = 1 + EXBITS + P 01665 * 01666 * NBITS is the total number of bits needed to store a 01667 * floating-point number. 01668 * 01669 IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN 01670 * 01671 * Either there are an odd number of bits used to store a 01672 * floating-point number, which is unlikely, or some bits are 01673 * not used in the representation of numbers, which is possible, 01674 * (e.g. Cray machines) or the mantissa has an implicit bit, 01675 * (e.g. IEEE machines, Dec Vax machines), which is perhaps the 01676 * most likely. We have to assume the last alternative. 01677 * If this is true, then we need to reduce EMAX by one because 01678 * there must be some way of representing zero in an implicit-bit 01679 * system. On machines like Cray, we are reducing EMAX by one 01680 * unnecessarily. 01681 * 01682 EMAX = EMAX - 1 01683 END IF 01684 * 01685 IF( IEEE ) THEN 01686 * 01687 * Assume we are on an IEEE machine which reserves one exponent 01688 * for infinity and NaN. 01689 * 01690 EMAX = EMAX - 1 01691 END IF 01692 * 01693 * Now create RMAX, the largest machine number, which should 01694 * be equal to (1.0 - BETA**(-P)) * BETA**EMAX . 01695 * 01696 * First compute 1.0 - BETA**(-P), being careful that the 01697 * result is less than 1.0 . 01698 * 01699 RECBAS = ONE / BETA 01700 Z = BETA - ONE 01701 Y = ZERO 01702 DO 20 I = 1, P 01703 Z = Z*RECBAS 01704 IF( Y.LT.ONE ) 01705 $ OLDY = Y 01706 Y = SLAMC3( Y, Z ) 01707 20 CONTINUE 01708 IF( Y.GE.ONE ) 01709 $ Y = OLDY 01710 * 01711 * Now multiply by BETA**EMAX to get RMAX. 01712 * 01713 DO 30 I = 1, EMAX 01714 Y = SLAMC3( Y*BETA, ZERO ) 01715 30 CONTINUE 01716 * 01717 RMAX = Y 01718 RETURN 01719 * 01720 * End of SLAMC5 01721 * 01722 END 01723 LOGICAL FUNCTION LSAME( CA, CB ) 01724 * 01725 * -- LAPACK auxiliary routine (version 2.0) -- 01726 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 01727 * Courant Institute, Argonne National Lab, and Rice University 01728 * June 30, 1994 01729 * 01730 * .. Scalar Arguments .. 01731 CHARACTER CA, CB 01732 * .. 01733 * 01734 * Purpose 01735 * ======= 01736 * 01737 * LSAME returns .TRUE. if CA is the same letter as CB regardless of 01738 * case. 01739 * 01740 * Arguments 01741 * ========= 01742 * 01743 * CA (input) CHARACTER*1 01744 * CB (input) CHARACTER*1 01745 * CA and CB specify the single characters to be compared. 01746 * 01747 * ===================================================================== 01748 * 01749 * .. Intrinsic Functions .. 01750 INTRINSIC ICHAR 01751 * .. 01752 * .. Local Scalars .. 01753 INTEGER INTA, INTB, ZCODE 01754 * .. 01755 * .. Executable Statements .. 01756 * 01757 * Test if the characters are equal 01758 * 01759 LSAME = CA.EQ.CB 01760 IF( LSAME ) 01761 $ RETURN 01762 * 01763 * Now test for equivalence if both characters are alphabetic. 01764 * 01765 ZCODE = ICHAR( 'Z' ) 01766 * 01767 * Use 'Z' rather than 'A' so that ASCII can be detected on Prime 01768 * machines, on which ICHAR returns a value with bit 8 set. 01769 * ICHAR('A') on Prime machines returns 193 which is the same as 01770 * ICHAR('A') on an EBCDIC machine. 01771 * 01772 INTA = ICHAR( CA ) 01773 INTB = ICHAR( CB ) 01774 * 01775 IF( ZCODE.EQ.90 .OR. ZCODE.EQ.122 ) THEN 01776 * 01777 * ASCII is assumed - ZCODE is the ASCII code of either lower or 01778 * upper case 'Z'. 01779 * 01780 IF( INTA.GE.97 .AND. INTA.LE.122 ) INTA = INTA - 32 01781 IF( INTB.GE.97 .AND. INTB.LE.122 ) INTB = INTB - 32 01782 * 01783 ELSE IF( ZCODE.EQ.233 .OR. ZCODE.EQ.169 ) THEN 01784 * 01785 * EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or 01786 * upper case 'Z'. 01787 * 01788 IF( INTA.GE.129 .AND. INTA.LE.137 .OR. 01789 $ INTA.GE.145 .AND. INTA.LE.153 .OR. 01790 $ INTA.GE.162 .AND. INTA.LE.169 ) INTA = INTA + 64 01791 IF( INTB.GE.129 .AND. INTB.LE.137 .OR. 01792 $ INTB.GE.145 .AND. INTB.LE.153 .OR. 01793 $ INTB.GE.162 .AND. INTB.LE.169 ) INTB = INTB + 64 01794 * 01795 ELSE IF( ZCODE.EQ.218 .OR. ZCODE.EQ.250 ) THEN 01796 * 01797 * ASCII is assumed, on Prime machines - ZCODE is the ASCII code 01798 * plus 128 of either lower or upper case 'Z'. 01799 * 01800 IF( INTA.GE.225 .AND. INTA.LE.250 ) INTA = INTA - 32 01801 IF( INTB.GE.225 .AND. INTB.LE.250 ) INTB = INTB - 32 01802 END IF 01803 LSAME = INTA.EQ.INTB 01804 * 01805 * RETURN 01806 * 01807 * End of LSAME 01808 * 01809 END 01810 DOUBLE PRECISION FUNCTION DLARND( IDIST, ISEED ) 01811 * 01812 * -- LAPACK auxiliary routine (version 2.0) -- 01813 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 01814 * Courant Institute, Argonne National Lab, and Rice University 01815 * June 30, 1994 01816 * 01817 * .. Scalar Arguments .. 01818 INTEGER IDIST 01819 * .. 01820 * .. Array Arguments .. 01821 INTEGER ISEED( 4 ) 01822 * .. 01823 * 01824 * Purpose 01825 * ======= 01826 * 01827 * DLARND returns a random real number from a uniform or normal 01828 * distribution. 01829 * 01830 * Arguments 01831 * ========= 01832 * 01833 * IDIST (input) INTEGER 01834 * Specifies the distribution of the random numbers: 01835 * = 1: uniform (0,1) 01836 * = 2: uniform (-1,1) 01837 * = 3: normal (0,1) 01838 * 01839 * ISEED (input/output) INTEGER array, dimension (4) 01840 * On entry, the seed of the random number generator; the array 01841 * elements must be between 0 and 4095, and ISEED(4) must be 01842 * odd. 01843 * On exit, the seed is updated. 01844 * 01845 * Further Details 01846 * =============== 01847 * 01848 * This routine calls the auxiliary routine DLARAN to generate a random 01849 * real number from a uniform (0,1) distribution. The Box-Muller method 01850 * is used to transform numbers from a uniform to a normal distribution. 01851 * 01852 * ===================================================================== 01853 * 01854 * .. Parameters .. 01855 DOUBLE PRECISION ONE, TWO 01856 PARAMETER ( ONE = 1.0D+0, TWO = 2.0D+0 ) 01857 DOUBLE PRECISION TWOPI 01858 PARAMETER ( TWOPI = 6.2831853071795864769252867663D+0 ) 01859 * .. 01860 * .. Local Scalars .. 01861 DOUBLE PRECISION T1, T2 01862 * .. 01863 * .. External Functions .. 01864 DOUBLE PRECISION DLARAN 01865 EXTERNAL DLARAN 01866 * .. 01867 * .. Intrinsic Functions .. 01868 INTRINSIC COS, LOG, SQRT 01869 * .. 01870 * .. Executable Statements .. 01871 * 01872 * Generate a real random number from a uniform (0,1) distribution 01873 * 01874 T1 = DLARAN( ISEED ) 01875 * 01876 IF( IDIST.EQ.1 ) THEN 01877 * 01878 * uniform (0,1) 01879 * 01880 DLARND = T1 01881 ELSE IF( IDIST.EQ.2 ) THEN 01882 * 01883 * uniform (-1,1) 01884 * 01885 DLARND = TWO*T1 - ONE 01886 ELSE IF( IDIST.EQ.3 ) THEN 01887 * 01888 * normal (0,1) 01889 * 01890 T2 = DLARAN( ISEED ) 01891 DLARND = SQRT( -TWO*LOG( T1 ) )*COS( TWOPI*T2 ) 01892 END IF 01893 RETURN 01894 * 01895 * End of DLARND 01896 * 01897 END 01898 DOUBLE COMPLEX FUNCTION ZLARND( IDIST, ISEED ) 01899 * 01900 * -- LAPACK auxiliary routine (version 2.0) -- 01901 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 01902 * Courant Institute, Argonne National Lab, and Rice University 01903 * June 30, 1994 01904 * 01905 * .. Scalar Arguments .. 01906 INTEGER IDIST 01907 * .. 01908 * .. Array Arguments .. 01909 INTEGER ISEED( 4 ) 01910 * .. 01911 * 01912 * Purpose 01913 * ======= 01914 * 01915 * ZLARND returns a random complex number from a uniform or normal 01916 * distribution. 01917 * 01918 * Arguments 01919 * ========= 01920 * 01921 * IDIST (input) INTEGER 01922 * Specifies the distribution of the random numbers: 01923 * = 1: real and imaginary parts each uniform (0,1) 01924 * = 2: real and imaginary parts each uniform (-1,1) 01925 * = 3: real and imaginary parts each normal (0,1) 01926 * = 4: uniformly distributed on the disc abs(z) <= 1 01927 * = 5: uniformly distributed on the circle abs(z) = 1 01928 * 01929 * ISEED (input/output) INTEGER array, dimension (4) 01930 * On entry, the seed of the random number generator; the array 01931 * elements must be between 0 and 4095, and ISEED(4) must be 01932 * odd. 01933 * On exit, the seed is updated. 01934 * 01935 * Further Details 01936 * =============== 01937 * 01938 * This routine calls the auxiliary routine DLARAN to generate a random 01939 * real number from a uniform (0,1) distribution. The Box-Muller method 01940 * is used to transform numbers from a uniform to a normal distribution. 01941 * 01942 * ===================================================================== 01943 * 01944 * .. Parameters .. 01945 DOUBLE PRECISION ZERO, ONE, TWO 01946 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 ) 01947 DOUBLE PRECISION TWOPI 01948 PARAMETER ( TWOPI = 6.2831853071795864769252867663D+0 ) 01949 * .. 01950 * .. Local Scalars .. 01951 DOUBLE PRECISION T1, T2 01952 * .. 01953 * .. External Functions .. 01954 DOUBLE PRECISION DLARAN 01955 EXTERNAL DLARAN 01956 * .. 01957 * .. Intrinsic Functions .. 01958 INTRINSIC DCMPLX, EXP, LOG, SQRT 01959 * .. 01960 * .. Executable Statements .. 01961 * 01962 * Generate a pair of real random numbers from a uniform (0,1) 01963 * distribution 01964 * 01965 T1 = DLARAN( ISEED ) 01966 T2 = DLARAN( ISEED ) 01967 * 01968 IF( IDIST.EQ.1 ) THEN 01969 * 01970 * real and imaginary parts each uniform (0,1) 01971 * 01972 ZLARND = DCMPLX( T1, T2 ) 01973 ELSE IF( IDIST.EQ.2 ) THEN 01974 * 01975 * real and imaginary parts each uniform (-1,1) 01976 * 01977 ZLARND = DCMPLX( TWO*T1-ONE, TWO*T2-ONE ) 01978 ELSE IF( IDIST.EQ.3 ) THEN 01979 * 01980 * real and imaginary parts each normal (0,1) 01981 * 01982 ZLARND = SQRT( -TWO*LOG( T1 ) )*EXP( DCMPLX( ZERO, TWOPI*T2 ) ) 01983 ELSE IF( IDIST.EQ.4 ) THEN 01984 * 01985 * uniform distribution on the unit disc abs(z) <= 1 01986 * 01987 ZLARND = SQRT( T1 )*EXP( DCMPLX( ZERO, TWOPI*T2 ) ) 01988 ELSE IF( IDIST.EQ.5 ) THEN 01989 * 01990 * uniform distribution on the unit circle abs(z) = 1 01991 * 01992 ZLARND = EXP( DCMPLX( ZERO, TWOPI*T2 ) ) 01993 END IF 01994 RETURN 01995 * 01996 * End of ZLARND 01997 * 01998 END 01999 DOUBLE PRECISION FUNCTION DLARAN( ISEED ) 02000 * 02001 * -- LAPACK auxiliary routine (version 2.0) -- 02002 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 02003 * Courant Institute, Argonne National Lab, and Rice University 02004 * February 29, 1992 02005 * 02006 * .. Array Arguments .. 02007 INTEGER ISEED( 4 ) 02008 * .. 02009 * 02010 * Purpose 02011 * ======= 02012 * 02013 * DLARAN returns a random real number from a uniform (0,1) 02014 * distribution. 02015 * 02016 * Arguments 02017 * ========= 02018 * 02019 * ISEED (input/output) INTEGER array, dimension (4) 02020 * On entry, the seed of the random number generator; the array 02021 * elements must be between 0 and 4095, and ISEED(4) must be 02022 * odd. 02023 * On exit, the seed is updated. 02024 * 02025 * Further Details 02026 * =============== 02027 * 02028 * This routine uses a multiplicative congruential method with modulus 02029 * 2**48 and multiplier 33952834046453 (see G.S.Fishman, 02030 * 'Multiplicative congruential random number generators with modulus 02031 * 2**b: an exhaustive analysis for b = 32 and a partial analysis for 02032 * b = 48', Math. Comp. 189, pp 331-344, 1990). 02033 * 02034 * 48-bit integers are stored in 4 integer array elements with 12 bits 02035 * per element. Hence the routine is portable across machines with 02036 * integers of 32 bits or more. 02037 * 02038 * ===================================================================== 02039 * 02040 * .. Parameters .. 02041 INTEGER M1, M2, M3, M4 02042 PARAMETER ( M1 = 494, M2 = 322, M3 = 2508, M4 = 2549 ) 02043 DOUBLE PRECISION ONE 02044 PARAMETER ( ONE = 1.0D+0 ) 02045 INTEGER IPW2 02046 DOUBLE PRECISION R 02047 PARAMETER ( IPW2 = 4096, R = ONE / IPW2 ) 02048 * .. 02049 * .. Local Scalars .. 02050 INTEGER IT1, IT2, IT3, IT4 02051 * .. 02052 * .. Intrinsic Functions .. 02053 INTRINSIC DBLE, MOD 02054 * .. 02055 * .. Executable Statements .. 02056 * 02057 * multiply the seed by the multiplier modulo 2**48 02058 * 02059 IT4 = ISEED( 4 )*M4 02060 IT3 = IT4 / IPW2 02061 IT4 = IT4 - IPW2*IT3 02062 IT3 = IT3 + ISEED( 3 )*M4 + ISEED( 4 )*M3 02063 IT2 = IT3 / IPW2 02064 IT3 = IT3 - IPW2*IT2 02065 IT2 = IT2 + ISEED( 2 )*M4 + ISEED( 3 )*M3 + ISEED( 4 )*M2 02066 IT1 = IT2 / IPW2 02067 IT2 = IT2 - IPW2*IT1 02068 IT1 = IT1 + ISEED( 1 )*M4 + ISEED( 2 )*M3 + ISEED( 3 )*M2 + 02069 $ ISEED( 4 )*M1 02070 IT1 = MOD( IT1, IPW2 ) 02071 * 02072 * return updated seed 02073 * 02074 ISEED( 1 ) = IT1 02075 ISEED( 2 ) = IT2 02076 ISEED( 3 ) = IT3 02077 ISEED( 4 ) = IT4 02078 * 02079 * convert 48-bit integer to a real number in the interval (0,1) 02080 * 02081 DLARAN = R*( DBLE( IT1 )+R*( DBLE( IT2 )+R*( DBLE( IT3 )+R* 02082 $ ( DBLE( IT4 ) ) ) ) ) 02083 RETURN 02084 * 02085 * End of DLARAN 02086 * 02087 END