<jupyter_start><jupyter_text>Correlated (multivariate) normal random variables<jupyter_code>import numpy as np
import scipy.stats as spst
import matplotlib.pyplot as plt

np.set_printoptions(precision=3)<jupyter_output><empty_output><jupyter_text>Two correlated normal random variables<jupyter_code>xnorm = np.random.normal(size=10000)
ynorm = np.random.normal(size=10000)
np.corrcoef(xnorm, ynorm)
rho = 0.75
ynorm = rho*xnorm + np.sqrt(1-rho**2)*ynorm
np.corrcoef(xnorm, ynorm)<jupyter_output><empty_output><jupyter_text>Sigma (std) and correlation matrix<jupyter_code>sig_v = np.array([2, 5, 2])
cor_m = np.array([[1, 0.7, -0.2], [0.7, 1, 0.5], [-0.2, 0.5, 1]])
print(sig_v, '\n', cor_m)
# You can also create random Correlation matrixs

n_asset = 5
eig_val = np.random.uniform(size=n_asset)
eig_val *= n_asset / np.sum(eig_val)
# sum of eig_val = n_asset

np.random.seed(123456)
cor_m2 = spst.random_correlation.rvs(eig_val, tol=1e-8)
_ = plt.matshow(cor_m2, cmap=plt.cm.Blues)<jupyter_output><empty_output><jupyter_text>Construct Covariance Matrix<jupyter_code>sig_v[:,None]
sig_v[:,None] * sig_v * cor_m<jupyter_output><empty_output><jupyter_text>Covariance and correlation matrices:$$ \Sigma_{ij} = \sigma_i R_{ij} \sigma_j $$<jupyter_code>cov_m = sig_v[:,None] * cor_m * sig_v 
print(cov_m)<jupyter_output>[[ 4.   7.  -0.8]
 [ 7.  25.   5. ]
 [-0.8  5.   4. ]]<jupyter_text>Cholesky decomposition of covariance matrix<jupyter_code>chol_m = np.linalg.cholesky(cov_m)
print(chol_m)
# Let's verify that L x L^T = Covariance

print( chol_m @ chol_m.T, '\n' )
print( chol_m @ chol_m.T - cov_m )
# Now let's create multivariate normal random variables following the covariance matrix
# First, create standard normals (3 x 1000)

znorm_m = np.random.normal(size=(3, 1000))
znorm_m
np.round(np.cov(znorm_m),3)
# Then multiply C^T

#xnorm_m = znorm_m @ chol_m.transpose()
xnorm_m = chol_m @ znorm_m
print(xnorm_m.shape)
xnorm_m
# Let's verify that X = C * Z  follows the covariance
print(cov_m)
cov_m_sample = np.cov( xnorm_m )
print( 'Cov from sample:\n', cov_m_sample )
print( 'Error of Cov matrix:\n', cov_m_sample - cov_m )
# also check the correation
print(cor_m)
cor_m_sample = np.corrcoef( xnorm_m )
print( 'Corr from sample:\n', cor_m_sample )
print( 'Error:\n', cor_m_sample - cor_m )<jupyter_output>[[ 1.   0.7 -0.2]
 [ 0.7  1.   0.5]
 [-0.2  0.5  1. ]]
Corr from sample:
 [[ 1.     0.72  -0.192]
 [ 0.72   1.     0.48 ]
 [-0.192  0.48   1.   ]]
Error:
 [[-2.220e-16  2.010e-02  7.570e-03]
 [ 2.010e-02  0.000e+00 -1.954e-02]
 [ 7.570e-03 -1.954e-02  0.000e+00]]
{'fraction_non_alphanumeric': 0.1528588098016336, 'fraction_numerical': 0.062232594321275765, 'mean_word_length': 4.603485838779957, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '361413', 'license': 'MIT', 'n_tokens_mistral': 1231, 'n_tokens_neox': 1124, 'n_words': 233, 'path': 'py/CorrelatedNormals_Demo.ipynb', 'repo_name': 'yogaball/ASP2021', 'size': '2571'}