dlarnv.f

          SUBROUTINE DLARNV( IDIST, ISEED, N, X )
    *
    *  -- LAPACK auxiliary routine (version 3.1) --
    *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
    *     November 2006
    *
    *     .. Scalar Arguments ..
          INTEGER            IDIST, N
    *     ..
    *     .. Array Arguments ..
          INTEGER            ISEED( 4 )
          DOUBLE PRECISION   X( * )
    *     ..
    *
    *  Purpose
    *  =======
    *
    *  DLARNV returns a vector of n random real numbers from a uniform or
    *  normal distribution.
    *
    *  Arguments
    *  =========
    *
    *  IDIST   (input) INTEGER
    *          Specifies the distribution of the random numbers:
    *          = 1:  uniform (0,1)
    *          = 2:  uniform (-1,1)
    *          = 3:  normal (0,1)
    *
    *  ISEED   (input/output) INTEGER array, dimension (4)
    *          On entry, the seed of the random number generator; the array
    *          elements must be between 0 and 4095, and ISEED(4) must be
    *          odd.
    *          On exit, the seed is updated.
    *
    *  N       (input) INTEGER
    *          The number of random numbers to be generated.
    *
    *  X       (output) DOUBLE PRECISION array, dimension (N)
    *          The generated random numbers.
    *
    *  Further Details
    *  ===============
    *
    *  This routine calls the auxiliary routine DLARUV to generate random
    *  real numbers from a uniform (0,1) distribution, in batches of up to
    *  128 using vectorisable code. The Box-Muller method is used to
    *  transform numbers from a uniform to a normal distribution.
    *
    *  =====================================================================
    *
    *     .. Parameters ..
          DOUBLE PRECISION   ONE, TWO
          PARAMETER          ( ONE = 1.0D+0, TWO = 2.0D+0 )
          INTEGER            LV
          PARAMETER          ( LV = 128 )
          DOUBLE PRECISION   TWOPI
          PARAMETER          ( TWOPI = 6.2831853071795864769252867663D+0 )
    *     ..
    *     .. Local Scalars ..
          INTEGER            I, IL, IL2, IV
    *     ..
    *     .. Local Arrays ..
          DOUBLE PRECISION   U( LV )
    *     ..
    *     .. Intrinsic Functions ..
          INTRINSIC          COS, LOG, MIN, SQRT
    *     ..
    *     .. External Subroutines ..
          EXTERNAL           DLARUV
    *     ..
    *     .. Executable Statements ..
    *
          DO 40 IV = 1, N, LV / 2
             IL = MIN( LV / 2, N-IV+1 )
             IF( IDIST.EQ.3 ) THEN
                IL2 = 2*IL
             ELSE
                IL2 = IL
             END IF
    *
    *        Call DLARUV to generate IL2 numbers from a uniform (0,1)
    *        distribution (IL2 <= LV)
    *
             CALL DLARUV( ISEED, IL2, U )
    *
             IF( IDIST.EQ.1 ) THEN
    *
    *           Copy generated numbers
    *
                DO 10 I = 1, IL
                   X( IV+I-1 ) = U( I )
       10       CONTINUE
             ELSE IF( IDIST.EQ.2 ) THEN
    *
    *           Convert generated numbers to uniform (-1,1) distribution
    *
                DO 20 I = 1, IL
                   X( IV+I-1 ) = TWO*U( I ) - ONE
       20       CONTINUE
             ELSE IF( IDIST.EQ.3 ) THEN
    *
    *           Convert generated numbers to normal (0,1) distribution
    *
                DO 30 I = 1, IL
                   X( IV+I-1 ) = SQRT( -TWO*LOG( U( 2*I-1 ) ) )*
         $                       COS( TWOPI*U( 2*I ) )
       30       CONTINUE
             END IF
       40 CONTINUE
          RETURN
    *
    *     End of DLARNV
    *
          END