Error: The observed covariance matrix is not a symmetric matrix

2 replies [Last post]
suzannejak's picture
Offline
Joined: 01/06/2010

Hello all,

I am calculating the observed covariance matrix from the correlation matrix and the standard deviations. However, the resulting matrix apparently is not symmetric anymore (although judged by me it is...). Leading to the error message: The observed covariance matrix is not a symmetric matrix.

I hope somebody can help me out, thanks in advance!

Here is the code:

X = matrix(0,8,8)
val = c(1,.39,.35,.21,.32,.40,.39,.39,
1,.67,.11,.27,.29,.32,.29,1,.16,.29,
.28,.30,.37,1,.38,.30,.31,.42, 1,.47,
.42,.58,1,.41,.51,1,.42,1)
X[lower.tri(X, diag=TRUE)] = val
kaufcor = X + t(X) - diag(diag(X))

SD = matrix(0,8,8)
diag(SD) = c(3.40,2.40,2.90,2.70,2.70,4.20,2.80,3.00)

kaufcov = SD %*% kaufcor %*% SD

kaufcor==t(kaufcor)
kaufcov==t(kaufcov)

tbrick's picture
Offline
Joined: 07/31/2009
Looks like a matter of numerical precision.

Looks like a matter of numerical precision.

You can fix this by choosing a finite precision (say, 10^-9), and rounding:

 roundCov <- round(kaufcov, 9)

You'll find that this is perfectly symmetric.

What's happening is that you're reaching the boundaries of machine precision. Because R is using a finite-length binary representation of each number, there is often a little rounding at the last bit or two (like when a calculator abbreviates 2/3 as .667). As a result, small changes like the order in which operations occur can sometimes make differences appear in the last few bits.

If you do kaufcov - t(kaufcov), you'll see these differences specifically. They're at the edges of machine precision, on the order of 10^-16. Rounding off the last few bits will make these differences disappear without losing much precision. You can also use signif(kaufcov, #) if you know the number of significant digits you want to maintain.

suzannejak's picture
Offline
Joined: 01/06/2010
Great, thank you very much!

Great, thank you very much!