CV与代码无关,但我对看到所有好的答案(特别是@Mark L. Stone贡献)后的外观很感兴趣。该问题的实际答案在其职位上提供(如有疑问,请记入其职位)。我将在此处移动此附加信息,以方便将来检索此帖子。在Mark回答之后,无需淡化任何其他出色的答案,这可以通过更正OP中的帖子来解决问题。
在PYTHON:
import numpy as np
no_obs = 1000 # Number of observations per column
means = [1, 2, 3] # Mean values of each column
no_cols = 3 # Number of columns
sds = [1, 2, 3] # SD of each column
sd = np.diag(sds) # SD in a diagonal matrix for later operations
observations = np.random.normal(0, 1, (no_cols, no_obs)) # Rd draws N(0,1) in [3 x 1,000]
cor_matrix = np.array([[1.0, 0.6, 0.9],
[0.6, 1.0, 0.5],
[0.9, 0.5, 1.0]]) # The correlation matrix [3 x 3]
cov_matrix = np.dot(sd, np.dot(cor_matrix, sd)) # The covariance matrix
Chol = np.linalg.cholesky(cov_matrix) # Cholesky decomposition
array([[ 1. , 0. , 0. ],
[ 1.2 , 1.6 , 0. ],
[ 2.7 , -0.15 , 1.29903811]])
sam_eq_mean = Chol .dot(observations) # Generating random MVN (0, cov_matrix)
s = sam_eq_mean.transpose() + means # Adding the means column wise
samples = s.transpose() # Transposing back
print(np.corrcoef(samples)) # Checking correlation consistency.
[[ 1. 0.59167434 0.90182308]
[ 0.59167434 1. 0.49279316]
[ 0.90182308 0.49279316 1. ]]
IN [R]:
no_obs = 1000 # Number of observations per column
means = 1:3 # Mean values of each column
no_cols = 3 # Number of columns
sds = 1:3 # SD of each column
sd = diag(sds) # SD in a diagonal matrix for later operations
observations = matrix(rnorm(no_cols * no_obs), nrow = no_cols) # Rd draws N(0,1)
cor_matrix = matrix(c(1.0, 0.6, 0.9,
0.6, 1.0, 0.5,
0.9, 0.5, 1.0), byrow = T, nrow = 3) # cor matrix [3 x 3]
cov_matrix = sd %*% cor_matrix %*% sd # The covariance matrix
Chol = chol(cov_matrix) # Cholesky decomposition
[,1] [,2] [,3]
[1,] 1 1.2 2.700000
[2,] 0 1.6 -0.150000
[3,] 0 0.0 1.299038
sam_eq_mean = t(observations) %*% Chol # Generating random MVN (0, cov_matrix)
samples = t(sam_eq_mean) + means
cor(t(samples))
[,1] [,2] [,3]
[1,] 1.0000000 0.6071067 0.8857339
[2,] 0.6071067 1.0000000 0.4655579
[3,] 0.8857339 0.4655579 1.0000000
colMeans(t(samples))
[1] 1.035056 2.099352 3.065797
apply(t(samples), 2, sd)
[1] 0.9543873 1.9788250 2.8903964