Checking the symmetry of a matrix

Don’t broadcast it! isapprox works directly for matrices. Just do isapprox(A, A', rtol=1e-12) or whatever your tolerance is.

The reason you don’t want to broadcast isapprox elementwise is that when you are asking “is this difference small” you need to know “small compared to what?” And the correct scale to compare to is generally based on the whole matrix.

For example, this matrix A is very non-symmetrical, and in fact is defective:

julia> A = [1e-15 1e-15; 0 1e-15]
2×2 Matrix{Float64}:
 1.0e-15  1.0e-15
 0.0      1.0e-15

whereas this matrix B is nearly Hermitian:

julia> B = [1 1e-15; 0 1]
2×2 Matrix{Float64}:
 1.0  1.0e-15
 0.0  1.0

even though A - A^T = B - B^T!

julia> A - A' == B - B'
true

If you use isapprox on the whole matrix, it will tell you this:

julia> isapprox(A, A', rtol=1e-12)
false

julia> isapprox(B, B', rtol=1e-12)
true

whereas if you try to use isapprox element-wise it will fail for B:

julia> all(isapprox.(B, B', rtol=1e-12))
false

The reason is that, if you look elementwise, the test 0 ≈ 1e-15 must necessarily fail with any relative tolerance, because you don’t have any yardstick to know that 1e-15 is small in an “absolute” sense. See also this discussion and the isapprox documentation on comparison to zero.

9 Likes