-
Notifications
You must be signed in to change notification settings - Fork 123
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
Pullback of rational functions along strict transforms #2681
Changes from 12 commits
b82103a
40fabe8
b19015f
87b0814
022f6ea
55e8503
4c8a403
ee6cfeb
9c46e89
abb4910
4c0432d
9f8262e
f7dcfe5
739458e
e1b9e10
bdb6201
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,8 +73,15 @@ with restriction | |
``` | ||
""" | ||
@attributes mutable struct BlowupMorphism{ | ||
CodomainType<:AbsCoveredScheme | ||
} # TODO: Derive this from AbsCoveredSchemeMorphism ? | ||
DomainType<:AbsCoveredScheme, # Not a concrete type in general because this is lazy | ||
CodomainType<:AbsCoveredScheme, | ||
BaseMorphismType # Nothing in case of no base change | ||
} <: AbsCoveredSchemeMorphism{ | ||
DomainType, | ||
CodomainType, | ||
BaseMorphismType, | ||
BlowupMorphism | ||
} | ||
projective_bundle::CoveredProjectiveScheme | ||
codomain::CodomainType # in general a CoveredScheme | ||
center::IdealSheaf # on codomain | ||
|
@@ -88,10 +95,13 @@ with restriction | |
) | ||
X = base_scheme(IP) | ||
X === scheme(I) || error("ideal sheaf not compatible with blown up variety") | ||
return new{typeof(X)}(IP, X, I) | ||
return new{AbsCoveredScheme, typeof(X), Nothing}(IP, X, I) | ||
end | ||
end | ||
|
||
### Forward the essential functionality | ||
underlying_morphism(phi::BlowupMorphism) = projection(phi) | ||
|
||
function domain(p::BlowupMorphism) | ||
if !isdefined(p, :domain) | ||
p.domain = covered_scheme(p.projective_bundle) | ||
|
@@ -151,10 +161,60 @@ function strict_transform(p::BlowupMorphism, inc::CoveredClosedEmbedding) | |
inc_Z_trans = CoveredClosedEmbedding(Y, I_trans, | ||
covering=simplified_covering(Y), # Has been set by the previous call | ||
check=false) | ||
inc_cov = covering_morphism(inc_Z_trans) | ||
inc_dom_cov = covering_morphism(inc_Z_trans) | ||
inc_cod_cov = covering_morphism(inc) | ||
|
||
Z_trans = domain(inc_Z_trans) | ||
pr_res = restrict(projection(p), inc_Z_trans, inc) | ||
|
||
if has_attribute(p, :isomorphism_on_open_subset) | ||
OOX = OO(X) | ||
OOY = OO(Y) | ||
p_iso = isomorphism_on_open_subset(p) | ||
U = domain(p_iso)::PrincipalOpenSubset | ||
V = codomain(p_iso)::PrincipalOpenSubset | ||
V_amb = ambient_scheme(V) | ||
U_amb = ambient_scheme(U) | ||
|
||
# Given all the refinements that potentially had to be done, we have | ||
# to do the following. | ||
# - Find a `patch` `U_sub` of the `domain` of `inc_dom_cov` for which | ||
# inc_cod : U_sub -> W has a codomain `W` which has `U_amb` as an | ||
# ancestor. Since `U_amb` is one of the `affine_charts` of `X`, this will work. | ||
simonbrandhorst marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# - pr_res : U_amb -> V_amb has some codomain such that there exists | ||
# an ancestor `VV` in the `domain` of `inc_dom_cov` such that | ||
# inc_dom : VV -> W' has a codomain with `V_amb` as an ancestor. | ||
# - outside the `complement_equation`s of `U` and `V` the projection | ||
# was an isomorphism. Then the restriction of `pr_res` to those | ||
# complements in `U_sub` and `V_sub` also is. | ||
k = findfirst(x->has_ancestor(y->y===U_amb, codomain(inc_dom_cov[x])), patches(domain(inc_dom_cov))) | ||
U_sub = patches(domain(inc_dom_cov))[k] | ||
iso_U_sub = _flatten_open_subscheme(U_sub, domain(inc_dom_cov[U_sub])) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what does this do and why do you do it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line 192 is deprecated and superfluous. Did you mean that? In that case: Thanks for catching! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep |
||
U_sub_res = PrincipalOpenSubset(U_sub, | ||
pullback(inc_dom_cov[U_sub])( | ||
OOX(U_amb, codomain(inc_dom_cov[U_sub]))( | ||
complement_equation(U) | ||
) | ||
) | ||
) | ||
|
||
pr_res_cov = covering_morphism(pr_res) | ||
pr_sub = pr_res_cov[U_sub] | ||
|
||
V_sub = codomain(pr_sub) | ||
@assert has_ancestor(x->any(y->y===x, patches(domain(inc_cod_cov))), V_sub) | ||
V_sub_inc, comp_eqns = _find_chart(V_sub, domain(inc_cod_cov)) | ||
OOZ = OO(Z) | ||
dummy_dom = codomain(V_sub_inc) | ||
dummy_map = inc_cod_cov[dummy_dom] | ||
dummy_cod = codomain(dummy_map) | ||
V_sub_res = PrincipalOpenSubset(V_sub, | ||
OOZ(dummy_dom, V_sub)(pullback(dummy_map)(OOY(V_amb, dummy_cod)(complement_equation(V))))) | ||
result = restrict(pr_sub, U_sub_res, V_sub_res) | ||
# TODO: Obtain the inverse another way? | ||
@assert is_isomorphism(result) | ||
set_attribute!(pr_res, :isomorphism_on_open_subset, result) | ||
end | ||
return Z_trans, inc_Z_trans, pr_res | ||
end | ||
|
||
|
@@ -498,13 +558,17 @@ end | |
return p_res | ||
end | ||
|
||
### Some functionality used by function fields | ||
|
||
# If set this attribute shall return some isomorphism on some open subsets of the domain | ||
# and codomain of phi. If both are irreducible, this automatically implies that both are | ||
# dense, but we do not check for this. | ||
@attr AbsSpecMor function isomorphism_on_open_subset(f::BlowupMorphism) | ||
pr = isomorphism_on_complement_of_center(f) | ||
X = domain(pr) | ||
Y = codomain(pr) | ||
pr_cov = covering_morphism(pr) | ||
U = first(patches(domain(pr_cov))) | ||
pr_res = pr_cov[U] | ||
X = domain(f) | ||
Y = codomain(f) | ||
iso_dict = get_attribute(f, :isos_on_complement_of_center) | ||
pr_res = first(values(iso_dict)) | ||
U = domain(pr_res) | ||
V = codomain(pr_res) | ||
iso_U = _flatten_open_subscheme(U, default_covering(X)) | ||
U_flat = codomain(iso_U) | ||
|
@@ -544,3 +608,20 @@ function pushforward(f::BlowupMorphism, g::VarietyFunctionFieldElem) | |
pfg = fraction(pullback(phi)(OO(V)(numerator(h))))//fraction(pullback(phi)(OO(V)(denominator(h)))) | ||
return FY.(pfg) | ||
end | ||
|
||
@attr AbsSpecMor function isomorphism_on_open_subset(phi::AbsCoveredSchemeMorphism) | ||
error("attribute not found; this needs to be set manually in general") | ||
end | ||
|
||
function compose(f::BlowupMorphism, g::BlowupMorphism) | ||
return composite_map(f, g) | ||
end | ||
|
||
function compose(f::BlowupMorphism, g::AbsCoveredSchemeMorphism) | ||
return composite_map(f, g) | ||
end | ||
|
||
function compose(f::AbsCoveredSchemeMorphism, g::BlowupMorphism) | ||
return composite_map(f, g) | ||
end | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -568,3 +568,162 @@ function CoveredClosedEmbedding(X::AbsCoveredScheme, I::IdealSheaf; | |||||||||||||||||||||||||||
return CoveredClosedEmbedding(Z, X, cov_inc, ideal_sheaf=I, check=false) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
######################################################################## | ||||||||||||||||||||||||||||
# Composite morphism of covered schemes | ||||||||||||||||||||||||||||
######################################################################## | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
@attributes mutable struct CompositeCoveredSchemeMorphism{ | ||||||||||||||||||||||||||||
simonbrandhorst marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
DomainType<:AbsCoveredScheme, | ||||||||||||||||||||||||||||
CodomainType<:AbsCoveredScheme, | ||||||||||||||||||||||||||||
BaseMorphismType | ||||||||||||||||||||||||||||
} <: AbsCoveredSchemeMorphism{ | ||||||||||||||||||||||||||||
DomainType, | ||||||||||||||||||||||||||||
CodomainType, | ||||||||||||||||||||||||||||
BaseMorphismType, | ||||||||||||||||||||||||||||
CoveredSchemeMorphism | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
maps::Vector{<:AbsCoveredSchemeMorphism} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
# fields for caching | ||||||||||||||||||||||||||||
composed_map::AbsCoveredSchemeMorphism | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
function CompositeCoveredSchemeMorphism(maps::Vector{<:AbsCoveredSchemeMorphism}) | ||||||||||||||||||||||||||||
n = length(maps) | ||||||||||||||||||||||||||||
for i in 1:n-1 | ||||||||||||||||||||||||||||
@assert codomain(maps[i]) === domain(maps[i+1]) "maps are not compatible" | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
# TODO: Take care of non-trivial base changes! | ||||||||||||||||||||||||||||
return new{typeof(domain(first(maps))), typeof(codomain(maps[end])), Nothing}(maps) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
### Essential getters | ||||||||||||||||||||||||||||
maps(f::CompositeCoveredSchemeMorphism) = f.maps | ||||||||||||||||||||||||||||
domain(f::CompositeCoveredSchemeMorphism) = domain(first(f.maps)) | ||||||||||||||||||||||||||||
codomain(f::CompositeCoveredSchemeMorphism) = codomain(f.maps[end]) | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
### Forwarding essential functionality (to be avoided!) | ||||||||||||||||||||||||||||
function underlying_morphism(f::CompositeCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
if !isdefined(f, :composed_map) | ||||||||||||||||||||||||||||
result = underlying_morphism(first(maps(f)))::CoveredSchemeMorphism | ||||||||||||||||||||||||||||
for i in 2:length(maps(f)) | ||||||||||||||||||||||||||||
result = compose(result, underlying_morphism(maps(f)[i]))::CoveredSchemeMorphism | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
f.composed_map = result | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
return f.composed_map::CoveredSchemeMorphism | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
### Specialized functionality | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
# Casting into the minimal concrete type for AbsCoveredSchemeMorphism | ||||||||||||||||||||||||||||
function CoveredSchemeMorphism(f::CompositeCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
return underlying_morphism(f) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
function CoveredSchemeMorphism(f::CoveredSchemeMorphism) | ||||||||||||||||||||||||||||
return f | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
######################################################################## | ||||||||||||||||||||||||||||
# The standard constructors | ||||||||||||||||||||||||||||
######################################################################## | ||||||||||||||||||||||||||||
@doc raw""" | ||||||||||||||||||||||||||||
composite_map(f::AbsCoveredSchemeMorphism, g::AbsCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
Realize the composition ``x → g(f(x))`` as a composite map, i.e. an | ||||||||||||||||||||||||||||
instance of `CompositeCoveredSchemeMorphism`. | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
# Examples | ||||||||||||||||||||||||||||
```jldoctest | ||||||||||||||||||||||||||||
julia> IA2 = affine_space(QQ, [:x, :y]) | ||||||||||||||||||||||||||||
Affine space of dimension 2 | ||||||||||||||||||||||||||||
over rational field | ||||||||||||||||||||||||||||
with coordinates [x, y] | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
julia> (x, y) = gens(OO(IA2)); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
julia> I = ideal(OO(IA2), [x, y]); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
julia> pr = blow_up(IA2, I); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
julia> JJ = ideal_sheaf(exceptional_divisor(pr)); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
julia> inc_E = oscar.CoveredClosedEmbedding(domain(pr), JJ); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
julia> comp = oscar.composite_map(inc_E, pr) | ||||||||||||||||||||||||||||
Composite morphism of | ||||||||||||||||||||||||||||
Morphism: scheme over QQ covered with 2 patches -> scheme over QQ covered with 2 patches | ||||||||||||||||||||||||||||
Blow-up: scheme over QQ covered with 2 patches -> scheme over QQ covered with 1 patch | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
julia> oscar.maps(comp)[1] === inc_E | ||||||||||||||||||||||||||||
true | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
julia> oscar.maps(comp)[2] === pr | ||||||||||||||||||||||||||||
true | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||
function composite_map(f::AbsCoveredSchemeMorphism, g::AbsCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
return CompositeCoveredSchemeMorphism([f, g]) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
function composite_map(f::AbsCoveredSchemeMorphism, g::CompositeCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
return CompositeCoveredSchemeMorphism(pushfirst!(Vector{AbsCoveredSchemeMorphism}(copy(maps(g))), f)) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
function composite_map(f::CompositeCoveredSchemeMorphism, g::CompositeCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
return CompositeCoveredSchemeMorphism(vcat(maps(f), maps(g))) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
function composite_map(f::CompositeCoveredSchemeMorphism, g::AbsCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
return CompositeCoveredSchemeMorphism(push!(Vector{AbsCoveredSchemeMorphism}(copy(maps(f))), g)) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
######################################################################## | ||||||||||||||||||||||||||||
# Printing | ||||||||||||||||||||||||||||
######################################################################## | ||||||||||||||||||||||||||||
function Base.show(io::IO, f::CompositeCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
io = pretty(io) | ||||||||||||||||||||||||||||
if get(io, :supercompact, false) | ||||||||||||||||||||||||||||
print(io, "Composite morphism") | ||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||
map_string = "$(domain(f)) -> " | ||||||||||||||||||||||||||||
for i in 2:length(maps(f)) | ||||||||||||||||||||||||||||
map_string = map_string * "$(domain(map(f)[i])) -> " | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
map_string = map_string * "$(codomain(map(f)[end]))" | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
print(io, "Composition of ", map_string) | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to print to an intermediate string
Suggested change
|
||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
function Base.show(io::IO, ::MIME"text/plain", f::CompositeCoveredSchemeMorphism) | ||||||||||||||||||||||||||||
io = pretty(io) | ||||||||||||||||||||||||||||
println(io, "Composite morphism of", Indent()) | ||||||||||||||||||||||||||||
for g in maps(f) | ||||||||||||||||||||||||||||
println(io, g) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
######################################################################## | ||||||||||||||||||||||||||||
# Bound functionality | ||||||||||||||||||||||||||||
######################################################################## | ||||||||||||||||||||||||||||
function pushforward(f::CompositeCoveredSchemeMorphism, a::VarietyFunctionFieldElem) | ||||||||||||||||||||||||||||
result = a | ||||||||||||||||||||||||||||
for g in maps(f) | ||||||||||||||||||||||||||||
result = pushforward(g, result) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
return result | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
function pullback(f::CompositeCoveredSchemeMorphism, a::VarietyFunctionFieldElem) | ||||||||||||||||||||||||||||
result = a | ||||||||||||||||||||||||||||
for g in reverse(maps(f)) | ||||||||||||||||||||||||||||
result = pullback(g, result) | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
return result | ||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
### Missing compatibility | ||||||||||||||||||||||||||||
underlying_morphism(f::CoveredSchemeMorphism) = 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.
Why is
U_amb
a chart ofX
? It seems to me that it is a chart of Y?What is the domain and codomain of p_iso? (i.e. does it point in the same direction as p? or the opposite one?)