-
Notifications
You must be signed in to change notification settings - Fork 130
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
Some improvements on the modules #3041
Some improvements on the modules #3041
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #3041 +/- ##
==========================================
- Coverage 80.43% 80.43% -0.01%
==========================================
Files 520 520
Lines 70074 70175 +101
==========================================
+ Hits 56365 56446 +81
- Misses 13709 13729 +20
|
I tried to improve the code a bit, especially regarding the speed of evaluation of mappings. So far running the same test-suite for modules gives before:
after
So especially in terms of memory consumption, I think this is useful and should be merged one way or the other. Edit: The main upshots were:
|
Why not separate the code reorganization from the improvements PR wise? The spitting should definitely be happening. |
6431e23
to
29ddc51
Compare
I ran some more tests locally. Compared to current master I now get the following timings: before:
after:
The difference to the above runs is due to some tests being disabled (on both sides) before. These runs here really take the whole test suite for the modules. |
@jankoboehm : I double checked again. There is no internal constructor for neither Edit: Besides: Now that the |
Timings now go down to
No major improvement anymore. But still something. I think I can stop here. Could maybe someone confirm the changes with the hashing? |
5c2553e
to
4270dbe
Compare
295679b
to
81a4988
Compare
Can this be merged, then? |
b = 0xaa2ba4a32dd0b431 % UInt | ||
h = hash(typeof(a), h) | ||
h = hash(parent(a), h) | ||
h = hash(coordinates(a), h) | ||
return xor(h, b) | ||
end | ||
|
||
function hash(a::AbstractFreeModElem{<:MPolyQuoRingElem}, h::UInt) | ||
simplify!(a) |
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.
We just discussed how this call resp. this hash
method is somewhat dangerous:
- it assumes that
simplify!(a)
modifiesa
in-place and also "remembers" that it is simplified (so it is fast "amortized", i.e. you only compute a GB for it once) - it must produce a unique normal form -- but we don't really have a specification for
simplify!
. We really need one otherwise we are building on quicksand - perhaps it would be better to just do
error("not supported")
here and handle using these in dicts differently?? - however the old
hash(a::AbstractFreeModElem, h::UInt)
method just was wrong...
return xor(h, b) | ||
end | ||
|
||
simplify(a::AbstractFreeModElem{<:MPolyQuoRingElem}) = return parent(a)(map_entries(simplify, coordinates(a))) |
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.
simplify(a::AbstractFreeModElem{<:MPolyQuoRingElem}) = return parent(a)(map_entries(simplify, coordinates(a))) | |
simplify(a::AbstractFreeModElem{<:MPolyQuoRingElem}) = parent(a)(map_entries(simplify, coordinates(a))) |
@@ -553,9 +559,9 @@ Homogeneous module homomorphism) | |||
``` | |||
""" | |||
function image(h::FreeModuleHom) | |||
si = [x for x = map(h, basis(domain(h))) if !iszero(x)] | |||
si = filter(x->!iszero(x), images_of_generators(h)) |
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.
si = filter(x->!iszero(x), images_of_generators(h)) | |
si = filter(!iszero, images_of_generators(h)) |
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.
While there issues with the hash
method, the existing method is just as broken, so this doesn't really make it worse... We could merge this PR, and open an issue to remind us to resolve the hash
function (and also to specify simplify!
)
function hash(a::AbstractFreeModElem, h::UInt) | ||
# A special method for the case where we can safely assume | ||
# that the coordinates of elements allow hashing. | ||
function hash(a::AbstractFreeModElem{<:MPolyElem{<:FieldElem}}, h::UInt) |
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.
Note that a field element does not necessarily have correct hashing implemented either -- though as you correctly just pointed out to me when we talked, such fields probably won't be supported by Singular either.
But on the long run we probably want a bunch of type traits to model whether hashing, normal forms, etc. are supported:
can_hash(::Type) = false
can_compute_normal_form(::Type) = false
can_hash(::Type{<:MPolyElem{T}}) where T = can_hash(T)
can_compute_normal_form(::Type{<:MPolyElem{T}}) where T = can_compute_normal_form(T)
etc.
(Perhaps should turn this into an issue?)
Setting the generic hash function to error was not an option in the end. Even the |
@jankoboehm : I wanted to look a bit into the morphisms of modules for the reasons we talked about today. But before I could actually start doing that, I needed to split that gigantic file into more digestable parts. For me personally this was so that syntax highlighting would not crash all the time. But also in general, I think, it makes sense to split this into thematically ordered smaller chunks.
Do you agree?
Edit: splitting now takes place in #3042 . This PR will eventually be rebased. Until then check out the single last commit to see the changes for the improvements only.