I want to generate a random vector with N(0, C)
distribution, i.e. normal distribution with 0 mean and given covariance matrix C
.
I'm using MultivariateNormalDistribution
from Apache Commons:
double[] means = new double[2];
double[][] C = {
{ 5.1455479254351755, -2.0050191427617987 },
{ -2.0050191427617987, 0.7812776833676598 } };
new MultivariateNormalDistribution(new JDKRandomGenerator(), means, C);
And getting an exception matrix is singular
:
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)
I've read here that this means, that the matrix is not invertible. Ok.
But, all I want is a random vector with N(0, C)
distribution. I can use whatever method.
In Multivariate normal distribution Wikipedia article it's written:
The covariance matrix is allowed to be singular (in which case the corresponding distribution has no density). This case arises frequently in statistics (...)
How can I generate such a random vector in Java?
I've also tried CholeskyDecomposition
with the same C
array:
RealMatrix covMatrix = new Array2DRowRealMatrix(C);
CholeskyDecomposition choleskyDecomposition = new CholeskyDecomposition(covMatrix);
And it also doesn't work, throwing 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)
For people with similar problem:
Not Positive Definite Matrices - Causes and Cures gave me some insight.