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.