ScaLAPACK  2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
tools.f
Go to the documentation of this file.
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