/* t Copula (Latin Hypercube version) */ new; cls; rho=0.9; nu=2; /* degree of freedom */ nn=30; /* n~nn^dim */ U=Cth(rho,nu,nn); library pgraph; graphset; _plctrl=-1; xy(U[.,1],U[.,2]); proc Cth(rho,nu,nn); local Sig,A,dim,Z,X2,Y,X,U; Sig=1~rho| rho~1; A=chol(Sig); dim=cols(Sig); Z=cdfni(LHss(nn,dim)); Z=(Z-meanc(Z)')*inv(chol(vcx(Z))); /* This moment match is optional. You could erase. */ X2=rndchisq2(nu,nn^dim); Y=Z*A; X=Y./(sqrt(X2)/sqrt(nu)); U=1-cdftc(X,nu); retp(U); endp; proc rndchisq2(m,nn); local d,i,U,x,index; /* Stratified Sampling(LHS) */ /* divide between 0 and 1 into n segments and sample from each segment */ d=1/nn; U=zeros(nn,1); i=1; do while i<=nn; U[i]=(d*i-d*(i-1))*rndu(1,1)+d*(i-1); i=i+1; endo; /* check if the first element is zero or not */ do while U[1]==0; U[1]=d*rndu(1,1); endo; /* randomize the order */ x=zeros(nn,1); i=1; do while i<=nn-1; index=ceil((nn-(i-1))*rndu(1,1)); x[i]=U[index]; if index==1; U=U[2:rows(U)]; elseif index==rows(U); U=U[1:rows(U)-1]; else; U=U[1:(index-1) (index+1):rows(U)]; endif; i=i+1; endo; x[nn]=U; /* U(0,1) to Gamma(m/2,2) */ x=2*gammaii(m/2*ones(nn,1),x); retp(x); endp; /* ** LHss.txt - Latin Hypercube U(0,1). ** (C) Copyright 2005 Yosuke Amijima. All Rights Reserved. ** ** Purpose: Calculates Latin Hypercube numbers in a very easy way. new algorithm. ** ** Format: x=LHss(nn,dim); ** ** Input: nn scalar, max number of index (1,2,3,...,nn) ** ** dim scalar, dimension (1,...,dim) ** ** ** Output: x matrix , (nn^dim) x (dim) of resulting U(0,1) numbers ** ** Notice: It takes lots of memory to run. Light version of GAUSS will not work in most cases. */ proc LHss(nn,dim); local x,b,n,z,y,indexvec,d,U,i,index; /* convert x(base 10) to y(base b) */ x=seqa(1,1,nn^dim-1); b=nn; n=maxc(log(x)/log(b))+1; z=reshape(b,n,rows(x)); y=rev(recserrc(x,z))'; indexvec=y+1; /* shift all elements by 1 */ indexvec=ones(1,dim)|indexvec; /* insert 1's at the 1st row */ /* divide between 0 and 1 into nn segments and sample from each segment */ d=1/nn; U=(d*indexvec-d*(indexvec-1)).*rndu(nn^dim,dim)+d*(indexvec-1); do while NOT(U>0); /* check if U contains 0's */ U=(d*indexvec-d*(indexvec-1)).*rndu(nn^dim,dim)+d*(indexvec-1); endo; /* randomize the order as a row */ x=zeros(nn^dim,dim); i=1; do while i<=nn^dim-1; index=ceil((nn^dim-(i-1))*rndu(1,1)); x[i,.]=U[index,.]; if index==1; U=U[2:rows(U),.]; elseif index==rows(U); U=U[1:rows(U)-1,.]; else; U=U[1:(index-1) (index+1):rows(U),.]; endif; i=i+1; endo; x[nn^dim,.]=U; retp(x); endp;