Question

I have a matrix (mat1). When testing symmetry:

isSymmetric(mat1,tol = 0)

FALSE

Which means that with zero-tolerance, the matrix not symmetric. However testing with slightly larger tolerance, the matrix is deemed symmetric:

isSymmetric(mat1,tol = 10 * .Machine$double.eps)

TRUE

However, the maximum difference between symmetric entries is greater than this tolerance value:

max(abs(mat1-t(mat1))) > (10 * .Machine$double.eps)

TRUE

Why, when there is a symmetric difference greater than the tolerance value, is the matrix classified as symmetric?

For a worked example using the ?glm example:

counts <- c(18,17,15,20,10,20,25,13,12)
outcome <- gl(3,1,9)
treatment <- gl(3,3)
d.AD <- data.frame(treatment, outcome, counts)
glm.D93 <- glm(counts ~ outcome + treatment, family = poisson())
mat1 <- solve(vcov(glm.D93))

isSymmetric(mat1,tol=0) # FALSE
isSymmetric(mat1,tol=10 * .Machine$double.eps) # TRUE
max(abs(mat1-t(mat1))) > (10 * .Machine$double.eps) # TRUE 

I likely do not understand how tolerance works; my thinking was that values larger than the tolerance threshold would make the matrix symmetry test fail, which apparently is not the case.

Was it helpful?

Solution

@BenBolker told you to look at the help page for isSymmetric which directs you to all.equal. You built this matrix:

> mat1
            (Intercept)     outcome2     outcome3   treatment2   treatment3
(Intercept)         150 4.000000e+01 4.700000e+01 5.000000e+01 5.000000e+01
outcome2             40 4.000000e+01 2.237910e-14 1.333333e+01 1.333333e+01
outcome3             47 2.476834e-14 4.700000e+01 1.566667e+01 1.566667e+01
treatment2           50 1.333333e+01 1.566667e+01 5.000000e+01 2.710506e-14
treatment3           50 1.333333e+01 1.566667e+01 2.818926e-14 5.000000e+01

The test in all.equal is tolerance = .Machine$double.eps ^ 0.5, so none of your tests were actually the same as the one without an argument. (In the case of very small numbers the sqrt is actually quite a bit bigger.) Notice there is an additional test regarding equality of row and column names which your example would have satisfied.

If you look at the help page you should become suspicious about your understanding of what all.equal might be doing when yious see sthat is is testing ‘near equality’ and then refers you to the Details where it says:

 Numerical comparisons for scale = NULL (the default) are done by first computing the mean 
 absolute difference of the two numerical vectors.

In the code you can see that it is not individual differences being tested relative to the tolerance but the mean absolute differences.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top