From c0c07a74ec159e6d172fafb7d7ffe4a74da551c4 Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Wed, 13 Nov 2024 17:30:24 +0100 Subject: [PATCH] Intersection theory: hom --> map, more docu (#4304) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Intersection theory: hom --> map, more docu --------- Co-authored-by: Lars Göttgens --- .../docs/src/AbstractBundles.md | 8 ++ .../docs/src/AbstractVarietyMaps.md | 8 +- .../IntersectionTheory/docs/src/examples.md | 2 +- .../src/IntersectionTheory.jl | 8 +- experimental/IntersectionTheory/src/Main.jl | 126 +++++++++++++----- experimental/IntersectionTheory/src/blowup.jl | 6 +- .../IntersectionTheory/test/runtests.jl | 26 ++-- 7 files changed, 131 insertions(+), 53 deletions(-) diff --git a/experimental/IntersectionTheory/docs/src/AbstractBundles.md b/experimental/IntersectionTheory/docs/src/AbstractBundles.md index 0e54dc3c17ed..804a67e15334 100644 --- a/experimental/IntersectionTheory/docs/src/AbstractBundles.md +++ b/experimental/IntersectionTheory/docs/src/AbstractBundles.md @@ -89,6 +89,14 @@ exterior_power(F::AbstractBundle, k::Int) symmetric_power(F::AbstractBundle, k::Int) ``` +```@docs +pullback(f::AbstractVarietyMap, F::AbstractBundle) +``` + +```@docs +pushforward(f::AbstractVarietyMap, F::AbstractBundle) +``` + ## Tests on Abstract Bundles ```@docs diff --git a/experimental/IntersectionTheory/docs/src/AbstractVarietyMaps.md b/experimental/IntersectionTheory/docs/src/AbstractVarietyMaps.md index 830fdebe618d..d2c3bf83c3aa 100644 --- a/experimental/IntersectionTheory/docs/src/AbstractVarietyMaps.md +++ b/experimental/IntersectionTheory/docs/src/AbstractVarietyMaps.md @@ -8,7 +8,11 @@ DocTestSetup = Oscar.doctestsetup() ## Constructors ```@docs -hom(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = "x") +map(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = "x") +``` + +```@docs +identity_map(X::AbstractVariety) ``` ## Underlying Data of an Abstract Variety Map @@ -28,7 +32,7 @@ dim(f::AbstractVarietyMap) ``` ```@docs -pullback(f::AbstractVarietyMap, x::MPolyDecRingElem) +pullback(f::AbstractVarietyMap, y::MPolyDecRingElem) ``` ```@docs diff --git a/experimental/IntersectionTheory/docs/src/examples.md b/experimental/IntersectionTheory/docs/src/examples.md index dcc97a382f7e..7aa595197e25 100644 --- a/experimental/IntersectionTheory/docs/src/examples.md +++ b/experimental/IntersectionTheory/docs/src/examples.md @@ -65,7 +65,7 @@ h julia> H = gens(P5)[1] H -julia> i = hom(P2, P5, [2*h]) +julia> i = map(P2, P5, [2*h]) AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5 julia> Bl, E, j = blowup(i) diff --git a/experimental/IntersectionTheory/src/IntersectionTheory.jl b/experimental/IntersectionTheory/src/IntersectionTheory.jl index 6354f3e43a17..ac34405a95a9 100644 --- a/experimental/IntersectionTheory/src/IntersectionTheory.jl +++ b/experimental/IntersectionTheory/src/IntersectionTheory.jl @@ -6,7 +6,7 @@ import ..Oscar: AffAlgHom, Ring, MPolyDecRingElem, symmetric_power, exterior_pow import ..Oscar: basis, betti_numbers, chow_ring, codomain, degree, det, dim, domain, dual, gens, hilbert_polynomial, hom, integral, rank, signature, partitions import ..Oscar.AbstractAlgebra: combinations import ..Oscar.AbstractAlgebra.Generic: FunctionalMap -import ..Oscar: pullback, pushforward, base, OO, product, compose +import ..Oscar: pullback, pushforward, base, OO, product, compose, identity_map, map import ..Oscar: trivial_line_bundle import ..Oscar: intersection_matrix import ..Oscar: chern_class @@ -41,10 +41,13 @@ export dual_basis export euler export euler_pairing export graph +export hom export hyperplane_class +export identity_map export l_genus export linear_subspaces_on_hypersurface export line_bundle +export map export OO export point_class export pontryagin_class @@ -120,11 +123,14 @@ export dual_basis export euler export euler_pairing export graph +export hom export hyperplane_class export intersection_matrix +export identity_map export l_genus export linear_subspaces_on_hypersurface export line_bundle +export map export OO export point_class export pontryagin_class diff --git a/experimental/IntersectionTheory/src/Main.jl b/experimental/IntersectionTheory/src/Main.jl index 8091e6d56c8e..36e04ad1f0aa 100644 --- a/experimental/IntersectionTheory/src/Main.jl +++ b/experimental/IntersectionTheory/src/Main.jl @@ -342,15 +342,15 @@ end # AbstractVarietyMap # @doc raw""" - hom(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = "x") + map(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = "x") Return an abstract variety map `X` $\rightarrow$ `Y` by specifying the pullbacks of the generators of the Chow ring of `Y`. !!! note - The corresponding pushforward can be automatically computed in certain cases. + The corresponding pushforward will be automatically computed in certain cases. -In case of an inclusion $i:X\hookrightarrow Y$ where the class of `X` is not +In the case of an inclusion `X` $\hookrightarrow$ `Y` where the class of `X` is not present in the Chow ring of `Y`, use the argument `inclusion = true`. Then, a copy of `Y` will be created, with extra classes added so that one can pushforward all classes on `X`. @@ -361,20 +361,29 @@ pushforward all classes on `X`. julia> P2xP2 = abstract_projective_space(2, symbol = "k")*abstract_projective_space(2, symbol = "l") AbstractVariety of dim 4 -julia> P8 = abstract_projective_space(8) -AbstractVariety of dim 8 - julia> k, l = gens(P2xP2) 2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}: k l -julia> Se = hom(P2xP2, P8, [k+l]) # Segre embedding +julia> P8 = abstract_projective_space(8) +AbstractVariety of dim 8 + +julia> h = gens(P8)[1] +h + +julia> Se = map(P2xP2, P8, [k+l]) # Segre embedding AbstractVarietyMap from AbstractVariety of dim 4 to AbstractVariety of dim 8 -``` +julia> pullback(Se, h) +k + l + +julia> pushforward(Se, k+l) +6*h^5 + +``` """ -function hom(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = "x") +function map(X::AbstractVariety, Y::AbstractVariety, fˣ::Vector, fₓ = nothing; inclusion::Bool = false, symbol::String = "x") AbstractVarietyMap(X, Y, fˣ, fₓ) # !inclusion && return AbstractVarietyMap(X, Y, fˣ, fₓ) # _inclusion(AbstractVarietyMap(X, Y, fˣ), symbol=symbol) @@ -398,7 +407,7 @@ AbstractVariety of dim 5 julia> h = gens(P2)[1] h -julia> i = hom(P2, P5, [2*h]) +julia> i = map(P2, P5, [2*h]) AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5 julia> dim(i) @@ -425,13 +434,13 @@ AbstractBundle of rank 2 on AbstractVariety of dim 2 julia> PT = abstract_projective_bundle(T) AbstractVariety of dim 3 -julia> pi = structure_map(PT) +julia> pr = structure_map(PT) AbstractVarietyMap from AbstractVariety of dim 3 to AbstractVariety of dim 2 -julia> PBT = pullback(pi, T) +julia> PBT = pullback(pr, T) AbstractBundle of rank 2 on AbstractVariety of dim 3 -julia> PBT*OO(PT, 1) - OO(PT) == tangent_bundle(pi) # relative Euler sequence +julia> PBT*OO(PT, 1) - OO(PT) == tangent_bundle(pr) # relative Euler sequence true ``` @@ -469,12 +478,12 @@ AbstractVariety of dim 5 julia> h = gens(P2)[1] h +julia> i = map(P2, P5, [2*h]) +AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5 + julia> H = gens(P5)[1] H -julia> i = hom(P2, P5, [2*h]) -AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5 - julia> pullback(i, H) 2*h @@ -486,6 +495,29 @@ pullback(f::AbstractVarietyMap, x::MPolyDecRingOrQuoElem) = f.pullback(x) pullback(f::AbstractVarietyMap, F::AbstractBundle) Return the pullback of `F` via `f`. + +# Examples + +```jldoctest +julia> P2 = abstract_projective_space(2) +AbstractVariety of dim 2 + +julia> P5 = abstract_projective_space(5, symbol = "H") +AbstractVariety of dim 5 + +julia> h = gens(P2)[1] +h + +julia> i = map(P2, P5, [2*h]) +AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5 + +julia> E = pullback(i, OO(P2,1)) +AbstractBundle of rank 1 on AbstractVariety of dim 2 + +julia> total_chern_class(E) +2*h + 1 + +``` """ pullback(f::AbstractVarietyMap, F::AbstractBundle) = AbstractBundle(f.domain, f.pullback(chern_character(F))) @@ -506,7 +538,7 @@ AbstractVariety of dim 5 julia> h = gens(P2)[1] h -julia> i = hom(P2, P5, [2*h]) +julia> i = map(P2, P5, [2*h]) AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5 julia> pushforward(i, h) @@ -519,10 +551,38 @@ pushforward(f::AbstractVarietyMap, x::MPolyDecRingOrQuoElem) = f.pushforward(x) pushforward(f::AbstractVarietyMap, F::AbstractBundle) Return the pushforward of `F` via `f`, that is, return the alternating sum of all direct images of `F` via `f`. + +# Examples + +```jldoctest +julia> P2 = abstract_projective_space(2) +AbstractVariety of dim 2 + +julia> P5 = abstract_projective_space(5, symbol = "H") +AbstractVariety of dim 5 + +julia> h = gens(P2)[1] +h + +julia> i = map(P2, P5, [2*h]) +AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5 + +julia> E = pushforward(i, OO(P2,1)) +AbstractBundle of rank 0 on AbstractVariety of dim 5 + +julia> total_chern_class(E) +168*H^5 + 42*H^4 + 8*H^3 + 1 + +``` """ pushforward(f::AbstractVarietyMap, F::AbstractBundle) = AbstractBundle(f.codomain, f.pushforward(chern_character(F) * todd_class(f))) # Grothendieck-Hirzebruch-Riemann-Roch -function identity_hom(X::V) where V <: AbstractVarietyT +@doc raw""" + identity_map(X::AbstractVariety) + +Return the identity map on `X`. +""" +function identity_map(X::AbstractVariety) AbstractVarietyMap(X, X, gens(X.ring), map_from_func(identity, X.ring, X.ring)) end @@ -1174,8 +1234,8 @@ julia> hilbert_polynomial(P2) hilbert_polynomial(X::AbstractVariety) = hilbert_polynomial(trivial_line_bundle(X)) # find canonically defined morphism from X to Y -function _hom(X::AbstractVariety, Y::AbstractVariety) - X == Y && return identity_hom(X) +function _map(X::AbstractVariety, Y::AbstractVariety) + X == Y && return identity_map(X) # first handle the case where X is a (fibered) product projs = get_attribute(X, :projections) if projs !== nothing @@ -1196,14 +1256,14 @@ end # morphisms for points are convenient, but are not desired when doing coercion @doc raw""" - hom(X::AbstractVariety, Y::AbstractVariety) + map(X::AbstractVariety, Y::AbstractVariety) -Return a canonically defined morphism from `X` to `Y`. +Return a canonically defined map from `X` to `Y`. """ -function hom(X::AbstractVariety, Y::AbstractVariety) - get_attribute(Y, :point) !== nothing && return hom(X, Y, [X(0)]) # Y is a point - get_attribute(X, :point) !== nothing && return hom(X, Y, repeat([X(0)], length(gens(Y.ring)))) # X is a point - _hom(X, Y) +function map(X::AbstractVariety, Y::AbstractVariety) + get_attribute(Y, :point) !== nothing && return map(X, Y, [X(0)]) # Y is a point + get_attribute(X, :point) !== nothing && return map(X, Y, repeat([X(0)], length(gens(Y.ring)))) # X is a point + _map(X, Y) end # product abstract_variety @@ -1281,7 +1341,7 @@ inclusion of the graph into the product. """ function graph(f::AbstractVarietyMap) X, Y = f.domain, f.codomain - hom(X, X * Y, vcat(gens(X), f.pullback.image)) + map(X, X * Y, vcat(gens(X), f.pullback.image)) end ############################################################################### @@ -1391,10 +1451,10 @@ function _coerce(F::AbstractBundle, G::AbstractBundle) X, Y = F.parent, G.parent X == Y && return F, G try - return F, pullback(_hom(X, Y), G) + return F, pullback(_map(X, Y), G) catch try - return pullback(_hom(Y, X), F), G + return pullback(_map(Y, X), F), G catch error("the sheaves are not on compatible varieties") end @@ -2049,7 +2109,7 @@ function degeneracy_locus(F::AbstractBundle, G::AbstractBundle, k::Int; class::B Gr = (m-k == 1) ? abstract_projective_bundle(F) : abstract_flag_bundle(F, m-k) S = Gr.bundles[1] D = zero_locus_section(dual(S) * G) - D.struct_map = hom(D, F.parent) # skip the flag abstract_variety + D.struct_map = map(D, F.parent) # skip the flag abstract_variety if isdefined(F.parent, :O1) D.O1 = pullback(D.struct_map, F.parent.O1) end @@ -2147,7 +2207,7 @@ function abstract_projective_space(n::Int; base::Ring=QQ, symbol::String="h") S = AbstractBundle(P, 1, 1-h) Q = trivial_line_bundle(P)*(n+1) - S P.bundles = [S, Q] - P.struct_map = hom(P, abstract_point(base=base), [P(1)]) + P.struct_map = map(P, abstract_point(base=base), [P(1)]) set_attribute!(P, :description => "Projective space of dim $n") set_attribute!(P, :grassmannian => :absolute) set_attribute!(P, :alg => true) @@ -2345,7 +2405,7 @@ function abstract_grassmannian(k::Int, n::Int; base::Ring = QQ, symbol::String = Gr.point = Gr((-1)^d*c[end]^(n-k)) Gr.T = dual(S) * Q Gr.bundles = [S, Q] - Gr.struct_map = hom(Gr, abstract_point(base=base), [Gr(1)]) + Gr.struct_map = map(Gr, abstract_point(base=base), [Gr(1)]) set_attribute!(Gr, :description => "Grassmannian Gr($k, $n)") set_attribute!(Gr, :grassmannian => :absolute) set_attribute!(Gr, :alg => true) @@ -2414,7 +2474,7 @@ function abs_flag(dims::Vector{Int}; base::Ring=QQ, symbol::String="c") Fl.O1 = simplify(sum((i-1)*chern_class(Fl.bundles[i], 1) for i in 1:l)) Fl.point = prod(top_chern_class(E)^dims[i] for (i,E) in enumerate(Fl.bundles[2:end])) Fl.T = sum(dual(Fl.bundles[i]) * sum([Fl.bundles[j] for j in i+1:l]) for i in 1:l-1) - Fl.struct_map = hom(Fl, abstract_point(base=base), [Fl(1)]) + Fl.struct_map = map(Fl, abstract_point(base=base), [Fl(1)]) set_attribute!(Fl, :description => "Flag abstract_variety Flag$(tuple(dims...))") if l == 2 set_attribute!(Fl, :grassmannian => :absolute) end set_attribute!(Fl, :alg => true) diff --git a/experimental/IntersectionTheory/src/blowup.jl b/experimental/IntersectionTheory/src/blowup.jl index 01fe613897b7..d21404c040fc 100644 --- a/experimental/IntersectionTheory/src/blowup.jl +++ b/experimental/IntersectionTheory/src/blowup.jl @@ -244,7 +244,7 @@ h julia> H = gens(P5)[1] H -julia> i = hom(P2, P5, [2*h]) +julia> i = map(P2, P5, [2*h]) AbstractVarietyMap from AbstractVariety of dim 2 to AbstractVariety of dim 5 julia> Bl, E, j = blowup(i) @@ -437,10 +437,10 @@ function blowup_points(X::AbstractVariety, n::Int; symbol::String = "e") Bl = X P = abstract_point(base = X.base) for i in 1:n - Bl = blowup(hom(P, Bl, [zero(P.ring) for j = 1:i]), symbol=symbs[i])[1] + Bl = blowup(map(P, Bl, [zero(P.ring) for j = 1:i]), symbol=symbs[i])[1] end set_attribute!(Bl, :description => "Blowup of $X at $n points") - Bl.struct_map = hom(Bl, X) + Bl.struct_map = map(Bl, X) if get_attribute(X, :alg) == true set_attribute!(Bl, :alg => true) end diff --git a/experimental/IntersectionTheory/test/runtests.jl b/experimental/IntersectionTheory/test/runtests.jl index f14742ffab53..529d31b8aabf 100644 --- a/experimental/IntersectionTheory/test/runtests.jl +++ b/experimental/IntersectionTheory/test/runtests.jl @@ -32,7 +32,7 @@ let pushforward = IntersectionTheory.pushforward @test schur_functor(A, [1,1]) == exterior_power(A, 2) @test schur_functor(A, [2]) == symmetric_power(A, 2) D = degeneracy_locus(A, B, 2) - @test pushforward(hom(D, X), D(1)) == degeneracy_locus(A, B, 2, class=true) + @test pushforward(map(D, X), D(1)) == degeneracy_locus(A, B, 2, class=true) # characteristic classes t = todd_class(2) @@ -51,11 +51,11 @@ let pushforward = IntersectionTheory.pushforward p = abstract_point() P2 = abstract_projective_space(2) - i = hom(P2, P2) + i = map(P2, P2) @test i.domain == P2 @test i.codomain == P2 - i = hom(p, P2) + i = map(p, P2) @test pushforward(i, p(1)) == P2.point @test pullback(i, P2.O1) == 0 @test i.T === tangent_bundle(i) @@ -81,7 +81,7 @@ let pushforward = IntersectionTheory.pushforward P5 = abstract_projective_space(5, symbol="H") h, H = P2.O1, P5.O1 - v = hom(P2, P5, [2h]) + v = map(P2, P5, [2h]) @test pullback(v, H) == 2h @test pullback(v, P5.point) == 0 @test v.pushforward(h) == 2H^4 @@ -91,14 +91,14 @@ let pushforward = IntersectionTheory.pushforward # test that hom works for product P, Q = abstract_projective_space(1), abstract_projective_space(1) PxQ = P * Q - p, q = hom(PxQ, P), hom(PxQ, Q) + p, q = map(PxQ, P), map(PxQ, Q) @test pushforward(p, PxQ.point) == P.point @test integral(pullback(p, P.point) * pullback(q, Q.point)) == 1 # # cubic containing a plane # P2 = abstract_projective_space(2) # Y = complete_intersection(abstract_projective_space(5), 3) - # i = hom(P2, Y, [P2.O1], inclusion=true) + # i = map(P2, Y, [P2.O1], inclusion=true) # Y1 = i.codomain # p = pushforward(i, P2(1)) # h = Y1.O1 @@ -243,7 +243,7 @@ let pushforward = IntersectionTheory.pushforward # blowup Veronese P2 = abstract_projective_space(2) P5 = abstract_projective_space(5) - i = hom(P2, P5, [2P2.O1]) + i = map(P2, P5, [2P2.O1]) Bl, E, j = blowup(i) c = top_chern_class(tangent_bundle(Bl)) @test integral(pushforward(structure_map(Bl), c)) == 12 @@ -257,7 +257,7 @@ let pushforward = IntersectionTheory.pushforward # blowup point in P2 P2 = abstract_projective_space(2) P = abstract_point(base = P2.base) - Bl, E, j = blowup(hom(P, P2, [zero(P.ring)])) + Bl, E, j = blowup(map(P, P2, [zero(P.ring)])) e = pushforward(j, E(1)) @test integral(e^2) == -1 @test integral(pullback(j, e)) == -1 @@ -266,14 +266,14 @@ let pushforward = IntersectionTheory.pushforward # blowup point in P7 P7 = abstract_projective_space(7) P = abstract_point(base = P2.base) - Bl, E, j = blowup(hom(P, P7, [zero(P.ring)])) + Bl, E, j = blowup(map(P, P7, [zero(P.ring)])) e = pushforward(j, E(1)) @test euler(Bl) == 14 # blowup twisted cubic P1 = abstract_projective_space(1) P3 = abstract_projective_space(3) - i = hom(P1, P3, [3P1.O1]) + i = map(P1, P3, [3P1.O1]) Bl, E, j = blowup(i) e = pushforward(j, E(1)) quad = pullback(structure_map(Bl), 2P3.O1) - e @@ -287,7 +287,7 @@ let pushforward = IntersectionTheory.pushforward (r, s, t) = gens(F) P1 = abstract_projective_space(1, base = F) P3 = abstract_projective_space(3, base = F) - i = hom(P1, P3, [3P1.O1]) + i = map(P1, P3, [3P1.O1]) Bl, E, j = blowup(i) e = pushforward(j, E(1)) rH, sH, tH = [pullback(structure_map(Bl), x * P3.O1) - e for x in [r,s,t]] @@ -295,7 +295,7 @@ let pushforward = IntersectionTheory.pushforward G = abstract_grassmannian(2, 5) P9 = abstract_projective_space(9) - i = hom(G, P9, [G.O1]) + i = map(G, P9, [G.O1]) Bl, E, j = blowup(i) e = pushforward(j, E(1)) quad = pullback(structure_map(Bl), 2P9.O1)-e @@ -310,7 +310,7 @@ let pushforward = IntersectionTheory.pushforward P3 = abstract_projective_space(3, base = F) C = zero_locus_section(OO(P2,d)) C.point = 1//(2-2g) * chern_class(C, 1) - i = hom(C, P3, [d * C.point]) + i = map(C, P3, [d * C.point]) Bl, E, j = blowup(i) e = pushforward(j, E(1)) rH, sH, tH = [pullback(structure_map(Bl), x * P3.O1) - e for x in [r,s,t]]