Skip to content
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

Elliptic surfaces fixes #4177

Merged
6 changes: 5 additions & 1 deletion experimental/Schemes/src/BlowupMorphism.jl
Original file line number Diff line number Diff line change
Expand Up @@ -644,13 +644,17 @@ function produce_object_on_affine_chart(I::StrictTransformIdealSheaf, U::AbsAffi
f_loc = covering_morphism(f)[U]
V = codomain(f_loc)
IE_loc = IE(U)
@assert isone(ngens(IE_loc)) "ideal sheaf of exceptional locus is not principal"
tot = pullback(f_loc)(J(V))
#return saturation_with_index(tot, IE_loc)
# It is usually better to pass to the simplified covering to do the computations
simp_cov = simplified_covering(X)
U_simp = first([V for V in patches(simp_cov) if original(V) === U])
a, b = identification_maps(U_simp)
result, _ = saturation_with_index(pullback(a)(tot), pullback(a)(IE_loc))
# This used to be the following line. But we don't use the index, so we
# switch to the more performant version
# result, _ = saturation_with_index(pullback(a)(tot), pullback(a)(IE_loc))
result = _iterative_saturation(pullback(a)(tot), elem_type(OO(U_simp))[pullback(a)(u) for (u, _) in factor(lifted_numerator(first(gens(IE_loc))))])
return pullback(b)(result)
end

Expand Down
33 changes: 29 additions & 4 deletions experimental/Schemes/src/elliptic_surface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@
U = X0[1][1]
(x,y,t) = coordinates(U)
b = P
return ideal_sheaf(X0,U,[OO(U)(i) for i in [x*denominator(b[1])(t)-numerator(b[1])(t),y*denominator(b[2])(t)-numerator(b[2])(t)]])
return ideal_sheaf(X0,U,[OO(U)(i) for i in [x*denominator(b[1])(t)-numerator(b[1])(t),y*denominator(b[2])(t)-numerator(b[2])(t)]]; check=false)
end

function _section(X::EllipticSurface, P::EllipticCurvePoint)
Expand Down Expand Up @@ -1649,6 +1649,19 @@
return -G, kernel(G; side = :left)
end

# This function allows to store a reduction map to positive characteristic,
# e.g. for computing intersection numbers.
function reduction_to_pos_char(X::EllipticSurface, red_map::Map)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we turn this into a field of EllipticSurface?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss this in #4183 .

return get_attribute!(X, :reduction_to_pos_char) do
kk0 = base_ring(X)
@assert domain(red_map) === kk0
kkp = codomain(red_map)
@assert characteristic(kkp) > 0
_, result = base_change(red_map, X)
return red_map, result

Check warning on line 1661 in experimental/Schemes/src/elliptic_surface.jl

View check run for this annotation

Codecov / codecov/patch

experimental/Schemes/src/elliptic_surface.jl#L1654-L1661

Added lines #L1654 - L1661 were not covered by tests
end::Tuple{<:Map, <:Map}
end

@doc raw"""
basis_representation(X::EllipticSurface, D::WeilDivisor)

Expand All @@ -1661,9 +1674,21 @@
n = length(basis_ambient)
v = zeros(ZZRingElem, n)
@vprint :EllipticSurface 3 "computing basis representation of $D\n"
for i in 1:n
@vprintln :EllipticSurface 4 "intersecting with $(i): $(basis_ambient[i])"
v[i] = intersect(basis_ambient[i], D)
kk = base_ring(X)
if iszero(characteristic(kk)) && has_attribute(X, :reduction_to_pos_char)
red_map, bc = get_attribute(X, :reduction_to_pos_char)
for i in 1:n
@vprintln :EllipticSurface 4 "intersecting with $(i): $(basis_ambient[i])"

Check warning on line 1681 in experimental/Schemes/src/elliptic_surface.jl

View check run for this annotation

Codecov / codecov/patch

experimental/Schemes/src/elliptic_surface.jl#L1679-L1681

Added lines #L1679 - L1681 were not covered by tests

v[i] = intersect(base_change(red_map, basis_ambient[i]; scheme_base_change=bc),

Check warning on line 1683 in experimental/Schemes/src/elliptic_surface.jl

View check run for this annotation

Codecov / codecov/patch

experimental/Schemes/src/elliptic_surface.jl#L1683

Added line #L1683 was not covered by tests
base_change(red_map, D; scheme_base_change=bc))
end

Check warning on line 1685 in experimental/Schemes/src/elliptic_surface.jl

View check run for this annotation

Codecov / codecov/patch

experimental/Schemes/src/elliptic_surface.jl#L1685

Added line #L1685 was not covered by tests
else
for i in 1:n
@vprintln :EllipticSurface 4 "intersecting with $(i): $(basis_ambient[i])"

v[i] = intersect(basis_ambient[i], D)
end
end
@vprint :EllipticSurface 3 "done computing basis representation\n"
return v*inv(G)
Expand Down
16 changes: 10 additions & 6 deletions src/AlgebraicGeometry/Schemes/Covering/Objects/Attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,22 @@

for V in patches(orig_cov)
# Collect the patches in `ref_cov` refining V
V_ref = [U for U in patches(ref_cov) if decomp_dict[U][1] === V]
# Collect the corresponding complement equations
comp_eqns = [decomp_dict[U][2] for U in V_ref]
V_ref = [(U, h) for (U, (UV, h)) in decomp_dict if UV === V]
_compl(a) = sum(length(lifted_numerator(b)) + length(lifted_denominator(b)) for b in a[2]; init=0)
V_ref = sort!(V_ref, by=_compl)
# Start out from the original decomposition info
dec_inf = copy(decomposition_info(orig_cov)[V])
for (i, U) in enumerate(V_ref)
for (i, (U, h)) in enumerate(V_ref)
# Cast the already made decomposition info down to U
tmp = elem_type(OO(U))[OX(V, U)(i) for i in dec_inf] # help the compiler
# Append the equations for the previously covered patches
for j in 1:i-1
W = V_ref[j]
surplus = OX(V, U).(decomp_dict[W][2])
_, hh = V_ref[j]
if is_empty(hh) # The patch for hh already covered everything; this one can hence be discarded.
push!(tmp, one(OO(U)))
break

Check warning on line 123 in src/AlgebraicGeometry/Schemes/Covering/Objects/Attributes.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgebraicGeometry/Schemes/Covering/Objects/Attributes.jl#L122-L123

Added lines #L122 - L123 were not covered by tests
end
surplus = OX(V, U).(hh)
push!(tmp, prod(surplus; init=one(OO(U))))
end
set_decomposition_info!(ref_cov, U, tmp)
Expand Down
8 changes: 7 additions & 1 deletion src/AlgebraicGeometry/Schemes/Divisors/base_change.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
@assert codomain(scheme_base_change) === X
Y = domain(scheme_base_change)
kk = coefficient_ring(C)
return AlgebraicCycle(Y, kk, IdDict{AbsIdealSheaf, elem_type(kk)}(pullback(scheme_base_change, I)=>c for (I, c) in coefficient_dict(C)); check=false)
ideal_dict = IdDict{AbsIdealSheaf, elem_type(kk)}()
for (I, c) in coefficient_dict(C)
I_red = pullback(scheme_base_change, I)
has_attribute(I, :_self_intersection) && set_attribute!(I_red, :_self_intersection=>(get_attribute(I, :_self_intersection)::Int))
ideal_dict[I_red] = c
end
return AlgebraicCycle(Y, kk, ideal_dict; check=false)

Check warning on line 15 in src/AlgebraicGeometry/Schemes/Divisors/base_change.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgebraicGeometry/Schemes/Divisors/base_change.jl#L9-L15

Added lines #L9 - L15 were not covered by tests
end

function base_change(
Expand Down
13 changes: 0 additions & 13 deletions src/AlgebraicGeometry/Schemes/Sheaves/CoherentSheaves.jl
Original file line number Diff line number Diff line change
Expand Up @@ -784,19 +784,6 @@ end
return C
end

function inherit_decomposition_info!(C::Covering, X::AbsCoveredScheme)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove this? Was it a duplicate?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. And it was wrong. Fortunately, it seemed to be used nowhere.

D = default_covering(X)
OOX = OO(X)
if has_decomposition_info(D)
for U in patches(C)
V = __find_chart(U, D)
phi = OOX(V, U)
set_decomposition_info!(C, U, phi.(decomposition_info(D)[V]))
end
end
return C
end

@attr Covering function trivializing_covering(M::HomSheaf)
X = scheme(M)
OOX = OO(X)
Expand Down
11 changes: 6 additions & 5 deletions src/AlgebraicGeometry/Schemes/Sheaves/IdealSheaves.jl
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ end
end

@attr Bool function has_dimension_leq_zero(I::Ideal)
is_one(I) && return true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove this line?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's superfluous. It's usually not easier to compute this than the dimension. Both are the same Groebner basis computation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Is the GB stored? Or could it be that it is discarded and just the is_one attribute is true?

return dim(I) <= 0
end

Expand All @@ -354,14 +353,13 @@ end
P = base_ring(R)::MPolyRing
J = ideal(P, numerator.(gens(I)))
has_dimension_leq_zero(J) && return true
is_one(I) && return true
return dim(I) <= 0
end

@attr Bool function has_dimension_leq_zero(I::MPolyQuoLocalizedIdeal)
R = base_ring(I)
P = base_ring(R)::MPolyRing
J = ideal(P, lifted_numerator.(gens(I)))
J = pre_saturated_ideal(pre_image_ideal(I))
has_dimension_leq_zero(J) && return true
is_one(I) && return true
return dim(I) <= 0
Expand Down Expand Up @@ -562,9 +560,12 @@ function extend!(
end

function _iterative_saturation(I::Ideal, f::RingElem)
fac = factor(f)
return _iterative_saturation(I, typeof(f)[u for (u, _) in factor(f)])
end

function _iterative_saturation(I::Ideal, f::Vector{T}) where{T<:RingElem}
R = base_ring(I)
for (u, k) in fac
for u in f
I = saturation(I, ideal(R, u))
end
return I
Expand Down
2 changes: 1 addition & 1 deletion test/AlgebraicGeometry/Schemes/CoveredScheme.jl
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
new_cov = Covering(append!(AbsAffineScheme[V1, V2], patches(orig_cov)[2:end]))
Oscar.inherit_gluings!(new_cov, orig_cov)
Oscar.inherit_decomposition_info!(X, new_cov, orig_cov=orig_cov)
@test Oscar.decomposition_info(new_cov)[V2] == [OO(V2)(x-1)]
@test Oscar.decomposition_info(new_cov)[V1] == [OO(V1)(x)]
end

@testset "fiber products of coverings" begin
Expand Down
Loading