I want to generate a covariance matrix, with the constraint that all the diagonal elements are equal to 1:

Cov[i,i] = 1 for i = 1...dim

The ways I've seen so far to generate a covariance matrix is either use a Wishart distribution, or generate a random matrix and multiply it by itself:

X = rand(dim,dim)
Cov = X.T*X

I can't think of a way to force either of these solutions to have 1s in their diagonal


If I want my covariance matrix to be (d x d), then I only have d*(d-1)/2 parameters to generate. Because the diagonal is 1 and the matrix is symmetric. What I'm 'really' trying to do is to generate a
d*(d-1)/2 vector so that when I fill the covariance matrix with these values, the resulting matrix is positive-definite.

  • 1
    $\begingroup$ What distribution do you want these matrices to have? If you don't care, then fix any one matrix you can find and use it forever! $\endgroup$
    – whuber
    Aug 8 '17 at 20:32

Every correlation matrix is a valid covariance matrix with ones on the diagonal. In R, you could just do cor(X) for any matrix X. In Python, numpy.corrcoef(X).

Responding to question edit:

The easiest way to get the vector you want is to vectorize the subdiagonal of the correlation matrix.

  • $\begingroup$ In fact, the converse is true as well: every valid covariance matrix with ones on the diagonal is a correlation matrix. So, this strategy can generate any matrix satisfying your criteria. $\endgroup$ Aug 8 '17 at 20:13
  • $\begingroup$ If I understand correctly, numpy.corrcoef(X) gives you a matrix with all elements between -1 and 1. But this is not really required in a normal covariance matrix, For example, Cov[1,2] can be 3. no? $\endgroup$
    – Babak
    Aug 8 '17 at 20:28
  • 1
    $\begingroup$ It can, but not when Cov[1, 1]= Cov[2, 2] = 1. Because: 0 <= Cov[X - Y, X - Y] = Cov[X, X] -2Cov[Y, X] + Cov[Y, Y] implies Cov[Y, X] <= ( Cov[X, X] + Cov[Y, Y] ) / 2 (= 1 in your case). There are other bounds of this sort as well. $\endgroup$ Aug 8 '17 at 20:51
  • $\begingroup$ Yeah, that makes sense. Thanks. Could you read what I wrote after 'EDIT'? So in your case, I would have to provide some random matrix 'X' with (n x d) dimensions. I want to provide (d*(d-1)/2) values that would return a covariance matrix. Is that possible? $\endgroup$
    – Babak
    Aug 8 '17 at 21:57
  • $\begingroup$ My problem is 'X' would need to have too many parameters and I only want to use d*(d-1)/2.0 $\endgroup$
    – Babak
    Aug 8 '17 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.