java - MultivariateNormalDistribution 抛出 "matrix is singular"

标签 java random matrix apache-commons

我想生成一个具有 N(0, C) 分布的随机 vector ,即平均值为 0 且给定协方差矩阵 C 的正态分布。

我正在使用MultivariateNormalDistribution来自 Apache Commons:

double[] means = new double[2];
double[][] C = {
{ 5.1455479254351755, -2.0050191427617987 },
{ -2.0050191427617987, 0.7812776833676598 } };
new MultivariateNormalDistribution(new JDKRandomGenerator(), means, C);

并得到一个异常矩阵是奇异的:

Exception in thread "main" org.apache.commons.math3.linear.SingularMatrixException: matrix is singular
    at org.apache.commons.math3.linear.EigenDecomposition$Solver.getInverse(EigenDecomposition.java:533)
    at org.apache.commons.math3.distribution.MultivariateNormalDistribution.<init>(MultivariateNormalDistribution.java:125)
    at javabbob.Experiment.main(Experiment.java:52)

我已阅读 here这意味着,矩阵是不可逆的。好的。

但是,我想要的只是一个具有 N(0, C) 分布的随机 vector 。我可以使用任何方法。

Multivariate normal distribution Wikipedia article上面写着:

The covariance matrix is allowed to be singular (in which case the corresponding distribution has no density). This case arises frequently in statistics (...)

如何在 Java 中生成这样的随机 vector ?


我也尝试过CholeskyDecomposition使用相同的 C 数组:

RealMatrix covMatrix = new Array2DRowRealMatrix(C);
CholeskyDecomposition choleskyDecomposition = new CholeskyDecomposition(covMatrix);

它也不起作用,抛出NonPositiveDefiniteMatrixException:

Exception in thread "main" org.apache.commons.math3.linear.NonPositiveDefiniteMatrixException: 0 is smaller than, or equal to, the minimum (0): not positive definite matrix: value 0 at index 1
    at org.apache.commons.math3.linear.CholeskyDecomposition.<init>(CholeskyDecomposition.java:142)
    at org.apache.commons.math3.linear.CholeskyDecomposition.<init>(CholeskyDecomposition.java:85)
    at javabbob.Experiment.main(Experiment.java:59)

对于有类似问题的人:

Not Positive Definite Matrices - Causes and Cures给了我一些见解。

最佳答案

在线矩阵计算器 bluebit.gr给出 C 矩阵的下三角 Cholesky 分解为:

L = { { 2.268380  0.000000},
      {-0.883899  0.000000} };

这意味着您应该能够生成单个标准法线 Z 并进行变换以获得两个相关法线,即 X1 = 2.268380*Z 和 X2 = -0.883899*Z。形式上它是 X2 = -0.883899*Z1 + 0.000000*Z2,但由于分解中右下角的条目为零您不需要第二个独立的 Z。如果它们不为零,请添加合适的均值。

附录

抱歉,我以为您正在寻找此特定问题的解决方案。一般来说,使用Cholesky decomposition分解方差/协方差矩阵C得到下三角“根”L。如果 M 是均值 vector ,Z 是独立法线 vector ,则 X = M + < strong>LZ 将是具有所需均值和方差/协方差结构的相关法线 vector 。我不熟悉 Java,所以你必须找到或实现一个合适的矩阵库。快速网络搜索显示 Apache CommonsNIST Java 中有 Cholesky 分解实现。

关于java - MultivariateNormalDistribution 抛出 "matrix is singular",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19622601/

相关文章:

python - 从列表中随机化字符串,并对字符串的开头进行约束

c++ - 在 C++ 的 vector resize() 函数中随机化构造函数参数

php - 如何从 PHP 中的数组中选择随机值?

javascript - Threejs 变换矩阵排序

python - 在python中将一个矩阵的每一行复制到另一个空矩阵的每一行

java - 小程序中收到二进制格式的短信如何获取短号码

Java 重绘问题 - 每次移动都会看到椭圆

java - 基于实体等于的唯一集的嵌套列表

java - 正弦在Java中是如何实现的?

matrix - 如何在 Julia 中使用 JuMP 提取优化问题矩阵 A,b,c