# Checking the symmetry of a matrix

**URL:** <https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206>\
**Category:** General Usage\
**Tags:** question, linearalgebra, matrices\
**Created:** [December 16, 2021, 3:05pm UTC](https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206 "2021-12-16T15:05:29Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rajesh\_Nakka](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rajesh_nakka/32/28445_2.png) [@Rajesh\_Nakka](https://discourse.julialang.org/u/Rajesh_Nakka)\
**Post date:** [December 16, 2021, 3:05pm UTC](https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206/1 "2021-12-16T15:05:30Z")

</div>

I am trying to check the symmetry of a matrix which I was expecting to be symmetric.

I have printed `A^T -A` to check the deviation from symmetry. It is actually populated with very small numbers, as shown below.

```julia
 0.0 0.0 0.0 0.0 0.0 1.13687e-13 9.09495e-13 5.68434e-14 0.0 0.0 1.13687e-13 1.42109e-14
  0.0 0.0 0.0 0.0 0.0 -9.09495e-13 0.0 0.0 0.0 0.0 -9.09495e-13 0.0
  0.0 0.0 0.0 0.0 0.0 -9.09495e-13 2.84217e-14 0.0 0.0 5.68434e-14 0.0 0.0
  0.0 0.0 0.0 0.0 0.0 0.0 -7.10543e-15 2.84217e-14 0.0 0.0 -2.77556e-17 1.42109e-14
  0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.22045e-16 0.0 3.55271e-15
 -1.13687e-13 9.09495e-13 9.09495e-13 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.55271e-15 -1.81899e-12
 -9.09495e-13 0.0 -2.84217e-14 7.10543e-15 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
 -5.68434e-14 0.0 0.0 -2.84217e-14 0.0 0.0 0.0 0.0 0.0 0.0 2.84217e-14 0.0
  0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.13687e-13 0.0 0.0
  0.0 0.0 -5.68434e-14 0.0 -2.22045e-16 0.0 0.0 0.0 -1.13687e-13 0.0 -4.44089e-16 0.0
 -1.13687e-13 9.09495e-13 0.0 2.77556e-17 0.0 -3.55271e-15 0.0 -2.84217e-14 0.0 4.44089e-16 0.0 0.0
 -1.42109e-14 0.0 0.0 -1.42109e-14 -3.55271e-15 1.81899e-12 0.0 0.0 0.0 0.0 0.0 0.0

```

Please let me know if there is a way to give tolerance on checking the equality of terms about the main diagonal.

Thanks.

---

<div class="post-metadata">

**Author:** ![trahflow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trahflow/32/30585_2.png) [@trahflow](https://discourse.julialang.org/u/trahflow)\
**Post date:** [December 16, 2021, 3:12pm UTC](https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206/2 "2021-12-16T15:12:26Z")

</div>

Are you aware of `LinearAlgebra.issymmetric()`?

afaik `issymmetric()` doesn’t have a way of specifying a tolerance though.

> [@Rajesh\_Nakka](#):
>
> Please let me know if there is a way to give tolerance on checking the equality of terms about the main diagonal.

There is the build-in function `isapprox`, which allows you to specify absolute and relative tolerances. You could just broadcast this over the full array (`A - A'`) and reduce with `all`, e.g you could define:.

```julia
isapproxsymmetric(A) = all(isapprox.(A - A', 0; rtol=1e-10))

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 16, 2021, 3:33pm UTC](https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206/3 "2021-12-16T15:33:30Z")

</div>

> [@trahflow](#):
>
> There is the build-in function `isapprox` , which allows you to specify absolute and relative tolerances. You could just broadcast this over the full array ( `A - A'` ) and reduce with `all` .

**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](https://en.wikipedia.org/wiki/Defective_matrix):

```julia
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
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
julia> A - A' == B - B'
true

```

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

```julia
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
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](https://discourse.julialang.org/t/bug-with-isapprox/7600/5) and the [`isapprox` documentation](https://docs.julialang.org/en/v1/base/math/#Base.isapprox) on comparison to zero.

---

<div class="post-metadata">

**Author:** ![trahflow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trahflow/32/30585_2.png) [@trahflow](https://discourse.julialang.org/u/trahflow)\
**Post date:** [December 16, 2021, 3:44pm UTC](https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206/4 "2021-12-16T15:44:23Z")

</div>

Nice! Totally makes sense!  
I wasn’t aware `isapprox` is defined for `Matrix`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 16, 2021, 3:45pm UTC](https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206/5 "2021-12-16T15:45:13Z")

</div>

> [@trahflow](#):
>
> I wasn’t aware `isapprox` is defined for `Matrix` .

~~It’s defined for any type with `-` and `norm` (essentially, the concept of a “relative error” makes sense for any normed vector space).~~ My mistake, we currently define it only for `AbstractArray` types and `Number`s (and a few other odds and ends like `Missing`).

But we _could_ define for any type with `-` and `norm`, since that’s all we really need. (I guess we also need `eltype` in order to choose the default `rtol`, or maybe `eps`.)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 16, 2021, 3:56pm UTC](https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206/6 "2021-12-16T15:56:09Z")

</div>

> [@trahflow](#):
>
> `all(isapprox.(A - A', 0; rtol=1e-10))`

Also, as explained in links [above](https://discourse.julialang.org/t/checking-the-symmetry-of-a-matrix/73206/3), comparing to zero with a relative tolerance (`rtol`) is equivalent to `==`, which is almost never what you want.
