/* spec3d is used to examine random samples from trivariate normal distributions with given eigenvalues and angles of the major eigenvector. In the macro arguments, l1, l2, and l3 are the eigenvalues ordered from largest to smallest. Theta1 and theta2 are the angles (in radians) from the positive x axis and positive z axis in spherical coordinates for the eigenvector associated with the largest eigenvalue. The eigenvalues l1, l2, and l3 must be nonnegative. Theta1 and theta2 should satisfy 0 < theta1, theta2 < pi = 3.14159265 n is the sample size of the random sample. */ %macro spec3d(l1,l2,l3,theta1,theta2,n) ; goptions hsize=7.5 vsize =7.5 ; data one ; do i = 1 to &n ; z1 = rannor(0) ; z2 = rannor(0) ; z3 = rannor(0) ; output ; end ; drop i ; run ; *proc print data = one ; proc iml ; x1 = cos(&theta1)*sin(&theta2) ; x2 = sin(&theta1)*sin(&theta2) ; x3 = cos(&theta2) ; *print x1 x2 x3 ; x = x1 // x2 // x3 ; m1 = x*x` ; *print x ; *print m1 ; a = x || {1, 0, 0} || {0, 1, 0} ; print a ; call gsorth( p,t,lindep,a ); /* gsorth performs a Gram-Schmidt orthogonalization of the matrix A. If the return argument lindep is 1, then the matrix A was not of full rank */ print p t lindep ; pr1 = p[,1]*p[,1]` ; *print pr1 ; pr2 = p[,2]*p[,2]` ; *print pr2 ; pr3 = p[,3]*p[,3]` ; *print pr3 ; sig = &l1*pr1 + &l2*pr2 +&l3*pr3 ; print sig ; m2 = half(sig) ; /* The half function performs the Cholesky decomposition of the population covariance matrix SIG */ *print m2 ; pr4 = m2`*m2 ; *print pr4 ; use one ; read all var{z1 z2 z3} into z ; *list all ; y = z*m2 ; *print y ; cname = {y1 y2 y3} ; create two from y[colname=cname] ; append from y ; close two ; call eigen(sigv,sigvec,sig) ; print sigv sigvec ; quit ; * proc print data = two ; run ; proc princomp covariance ; var y1 y2 y3 ; proc g3d ; scatter y1*y2=y3 /rotate = 30 to 120 by 30 ; run ; proc insight data = two ; rotate y1*y2*y3 ; run ; %mend spec3d ; %spec3d(74.1,24.1,1.,1.50,.55,500) ;