-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
fix some issues with equality of factorizations #41228
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
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# This file is a part of Julia. License is MIT: https://julialang.org/license | ||
|
||
module TestFactorization | ||
using Test, LinearAlgebra | ||
|
||
@testset "equality for factorizations - $f" for f in Any[ | ||
bunchkaufman, | ||
cholesky, | ||
x -> cholesky(x, Val(true)), | ||
eigen, | ||
hessenberg, | ||
lq, | ||
lu, | ||
qr, | ||
x -> qr(x, ColumnNorm()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to be manually changed to |
||
svd, | ||
schur, | ||
] | ||
A = randn(3, 3) | ||
A = A * A' # ensure A is pos. def. and symmetric | ||
F, G = f(A), f(A) | ||
|
||
@test F == G | ||
@test isequal(F, G) | ||
@test hash(F) == hash(G) | ||
|
||
f === hessenberg && continue | ||
|
||
F = typeof(F).name.wrapper(Base.mapany(1:nfields(F)) do i | ||
x = getfield(F, i) | ||
return x isa AbstractArray{Float64} ? Float32.(x) : x | ||
end...) | ||
G = typeof(G).name.wrapper(Base.mapany(1:nfields(G)) do i | ||
x = getfield(G, i) | ||
return x isa AbstractArray{Float64} ? Float64.(Float32.(x)) : x | ||
end...) | ||
|
||
@test F == G | ||
@test isequal(F, G) | ||
@test hash(F) == hash(G) | ||
end | ||
|
||
@testset "hash collisions" begin | ||
A, v = randn(2, 2), randn(2) | ||
F, G = LQ(A, v), QR(A, v) | ||
@test !isequal(F, G) | ||
@test hash(F) != hash(G) | ||
end | ||
|
||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,3 +25,4 @@ givens | |
structuredbroadcast | ||
addmul | ||
ldlt | ||
factorization |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been told that you should never fetch the internal fields like this. Maybe you can hash
propertynames
instead?More generally, should the
hash
traversepropertynames
instead of the fields? That should avoid the issue with non-active memory affecting thehash
and maybe make the specialized methods redundant.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it's a bit ugly, but I am unsure just using
propertynames
for the hash is quite enough, since a lot of them likevectors
andvalues
for Eigen are quite generic and not necessarily unique. Perhaps that is being a bit too paranoid, but hashing by type identity seems more formally correct, at least to me. For a stdlib, relying on internals is probably also not quite as bad, since it will always get tested and updated alongside other Base changes.Yeah, maybe? I think that would mean hashing the same data twice for some factorizations though, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the reason to avoid it was aesthetics but it's really not my department. Others should comment that if it should be avoided. Maybe it used to be a problem but no longer is. Otherwise, let's just keep it.
Yes. For e.g.
Cholesky
it would probably end up hashing the same data three times so we should probably have specialized versions. However, hashing the fields seems wrong since the inactive memory will affect the hash so I think using the properties will be the correct, although slow, fallback. E.g.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the main reason we discourage use of internal APIs like this is because they might change at any time, which will break such code. I don't think there are any other glaring problems with this approach.
Using
propertynames
for the fallback seems reasonable, I will change that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, trying this locally, using
propertynames
fails forbunchkaufman
.It seems like this is an issue for quite a lot of factorizations, so if we want this to be efficient, we would end up having to define this manually for a lot of cases, which kind of defeats the purpose of having this definition in the first place.
The more I think about it, the more I am convinced that we should just remove these definitions for the abstract type
Factorization
, since they really don't make much sense in terms of the abstractFactorization
interface, but instead have a macro similar to https://github.com/andrewcooke/AutoHashEquals.jl, which defines these for each factorization separately. That would also avoid having to rely onF.name.wrapper
. What do you think? It might be somewhat breaking if users define their own factorization types though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bump. How do you think we should proceed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't the macro based version end up inspecting the fields which was what I argued against in #41228 (comment)