1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
SUBROUTINE genmn(parm,x,work)
C**********************************************************************
C
C SUBROUTINE GENMN(PARM,X,WORK)
C GENerate Multivariate Normal random deviate
C
C
C Arguments
C
C
C PARM --> Parameters needed to generate multivariate normal
C deviates (MEANV and Cholesky decomposition of
C COVM). Set by a previous call to SETGMN.
C 1 : 1 - size of deviate, P
C 2 : P + 1 - mean vector
C P+2 : P*(P+3)/2 + 1 - upper half of cholesky
C decomposition of cov matrix
C DOUBLE PRECISION PARM(*)
C
C X <-- Vector deviate generated.
C DOUBLE PRECISION X(P)
C
C WORK <--> Scratch array
C DOUBLE PRECISION WORK(P)
C
C
C Method
C
C
C 1) Generate P independent standard normal deviates - Ei ~ N(0,1)
C
C 2) Using Cholesky decomposition find A s.t. trans(A)*A = COVM
C
C 3) trans(A)E + MEANV ~ N(MEANV,COVM)
C
C**********************************************************************
C .. Array Arguments ..
DOUBLE PRECISION parm(*),work(*),x(*)
C ..
C .. Local Scalars ..
DOUBLE PRECISION ae
INTEGER i,icount,j,p
C ..
C .. External Functions ..
DOUBLE PRECISION snorm
EXTERNAL snorm
C ..
C .. Intrinsic Functions ..
INTRINSIC int
C ..
C .. Executable Statements ..
p = int(parm(1))
C
C Generate P independent normal deviates - WORK ~ N(0,1)
C
DO 10,i = 1,p
work(i) = snorm()
10 CONTINUE
DO 30,i = 1,p
C
C PARM (P+2 : P*(P+3)/2 + 1) contains A, the Cholesky
C decomposition of the desired covariance matrix.
C trans(A)(1,1) = PARM(P+2)
C trans(A)(2,1) = PARM(P+3)
C trans(A)(2,2) = PARM(P+2+P)
C trans(A)(3,1) = PARM(P+4)
C trans(A)(3,2) = PARM(P+3+P)
C trans(A)(3,3) = PARM(P+2-1+2P) ...
C
C trans(A)*WORK + MEANV ~ N(MEANV,COVM)
C
icount = 0
ae = 0.0
DO 20,j = 1,i
icount = icount + j - 1
ae = ae + parm(i+ (j-1)*p-icount+p+1)*work(j)
20 CONTINUE
x(i) = ae + parm(i+1)
30 CONTINUE
RETURN
C
END
|