It follows a code that I have developed during some other works. It generates !size series randomly distributed according to a multivariate normal with the covariance matrix also generated randomly. This may be changed to generate according to the desired covariance matrix. Just make sure that the cov. matrix is positive semi-definite.
It might be useful for some...
Cheers!
Code: Select all
!size=3
matrix(!size,!size) rnd_covs
call rnd_pos_def_mat(rnd_covs)
'' I was having some trouble with the near singular matrix problem. This while was my best solution for now...
while @issingular(@implode(rnd_covs))=1 ''
call rnd_pos_def_mat(rnd_covs)
wend
call rnd_multivariate_normal(rnd_covs)
subroutine local rnd_pos_def_mat(matrix mat_res)
!size=@columns(mat_res)
matrix(!size,!size) tmp=0
for !i=1 to !size
tmp(!i,!i)=@sqrt(@rfdist(100,100))
for !j=!i+1 to !size
tmp(!i,!j)=@nrnd
next
next
matrix mat_res=@transpose(tmp)*tmp
endsub
subroutine rnd_multivariate_normal(matrix covs)
sym covs_sym=@implode(covs)
matrix cholesky=@cholesky(covs_sym)
matrix(@columns(covs),@obssmpl) vz_mat
for !i=1 to @columns(covs)
series z_norm=nrnd
stom(z_norm,vz_norm)
rowplace(vz_mat,@transpose(vz_norm),!i)
delete z_norm vz_norm
next
matrix mat_xs=cholesky*vz_mat
matrix mat_xs=@transpose(mat_xs)
mtos(mat_xs,xs)
delete covs_sym cholesky vz_mat mat_xs
endsub