-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve performance of issym and ishermitian for sparse matrices #11371
Conversation
Always. Especially with sparse stuff, you should absolutely add a bunch of new test cases with this. |
I updated with more test cases to |
Build timed out on x64 |
Is there any consensus how functions should behave on sparse matrices where explicit zeros have been inserted into the structure? |
I think what makes most sense usually is to preserve them (others will have
to correct me if I'm wrong). Our in what respect?
|
In the respect of correctness. If you allow explicit zeros, a symmetric sparse matrix does not necessarily have a symmetric sparse structure. For example, with my function in the PR: A = speye(10,10)
A2 = speye(10,10)
A[8,9] = 1.0
A.nzval[9] = 0
A == A2 # True
ishermitian(A) # True
ishermitian(A2) # False(!) In order for this to work, you need insert some checks for zero. |
For sparse matrices, "is numerically symmetric" is a distinct property from "is structurally symmetric." It's possible to construct examples of all 4 combinations. Numerical symmetry should treat explicit zeros as equal to implicit zeros in the other triangle, structural symmetry should treat explicit zeros as a structurally stored location. |
@KristofferC The cases I've tried will not represent them, and on the other hand, if you set a location to None, it preserves it... 👎
julia> z = sparse([1,2], [1,2], ["hello", 1.5])
2x2 sparse matrix with 2 Any entries:
[1, 1] = "hello"
[2, 2] = 1.5
julia> z[1,2] = None
Union()
julia> z
2x2 sparse matrix with 3 Any entries:
[1, 1] = "hello"
[1, 2] = Union()
[2, 2] = 1.5
julia> nnz(z)
3
julia> z[1,2] = 0
0
julia> nnz(z)
2
julia> z
2x2 sparse matrix with 2 Any entries:
[1, 1] = "hello"
[2, 2] = 1.5 This is rather unfortunate, because it means these are not suitable for database work... Am I missing something here? |
|
OK, when I read that about mutating operations, I didn't think it meant a plain set... especially after reading:
|
Please @ScottPJones, if you start your post with "Another issue" it should probably be in "Another issue". @tkelman So as it is, the function in this PR is bugged because it fails on no structurally symmetric, symmetric matrices. I will fix and update. |
@KristofferC Well, it seemed perfectly on point about your question... the docs say one thing, but the code seems to do something else...
|
@ScottPJones Yes, I should have said that it was more concretely about the function in this PR. A general discussion about dealing with explicit zeros in sparse matrices should probably be held in a separate issue. Anyway, I fixed the problem now so that A = speye(10,10)
A2 = speye(10,10)
A[8,9] = 1.0
A.nzval[9] = 0
A == A2 # True
ishermitian(A) # True
ishermitian(A2) # True Also rebased. |
Test fail seem to be unrelated?
|
@ScottPJones I request sticking to the discipline of discussing relevant matters in an issue, or else it becomes inconvenient for everyone else. Like I had suggested earlier, the issue of zeros in sparse matrices for non-numerical data is best discussed on julia-users, or through a PR, or perhaps even a separate issue. |
@ViralBShah I was simply responding to this, and bringing up the point that the code and documentation didn't seem to agree... That did seem relevant to the question.
|
Fair enough. The documentation should be updated too. BTW, |
What is the actual definition of structural symmetry? From http://docs.oracle.com/cd/E19205-01/819-5268/plug_sparse.html: "A structurally symmetric sparse matrix has nonzero values with the property that if a(i, j) not equal 0, then a(j, i) not equal 0 for all i and j." This seems to exclude cases like
where But from @tkelman's comment it seems like this should be regarded as structural symmetric. |
IMO, structural symmtery ignores the numerical values. |
Ok, I agree. There are two ways to implement the Another way is to make |
But you would also like to have the option to check structural and numeric
symmetry at the same time I guess.
|
Whether to store or not store zeros has been discussed before, but without definitive conclusion. The most discussion happened here #9928, where most wanted to keep zeros. |
If we are going to have the store zeros or not discussion here, I would say I am for keeping the sparse structure when you can. Stuff like this feels silly:
Regarding the PR, I don't think we should add too much. The symmetric structure checking could easily be added in a separate PR. |
I've been thinking that setindex with a zero rhs should introduce an explicit zero when it's assigning to a location that is already stored in the matrix, but that'll have to be argued about in a different PR. I'm not sure I'd take sunperf's documentation as the definitive truth here, I don't know what their policy is on explicit zeros there. MKL might be slightly more informative? Structural symmetry shouldn't look at the contents of |
Updated with some actual benchmarks. |
@KristofferC Is this ready? LGTM. |
Yeah, should be ready for merge. |
Improve performance of issym and ishermitian for sparse matrices
Great. Thanks for the work. |
This implements what @toivoh mentioned here JuliaLang/LinearAlgebra.jl#217
My testing shows that it is about 3 times faster for hermitian matrices than the current one and for non hermitian it usually terminates right away so it gains a lot there. It also uses less memory.
The logic in this function is of course more complicated than the current one so it is important that it is tested properly. I prodded it with as many different cases I could come up with and it works for all those but maybe there should be more tests in base?
Edit:
Some small benchmarks:
Results