在Matlab中生成多元正态分布随机数

时间:2015-01-23 10:02:54

标签: matlab random multidimensional-array normal-distribution

这个问题是关于在多维正态分布中使用协方差矩阵:

我想在Matlab中使用给定的均值x和协方差矩阵mu生成多维随机数Sigma。假设Z是标准的正态分布随机数(例如使用randn生成),那么正确的代码是什么:

x = mu + chol(Sigma) * Z

x = mu + Sigma ^ 0.5 * Z

我不确定在多维正态分布的定义中使用协方差矩阵 - 分母中的行列式是平方根还是Cholesky因子......

1 个答案:

答案 0 :(得分:3)

如果根据定义,您可以参考多元正态分布的密度

它既不包含Cholesky分解也不包含Σ的矩阵平方根,而是包含其反函数和其行列式的标量平方根。

但是,对于从该分布中数值生成随机数,密度没有帮助。它甚至不是多元正态分布的最一般描述,因为密度公式仅对正定矩阵Σ有意义,而如果零特征值也定义分布 - 这只意味着方向上的方差为0相应的特征向量。

您的问题遵循从Z生成的标准多变量正态分布随机数randn开始的方法,然后应用线性变换。假设mup - 维行向量,我们需要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。

然而,Cholesky分解的缺点是它只定义为正定Σ,而矩阵平方根的要求仅仅是Σ是非负定的(sqrtm返回单数的警告输入,但返回有效的结果。)