-
Notifications
You must be signed in to change notification settings - Fork 112
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
Spec retying #1537
Spec retying #1537
Conversation
@@ -6,56 +6,229 @@ CurrentModule = Oscar | |||
using Oscar | |||
``` | |||
|
|||
# General schemes | |||
# General schemes and their interfaces | |||
|
|||
Arbitrary schemes over a base ring ``\mathbb k`` which are given by means |
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.
Don't you want to mention somewhere that every ring here should at least be commutative with unity?
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 assumed this was understood. Has anyone ever seen schemes over non-commutative rings?
Ok, there are the non-commutative C*-algebras, but that is hardly ever called scheme.
Anyway: I think you are right. I will add that.
mult_set_type(::Type{Spec{BRT, BRET, RT, RET, MST}}) where {BRT, BRET, RT, RET, MST} = MST | ||
poly_ring_type(::Type{Spec{BRT, BRET, RT, RET, MST}}) where {BRT, BRET, RT, RET, MST} = RT | ||
poly_type(::Type{Spec{BRT, BRET, RT, RET, MST}}) where {BRT, BRET, RT, RET, MST} = RET | ||
function hypersurface_complement(X::SpecType, f::Vector{<:RingElem}) where {SpecType<:AbsSpec{<:Any, <:MPolyLocalizedRing}} |
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.
Why is f a vector here? For a hypersurface complement this should (from the point of view of mathematical theory) be a single element.
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.
This is more for internal use and passing on factors of f whenever we already have it in partially factorized form.
) where {BRT} | ||
R = base_ring(OO(X)) | ||
R == base_ring(OO(Y)) || error("schemes can not be compared") | ||
return Spec(quo(OO(Y), OO(Y)(modulus(OO(X))))[1]) |
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.
stupid question: don't you need to pay attention to the multiplicatively closed subsets used in the localizations of the two schemes (just as in the preceding instance)?
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.
Oops. Yes, I was missing out on 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.
Now that I'm looking at it again: No, only one of the rings has a multiplicative set and it's preserved, because I'm calling quo
on OO(Y)
.
end | ||
|
||
function Spec(kk::Ring, R::Ring) | ||
return new{typeof(kk), typeof(R)}(R) |
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.
Why is there only one argument here?
@@ -455,34 +784,59 @@ function preimage( | |||
return Spec(MPolyQuoLocalizedRing(R, ideal(R, new_gens) + modulus(OO(X)), inverted_set(OO(X))*new_units)) | |||
end | |||
|
|||
function is_isomorphism(f::SpecMor) | |||
function preimage(f::AbsSpecMor, Z::AbsSpec{<:Ring, <:MPolyRing}; check::Bool=true) |
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 do not see Z used in the function anywhere. Is that, because Z is automatically the whole codomain here or do we at least need to check compatibility with the codomain of f (as a sanity check)?
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, this is a mistake.
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.
Looking at it again: It's not a mistake. Since Z = Spec(P)
for a polynomial ring, it must necessarily be the full ambient space of the codomain of f
, so the preimage is simply a copy of the domain.
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.
Let me put the question more directly: How do you make sure that the user has not provided some Z which has nothing to do with f at all (maybe by mistake or typo in the name or because a previous computation had an unexpected result)? As you are not touching Z anywhere, no sanity check (apart from the fact that Z is a Spec of some polynomial ring) is performed -- neither explicitly nor implicitly.
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.
Significant rewrite, makes internal structure of the schemes-code a lot more readable and accesible to others.
Questions:
- How did the performance change?
- You have several open 'TODO' in there. Do you want to merge now and add those later on?
I see this pull request as aiming at setting up a stable foundation both for your further development/refinement of the scheme environment and for the ongoing development in packages relying on schemes. Thus I am in favor of approval.
To clarify why I am merely commenting instead of approving:
- I have not checked explicitly that at all relevant instances all 16 pairs of possible underlying rings are handled properly (i.e. none of them escaped our attention)
- I did not check that odd cases (like trying to map from or into an empty scheme) are caught.
return get_attribute(f, :inverse)::morphism_type(codomain(f), domain(f)) | ||
end | ||
|
||
@Markdown.doc """ | ||
product(X::Spec, Y::Spec) | ||
product(X::AbsSpec, Y::AbsSpec) | ||
|
||
Returns a triple ``(X×Y, p₁, p₂)`` consisting of the product ``X×Y`` and the two projections | ||
``p₁ : X×Y → X`` and ``p₂ : X×Y → 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.
Do you want to mention that this is the product over the common base field k?
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.
Yes, that should be mentioned and checked.
return ngens(ambient_ring(X)) | ||
end | ||
|
||
@attr function dim(X::AbsSpec{<:Ring, <:MPolyRing}) |
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.
How are you making sure that you are not dealing with SpecZZ[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.
We already talked about this on the phone. Could you quickly document your suggestion here? What precisely is the oddity I have to take into account?
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.
Don't you just want to leave this to the commutative algebra side of OSCAR and call something like the dimension of the zero ideal of your ring? All the shortcuts should reside on in the Rings or Ideals part, where this problem naturally appears and is certainly already taken care of.
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.
Yes, sure. But I need to know what is the mathematical oddity that has to be addressed. I remember you said dim(Spec(ZZ[x,y]) == 3
, because dim(ZZ) == 1
. So what is the problem exactly and how do you suggest to resolve it? Should there be a function dim(R::MPolyRing)
that we then use? Or should we do a manual case analysis of the base_ring
?
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.
Yes, this is precisely the oddity: If we are dealing with a polynomial ring over the integers in n variables, its dimension is n+1. If we are dealing with a quotient of a polynomial ring over the integers by some ideal, it makes a difference, whether the ideal contains an integer or not, but the backend Singular should take care of the oddity automatically as soon as it gets called.
OSCAR already has a function dim(Ideal) which returns the dimension of (Ring/Ideal), and we should use that applied to the ideal <0> in our ring here -- even if it feels odd. This shifts the case analysis to the commutative algebra, which in turn might or might not do it by itself or leave it to a backend like Singular -- in any case, the schemes-code are not the right place for the case analysis.
experimental/Schemes/SpecOpen.jl
Outdated
@@ -909,7 +980,14 @@ function restriction( | |||
return SpecOpenMor(U, V, new_maps_on_patches, check=check) | |||
end | |||
|
|||
identity_map(U::SpecOpen) = SpecOpenMor(U, U, [SpecMor(V, ambient(U), gens(OO(V)), check=false) for V in affine_patches(U)], check=false) | |||
function identity_map(U::SpecOpen) | |||
[SpecMor(V, ambient(U), gens(OO(V)), check=false) for V in affine_patches(U)] |
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.
left-over of debugging?
@@ -1060,11 +1146,11 @@ function restriction_map(U::SpecOpen, X::Spec, h::MPolyElem; check::Bool=true) | |||
# first find some basic relation hᵏ= ∑ᵢ aᵢ⋅dᵢ | |||
d = gens(U) | |||
I = complement_ideal(U) | |||
(k, poh) = Oscar._minimal_power_such_that(h, x->(x in I)) | |||
a = coordinates(poh, I) | |||
(k, poh) = Oscar._minimal_power_such_that(h, x->(base_ring(I)(x) in I)) |
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.
_minimal_power_such_that: I understand the name and the content of the function, but the name is not reaaly self explanatory
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.
Yes, but this is an internal function so I did not bother to really explain it.
I was hoping it was self explanatory: _minimal_power_such_that(h, P)
returns (k, h^k)
where k
is the minimal power of h
such that property P(h^k)
holds.
) | ||
Y = ambient(U) | ||
R = ambient_ring(Y) | ||
R == ambient_ring(X) || error("rings not compatible") |
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.
small sideremark -- just to make sure not to forget it:
Your arguments are schemes, but your error message talks about rings. You could try to be more consistent in your wording (schemes not compatible/corresponding rings not compatible).
|
||
export SimpleGlueing | ||
|
||
@attributes mutable struct SimpleGlueing{LST<:AbsSpec, |
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.
Would you mind adding a short description/documentation for that struct? 6 arguments are hard to keep track of, if you do not see the mathematical data behind it.
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.
This is actually work in progress and not even tested, yet. I will add descriptions, eventually. However, this type will most probably not be user facing and the documentation should be made for the AbsGlueing
interface.
Which performance? I think we do not have any performance tests and nothing to compare it to. Either way: This will depend on the performance of computations in the rings used, so it's not part of this PR. About the TODOs: Can you be more specific? I do not recall leaving any TODOs that I could have addressed at this point. But I have some that fall into the realm of others or have pending dependencies on others. So I guess whatever TODOs are still there, they are there for a reason, should be merged for the time being, and be addressed when the time is ripe. For instance |
concerning performance: I was only wondering whether something might have struck you as significant while running test. This drastic change in the level of abstraction could have had sideeffects (in both directions....) concerning TODO: I was mostly thinking of 'coordinates' and 'simplify' and my impression coincides with your statement. |
I don't think that it is even reasonable at this point to start comparing performance. Simply because of the many inefficient hacks that are necessarily there for the time being. We will have to see again, once the new cached groebner bases are there and so on. This will stay work in progress and performance questions should be addressed by the people working on the respective rings/ideals, etc. I don't think it's part of the schemes, really. But I did not see any significant decrease of speed in the tests, no. |
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.
There is precisely one question/point left to be addressed. See comment at the line
return ngens(base_ring(OO(X)))-dim(X) | ||
# TODO: This is not 100% mathematically correct, since codimension is | ||
# a local concept. Should we therefore forbid this method? | ||
@attr function codim(X::Spec) |
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.
You are actually aiming at height(modulus(X)), right? This involves a primary (or equidimensional) decomposition in the general, i.e. non-equidimensional, case and should be referred to the algebraic side, where all the functionality should be available.
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.
Yes, height(modulus(OO(X))
would be one candidate. It depends what this function will be used for. This has probably been introduced to determine the expected rank of the jacobian matrix of some set of generators of modulus(OO(X))
. In that case, invoking a primary decomposition first does not seem reasonable. So I would really vote for deleting this function and leave it to the user to exctract the information they need for their particular applications.
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.
Why would you forbid this? It is well-defined globally and can be computed without primary decomposition, the hightest-dimensional component wins.
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.
Yes, you are right, of course the highest-dimension component wins (Wald vor Bäumen nicht gesehen....).
This should just be
dimension of ambient scheme - dimension of X.
By the way: You do not get as much sensible information from the Jacobian criterion in the arithmetic case anyway...
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.
Looks good.
Only one remark left to be discussed (maybe in direct communication).
@@ -455,34 +784,59 @@ function preimage( | |||
return Spec(MPolyQuoLocalizedRing(R, ideal(R, new_gens) + modulus(OO(X)), inverted_set(OO(X))*new_units)) | |||
end | |||
|
|||
function is_isomorphism(f::SpecMor) | |||
function preimage(f::AbsSpecMor, Z::AbsSpec{<:Ring, <:MPolyRing}; check::Bool=true) |
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.
Let me put the question more directly: How do you make sure that the user has not provided some Z which has nothing to do with f at all (maybe by mistake or typo in the name or because a previous computation had an unexpected result)? As you are not touching Z anywhere, no sanity check (apart from the fact that Z is a Spec of some polynomial ring) is performed -- neither explicitly nor implicitly.
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.
The most recent changes are ok and now all items are resolved.
This provides two major improvements for the schemes package: