3
votes

I was trying to test numerically if the multiplication of a matrix and its transpose really generates a symmetric square matrix.

Below is the code I used:

mat = np.array([[1,2,3],[1,0,1],[1,1,1],[2,3,5]])
mat2 = np.linalg.inv(np.matmul(np.transpose(mat),mat))
mat2
array([[ 1.42857143,  0.42857143, -0.85714286],
   [ 0.42857143,  1.92857143, -1.35714286],
   [-0.85714286, -1.35714286,  1.21428571]])

mat2 appears to be symmetric.

However, the result of the below code made me confused:

np.transpose(mat2) == mat2
array([[ True, False, False],
   [False,  True, False],
   [False, False,  True]])

But when I did the same procedure with mat, the result was as I expected:

np.transpose(np.matmul(np.transpose(mat),mat)) == np.matmul(np.transpose(mat),mat)
array([[ True,  True,  True],
   [ True,  True,  True],
   [ True,  True,  True]])

Is this related a computational issue? If then, how can I show that the off-diagonal elements are identical?

1

1 Answers

2
votes

Comparing mat and mat.T, you're comparing integers to integers and there's no problem.

mat2 is floating point, which is prone to subtle errors. When you print out mat2, you're seeing the truncated version of the full digits. Look at the difference between mat2 and mat2.T:

>>> mat2 - mat2.T
array([[ 0.00000000e+00,  1.11022302e-16, -1.11022302e-16],
       [-1.11022302e-16,  0.00000000e+00,  2.22044605e-16],
       [ 1.11022302e-16, -2.22044605e-16,  0.00000000e+00]])

The differences are on the order of 0.0000000000000001, meaning that they're equal "for all intents an purposes" but not equal exactly. There are two places to go from here. You can either accept that numerical precision is limited and use something like numpy.allclose for your equality tests, which allows for some small errors:

>>> np.allclose(mat2, mat2.T)
True

Or, if you really insist on your matrices being symmetric, you can enforce it with something like this:

>>> mat3 = (mat2 + mat2.T)/2
>>> mat3 == mat3.T
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]])