Reputation: 2365
if not (sp.csc_matrix.transpose(a) == a).all():
a_transpose=sp.csc_matrix.transpose(a)
a=np.add(a,a_transpose)
I am keeping a check if the sparse matrix is symmetric or not but I am getting the following error- AttributeError: all not found
Upvotes: 2
Views: 3227
Reputation: 231395
For some random explorations of the topic:
In [77]: from scipy import sparse
Make a sparse matrix
In [78]: M = sparse.random(100,100,.2, 'csr')
In [79]: M
Out[79]:
<100x100 sparse matrix of type '<class 'numpy.float64'>'
with 2000 stored elements in Compressed Sparse Row format>
It doesn't like the equality test - it does but gives a warning, the original 2000 nonzero values has increased 3x
In [80]: M==M.T
/usr/local/lib/python3.5/dist-packages/scipy/sparse/compressed.py:226: SparseEfficiencyWarning: Comparing sparse matrices using == is inefficient, try using != instead.
" != instead.", SparseEfficiencyWarning)
Out[80]:
<100x100 sparse matrix of type '<class 'numpy.bool_'>'
with 6436 stored elements in Compressed Sparse Row format>
Difference still increases the number of nonzero terms, but not as much
In [81]: (M-M.T)
Out[81]:
<100x100 sparse matrix of type '<class 'numpy.float64'>'
with 3564 stored elements in Compressed Sparse Row format>
Python abs
works, because it delegates to the sparse method: M.__abs__
In [85]: abs(M-M.T)
Out[85]:
<100x100 sparse matrix of type '<class 'numpy.float64'>'
with 3564 stored elements in Compressed Sparse Row format>
Another warning if we ask how many are small - the differences for the 0s are all 0:
In [86]: abs(M-M.T)<1e-10
/usr/local/lib/python3.5/dist-packages/scipy/sparse/compressed.py:274: SparseEfficiencyWarning: Comparing a sparse matrix with a scalar greater than zero using < is inefficient, try using >= instead.
warn(bad_scalar_msg, SparseEfficiencyWarning)
Out[86]:
<100x100 sparse matrix of type '<class 'numpy.bool_'>'
with 6436 stored elements in Compressed Sparse Row format>
Create a symmetric matix:
In [87]: Ms = (M+M.T)/2
Now all terms are small
In [88]: abs(Ms-Ms.T)<1e-10
/usr/local/lib/python3.5/dist-packages/scipy/sparse/compressed.py:274: SparseEfficiencyWarning: Comparing a sparse matrix with a scalar greater than zero using < is inefficient, try using >= instead.
warn(bad_scalar_msg, SparseEfficiencyWarning)
Out[88]:
<100x100 sparse matrix of type '<class 'numpy.bool_'>'
with 10000 stored elements in Compressed Sparse Row format>
Instead lets check how many differences are too large:
In [89]: abs(Ms-Ms.T)>1e-10
Out[89]:
<100x100 sparse matrix of type '<class 'numpy.bool_'>'
with 0 stored elements in Compressed Sparse Row format>
In [90]: abs(M-M.T)>1e-10
Out[90]:
<100x100 sparse matrix of type '<class 'numpy.bool_'>'
with 3564 stored elements in Compressed Sparse Row format>
So the matrix is symmetric if:
In [94]: (abs(Ms-Ms.T)>1e-10).nnz == 0
Out[94]: True
Upvotes: 8
Reputation: 33532
Even if the eq-operator would work here, it's dense. Compare with:
import scipy.sparse as sp
import numpy as np
np.random.seed(1)
a = sp.random(5, 5, density=0.5)
blub = a == a.T
print(blub.shape)
(5, 5)
So don't go this route.
Assuming the data.attribute is available (at least for csc) and of course symmetry, i would do:
sym_err = a - a.T
sym_check_res = np.all(np.abs(sym_err.data) < 1e-10) # tune this value
The effect:
sym_err.data
will be of shape (nnz,)
, here: (12,)
(of course sym_err
is sparse too under mild conditions: see next note)
The introduced thresholding is necessary in many use-cases involving fp-math. Skip it or decrease the threshold only if you know what you are doing.
Upvotes: 0