这个问题是关于在多维正态分布中使用协方差矩阵:
我想在Matlab中使用给定的均值x
和协方差矩阵mu
生成多维随机数Sigma
。假设Z
是标准的正态分布随机数(例如使用randn
生成),那么正确的代码是什么:
x = mu + chol(Sigma) * Z
或
x = mu + Sigma ^ 0.5 * Z
我不确定在多维正态分布的定义中使用协方差矩阵 - 分母中的行列式是平方根还是Cholesky因子......
答案 0 :(得分:3)
如果根据定义,您可以参考多元正态分布的密度:
它既不包含Cholesky分解也不包含Σ的矩阵平方根,而是包含其反函数和其行列式的标量平方根。
但是,对于从该分布中数值生成随机数,密度没有帮助。它甚至不是多元正态分布的最一般描述,因为密度公式仅对正定矩阵Σ有意义,而如果零特征值也定义分布 - 这只意味着方向上的方差为0相应的特征向量。
您的问题遵循从Z
生成的标准多变量正态分布随机数randn
开始的方法,然后应用线性变换。假设mu
是p
- 维行向量,我们需要n
x p
- 维随机矩阵(每行一个观察,每列一个变量):
Z = randn(n, p);
x = mu + Z * A;
我们需要一个矩阵A
,以使x
的协方差为Sigma
。由于Z
的协方差是单位矩阵,x
的协方差由A' * A
给出。 Cholesky decomposition给出了一个解决方案,所以自然选择
A = chol(Sigma);
其中A
是上三角矩阵。
但是,我们也可以搜索Hermitian解决方案A' = A
,然后A' * A
变为A^2
矩阵平方。对此的解决方案由matrix square root给出,其通过将Sigma
的每个特征值替换为其平方根(或其负值)来计算;一般来说,n个正特征值有2个可能的解。 Matlab函数sqrtm
返回主矩阵平方根,这是唯一的非负定解。因此,
A = sqrtm(Sigma)
也有效。 A ^ 0.5
原则上应该这样做。
使用此代码进行模拟
p = 10;
n = 1000;
nr = 1000;
cp = nan(nr, 1);
sp = nan(nr, 1);
pp = nan(nr, 1);
for i = 1 : nr
x = randn(n, p);
Sigma = cov(x);
cS = chol(Sigma);
cp(i) = norm(cS' * cS - Sigma);
sS = sqrtm(Sigma);
sp(i) = norm(sS' * sS - Sigma);
pS = Sigma ^ 0.5;
pp(i) = norm(pS' * pS - Sigma);
end
mean([cp sp pp])
产生chol
比其他两种方法更精确,并且分析显示它也更快,因为p = 10和p = 100。
sqrtm
返回单数的警告输入,但返回有效的结果。)