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

Strict transform of an ideal in Cox ring #4154

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions experimental/Schemes/src/ToricBlowups/methods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,119 @@ end
function total_transform(f::AbsBlowupMorphism, II::AbsIdealSheaf)
return pullback(f, II)
end

@doc raw"""
_minimal_supercone(X::NormalToricVariety, r::AbstractVector{<:IntegerUnion})

Given a ray $r$ inside the support of the simplicial fan $Σ$ of a normal toric variety~$X$, not coinciding with any ray in $Σ(1)$, return the unique cone $σ$ in $Σ$ such that $r$ is in the relative interior of $σ$.

# Examples
```jldoctest
julia> X = projective_space(NormalToricVariety, 3)
Normal toric variety

julia> r = [1, 1, 0]
2-element Vector{Int64}:
1
1

julia> Oscar._minimal_supercone(X, r)
Polyhedral cone in ambient dimension 3

julia> rays(c)
2-element SubObjectIterator{RayVector{QQFieldElem}}:
[1, 0, 0]
[0, 1, 0]
```
"""
function _minimal_supercone(X::NormalToricVariety, r::AbstractVector{<:Union{IntegerUnion, QQFieldElem}})
@assert is_orbifold(X) "Only implemented when fan is simplicial"
contained_in_support_of_fan = false
mcone = maximal_cones(X)[1] # initialize `mcone`, fixing its type

mcones = maximal_cones(X)
while true
contained_in_subcone = false
for c in mcones
if r in c
contained_in_support_of_fan = true
contained_in_subcone = true
mcone = c
end
end
@assert contained_in_support_of_fan "Ray not contained in the support of the fan"
!contained_in_subcone && return mcone
n_rays(mcone) == 1 && return mcone

# set mcones to be the facets of mcone
mcones = [cone(setdiff(collect(rays(mcone)), [ray])) for ray in rays(mcone)]
end
end

function _cox_ring_homomorphism(f::ToricBlowupMorphism)
@assert is_normal(codomain(f))
@assert is_orbifold(codomain(f)) "Only implemented when fan is simplicial"
Y = domain(f)
@assert !has_torusfactor(codomain(f)) "Only implemented when there are no torus factors"
@assert n_rays(Y) == n_rays(codomain(f)) + 1 "Only implemented when the blowup adds a ray"
@assert grading_group(cox_ring(Y)) === class_group(Y)
G = class_group(Y)
Comment on lines +102 to +103
Copy link
Collaborator

Choose a reason for hiding this comment

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

First define G as the class_group(Y) and then use G in the assert, since you need G afterwards anyway and in the case of failure of the assert, you did not loose anything.

n = number_of_generators(G)
new_ray = rays(domain(f))[index_of_new_ray(f)]
c = Oscar._minimal_supercone(Y, new_ray)
U = affine_normal_toric_variety(c)
d = order(class_group(U))
# TODO: finish this...


new_var = cox_ring(Y)[index_of_new_ray(f)]
M = generator_degrees(cox_ring(Y))
@assert M[index_of_new_ray(f)][n] < 0 "Assuming the blowup adds a new column vector to `Oscar.generator_degrees(cox_ring(codomain(f)))`, the entry of that vector corresponding to the new ray should be negative. If not, multiply by -1."
Copy link
Collaborator

Choose a reason for hiding this comment

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

Your error messages in case of failing asserts seem pretty long to me. Please try to make them shorter and maybe add appropriate notes to the documentation instead.

ind = Int64(abs(M[index_of_new_ray(f)][n]))
for i in 1:n_rays(Y)
i == index_of_new_ray(f) || @assert M[i][n] >= 0 "Assuming the blowup adds a new column vector to `Oscar.generator_degrees(cox_ring(codomain(f)))` for which the entry corresponding to the new ray is negative, the entries corresponding to all the other rays should be nonnegative. If not, add integer multiples of the other columns until it is."
Comment on lines +116 to +117
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you want to say
@assert findfirst(M[i][n] < 0 && i != index_of_new_ray(f) , 1:n_rays(Y)) === nothing

end
if ind == 1
S = cox_ring(Y)
inj = hom(S, S, gens(S))
elseif ind > 1
# Change grading so that the negative entry would be -1
xs = ZZRingElem[]
for i in 1:n-1
push!(xs, M[index_of_new_ray(f)][i])
end
push!(xs, ZZRingElem(-1))
M_new = deepcopy(M)
M_new[index_of_new_ray(f)] = G(xs)
S_ungraded = forget_grading(cox_ring(Y))
S = grade(S_ungraded, M_new)[1]
inj = hom(cox_ring(Y), S, gens(S))
end
F = hom(cox_ring(codomain(f)), S, [inj(new_var^(M[i][n])*S[i]) for i in 1:n_rays(Y) if i != index_of_new_ray(f)])
return (F, ind)
end

function strict_transform(f::ToricBlowupMorphism, I::MPolyIdeal)
F, ind = _cox_ring_homomorphism(f)
Y = domain(f)
Comment on lines +139 to +141
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for looking into this!

This is to compute the strict transform of an ideal in the cox ring of the codomain, correct? I would probably insert an @assert here, or something.

Once this is done, I would be curious to compare performance with the chart-based approach!

S = cox_ring(Y)
new_var = S[index_of_new_ray(f)]
J = saturation(F(I), ideal(new_var))
if ind == 1
return J
elseif ind > 1
xs = elem_type(S)[]
for gen in gens(J)
new_exponent_vectors = Vector{Int64}[]
for i in 1:length(terms(gen))
exp_vec = exponent_vector(gen, i)
bool, result = divides(exp_vec[index_of_new_ray(f)], ind)
@assert bool "Given the finite set of generators of `J`, the exponent of `new_var` in every monomial of every member should be divisible by `ind`. If not, first make sure that none of the generators of `J` is divisible by `new_var`."
exp_vec[index_of_new_ray(f)] = result
push!(new_exponent_vectors, exp_vec)
end
push!(xs, S(collect(coefficients(gen)), new_exponent_vectors))
end
return ideal(cox_ring(Y), xs)
end
end
Loading