How to generate a matrix of correlated data based on a matrix of observations

7 views (last 30 days)
Hello,
I'm currently studying multicriteria decision aids and my problem is the following:
I have a matrix of n different opportunities (rows) evaluated by m different criteria (columns). Let's call it A (n x m). As I am using the Monte Carlo method, I would like to generate random data around the ones of the first column and then generate the others columns with the right correlation (based on A).
I've already tried the decomposition chol(A) but it didn't work because sometimes the covariance matrix is positive semi-definite. Then I tried the ldl(A) (LDL') but did not succeed.
I hope my problem is clear enough. If it is not, please ask me some more details.
Thank you for you answers!

Accepted Answer

John D'Errico
John D'Errico on 16 Dec 2014
If your covariance matrix is not truly positive definite, you can make it so, so that tools (like mvnrnd) which need it to be truly SPD will work. I've offered the nearestSPD function on the FEX, which efficiently forces a matrix to be positive definite, so that chol will work and produce a viable Cholesky factor.
For example,
X = randn(100,2);
X = [X,mean(X,2),X(:,2) - X(:,1)];
C = cov(X);
chol(C)
Error using chol
Matrix must be positive definite.
eig(C)
ans =
-1.66288209268421e-16
9.57105273868816e-16
1.65122791574384
2.56015621896871
Chat = nearestSPD( C );
eig(Chat)
ans =
1.1077538862225e-16
5.24485769289666e-16
1.65122791574385
2.56015621896871
format short g
C - Chat
ans =
-2.2204e-16 -8.3267e-17 1.1102e-16 -1.1102e-16
-8.3267e-17 -6.6613e-16 1.1102e-16 -8.8818e-16
1.1102e-16 1.1102e-16 3.3307e-16 -1.0929e-16
-1.1102e-16 -8.8818e-16 -1.0929e-16 -8.8818e-16
chol(Chat)
ans =
0.99191 0.12484 0.55838 -0.86707
0 0.97714 0.48857 0.97714
0 0 1.0537e-08 -2.1073e-08
0 0 0 2.581e-08

More Answers (1)

Dorian
Dorian on 16 Dec 2014
Thanks for your answer John. But the fact that the eigen values of my matrix are modified means that the rest of my results will not be truly precise. Am I right?
Do you know how to generate a matrix in which the elements will be correlated such as an initial one?
  1 Comment
John D'Errico
John D'Errico on 16 Dec 2014
Please, if you have a comment, USE THE COMMENT facility, rather than adding an answer.
Sorry, but you are incorrect. The covariance matrix generated by cov in my example is slightly negative definite only due to numerical round-off error.
In my example, look at the difference between C and Chat. I showed that difference matrix for a valid reason. See that the differences were on the order of eps in double precision, thus the differences were essentially in the least significant bits.
As far as asking how to generate a matrix that has elements which have the same correlation structure as your data, I JUST SHOWED YOU THAT. Simply use mvnrnd with the corrected covariance matrix. A covariance matrix which is generated from your data, but has some tiny negative eigenvalue due to numerical slop is exactly what nearestSPD is designed to correct.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!