Reputation: 565
I'm trying to make a function with the arguments (a,tol=1e-8)
that returns a boolean value that tells the user whether or not the matrix is symmetric (symmetric matrix is equal to its transpose). So far I have:
def check_symmetric(a, tol=1e-8):
if np.transpose(a, axes=axes) == np.transpose(a, axes=axes):
return True
def sqr(s):
rows = len(s)
for row in sq:
if len(row) != rows:
return False
return True
if a != sqr(s):
raise ValueError
although I keep getting an axes isn't defined
message so I'm pretty sure that doesn't work at all...... the tests I'd like to pass are:
e = np.eye(4)
f = np.diag([1], k=3)
g = e[1:, :]
print(check_symmetric(e))
print(not check_symmetric(e + f))
print(check_symmetric(e + f * 1e-9))
print(not check_symmetric(e + f * 1e-9, 1e-10))
try:
check_symmetric(g)
print(False)
except ValueError:
print(True)
Any help is appreciated, thanks!
Upvotes: 50
Views: 88028
Reputation: 290
Suppose we were not to consider tolerance e.i. consider integer matrices. We can use .all()
in this code to check the corresponding matrix elements and .shape
to find matrix dimensions so then we can write something like this:
def check_matrix(A:np.array):
a, b = A.shape
if a == b and (-1*np.transpose(A) == A).all():
return -1
if a == b and (np.transpose(A) == A).all():
return 1
return 0
Takes in a matrix first if statement checks if it's skew symmetrical, second, if it's symmetrical and if neither, returns 0. To adapt this code to floats, use .allclose()
. I am aware the previous answer has a better and more concise code but I wanted to share this because answers have not used .shape
, so it is unique. :)
Upvotes: 1
Reputation: 24169
If using SciPy is acceptable, you can use scipy.linalg.issymmetric()
(as of v1.8.0), which also includes some input validation.
When
atol
and/orrtol
are set, then the comparison is performed bynumpy.allclose
and the tolerance values are passed to it. Otherwise, an exact comparison against zero is performed by internal functions. Hence performance can improve or degrade depending on the size and dtype of the array.
Upvotes: 3
Reputation: 71
This is an old post but I would recommend another method. Especially for sparse matrices, this can be hundreds of times faster.
def is_symmetric(A, tol=1e-8):
return scipy.sparse.linalg.norm(A-A.T, scipy.Inf) < tol;
Or similar but you get the idea. Using a norm is a much more optimized calculation.
Upvotes: 5
Reputation: 2440
If you're not worried about the tot
threshold
(a==a.T).all()
is the simplest solution. This works for N-dimensional (N>2) arrays as well.
Upvotes: 8
Reputation: 448
The following function also solves the problem:
def check_symmetric(a, tol=1e-8):
return np.all(np.abs(a-a.T) < tol)
Upvotes: 24
Reputation: 36765
You can simply compare it to its transpose using allclose
def check_symmetric(a, rtol=1e-05, atol=1e-08):
return numpy.allclose(a, a.T, rtol=rtol, atol=atol)
Upvotes: 113