-
Notifications
You must be signed in to change notification settings - Fork 64
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
Is_unit and is_nilpotent (with tests) #1933
base: master
Are you sure you want to change the base?
Conversation
I don't think we can rely on any order when iterating over the coefficients. The only guarantee that we have is that
|
I notice that there are tests of
Should I disable these tests? I have not yet checked which code would be called... |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1933 +/- ##
==========================================
- Coverage 88.21% 87.89% -0.33%
==========================================
Files 119 119
Lines 30384 30397 +13
==========================================
- Hits 26803 26717 -86
- Misses 3581 3680 +99 ☔ View full report in Codecov by Sentry. |
I don't understand. Why would you disable the tests? Anyway, checking what code is called shouldn't be hard with |
is_constant(f) && return is_unit(constant_coefficient(f)) | ||
# Here deg(f) > 0; over an integral domain, non-constant polynomials are never units: | ||
is_domain_type(elem_type(coefficient_ring(f))) && return false | ||
for (c, expv) in zip(coefficients(f), exponent_vectors(f)) |
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.
Can we add a comment explaining the math? E.g.
for (c, expv) in zip(coefficients(f), exponent_vectors(f)) | |
# A polynomial over a commutative ring is a unit if and only if its | |
# constant term is a unit and all other coefficients are nilpotent. | |
# See URL/BOOKREF/SOMETHING for a proof. | |
for (c, expv) in zip(coefficients(f), exponent_vectors(f)) |
Obviously with a suitable source inserted.
In general, we cannot always decide if a *-series is a unit: e.g. if no terms of the series are known, or if the only known terms all have nilpotent coefficients... |
src/MPoly.jl
Outdated
function is_nilpotent(f::T) where {T<:MPolyRingElem} | ||
is_domain_type(elem_type(coefficient_ring(f))) && return is_zero(f) |
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.
function is_nilpotent(f::T) where {T<:MPolyRingElem} | |
is_domain_type(elem_type(coefficient_ring(f))) && return is_zero(f) | |
function is_nilpotent(f::MPolyRingElem{T}) where {T} | |
is_domain_type(T) && return is_zero(f) |
would be IMHO more idiomatic (and simply much shorter to read).
The same could of course be used in is_unit
above and elsewhere.
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.
OK, I'll try. I have found is_domain_type
to be quite obstreperous, which is why I have used work-arounds. Maybe I should update...
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.
Could you clarify what you found problematic about is_domain_type
? What are you "working around"?
src/NCRings.jl
Outdated
function is_nilpotent(a::T) where { T <: NCRingElem } | ||
is_domain_type(typeof(a)) && return is_zero(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.
function is_nilpotent(a::T) where { T <: NCRingElem } | |
is_domain_type(typeof(a)) && return is_zero(a) | |
function is_nilpotent(a::T) where {T <: NCRingElem} | |
is_domain_type(T) && return is_zero(a) |
Julia convention is to write {T <: NCRingElem}
not { T <: NCRingElem }
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 can do what you prefer, but there are lots of other functions which use different spacing in the where
clause e.g. no curly brackets, no spaces around <:
,...
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.
Sure. But I am not asking you to reformat the code, just to not introduce yet more variation. I just grepped the code base for AA and I found exactly one hit for where {
(i.e., with a space after the opening curly brace), and that was in code that was (a) copied from another project and (b) trying to highlight a very specific pattern (i.e. it makes sense, locally, to format it that way).
Let's not introduce this new variation without need in new code, yes?
As I expressed on several occasions, it'd be perfectly fine to ignore series completely for now, focus on getting the rest right, then after that is ready and merged, think more about dealing with series. So that we get the "easier" (not easy) bits done and usable, instead of getting bogged down in the more complicated (and less useful for us, currently) bits. But since you are asking: we do implement Now whether this is useful is another question -- which is part of why I'd be OK with us raising an error if one of these functions is called on a series element. |
BTW, note that doctests in |
@@ -40,6 +40,8 @@ one(::Rationals{T}) where T <: Integer = Rational{T}(1) | |||
|
|||
is_unit(a::Rational) = a != 0 | |||
|
|||
is_nilpotent(a::Rational) = (a == 0) |
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.
Redundant?
@@ -42,6 +42,8 @@ one(::Integers{T}) where T <: Integer = T(1) | |||
|
|||
is_unit(a::Integer) = a == 1 || a == -1 | |||
|
|||
is_nilpotent(a::Integer) = is_zero(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.
Redundant?
@test is_nilpotent(-x) | ||
@test is_nilpotent(x+y) | ||
@test is_nilpotent(x-y) | ||
@test is_nilpotent(x*y) |
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.
Instead of adding these tests (which are very similar each time) into multiple places, it would be better to test them to the general ring interface test suite in test/Rings-conformance-tests.jl
so that the tests get run for all our ring implementations (well, at least all that use the conformance tests).
Of course this may then reveal further issues, but so be it.
I'd like to add that despite my many minor nitpicks, overall this PR seems to be shaping up and headed in the right direction. Thank you. |
Still a draft