From 7650083b273a6ed9f8dc7745293d38f006ce2377 Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Sat, 18 Jan 2025 18:35:49 +0100 Subject: [PATCH 1/4] Compute strict transform, not total transform Fixes a bug in FTheoryTools instroduced by https://github.com/oscar-system/Oscar.jl/pull/4484 Namely, it previously computed the total transform, not the strict transform. Even with the speed improvements of https://github.com/oscar-system/Oscar.jl/pull/4485 computing the strict transform with ideals is slower than operating on polynomials. Therefore, I added a strict transform function on polynomials. --- .../src/AbstractFTheoryModels/methods.jl | 6 +++-- .../Schemes/src/ToricBlowups/methods.jl | 23 ++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/experimental/FTheoryTools/src/AbstractFTheoryModels/methods.jl b/experimental/FTheoryTools/src/AbstractFTheoryModels/methods.jl index b9ec8321f95..36948528d2f 100644 --- a/experimental/FTheoryTools/src/AbstractFTheoryModels/methods.jl +++ b/experimental/FTheoryTools/src/AbstractFTheoryModels/methods.jl @@ -157,7 +157,8 @@ function blow_up(m::AbstractFTheoryModel, I::AbsIdealSheaf; coordinate_name::Str # Construct the new model if m isa GlobalTateModel if isdefined(m, :tate_polynomial) && new_ambient_space isa NormalToricVariety - new_tate_polynomial = cox_ring_module_homomorphism(bd, tate_polynomial(m)) + f = tate_polynomial(m) + new_tate_polynomial = strict_transform(bd, f) model = GlobalTateModel(explicit_model_sections(m), defining_section_parametrization(m), new_tate_polynomial, base_space(m), new_ambient_space) else if bd isa ToricBlowupMorphism @@ -169,7 +170,8 @@ function blow_up(m::AbstractFTheoryModel, I::AbsIdealSheaf; coordinate_name::Str end else if isdefined(m, :weierstrass_polynomial) && new_ambient_space isa NormalToricVariety - new_weierstrass_polynomial = cox_ring_module_homomorphism(bd, weierstrass_polynomial(m)) + f = weierstrass_polynomial(m) + new_weierstrass_polynomial = strict_transform(bd, f) model = WeierstrassModel(explicit_model_sections(m), defining_section_parametrization(m), new_weierstrass_polynomial, base_space(m), new_ambient_space) else if bd isa ToricBlowupMorphism diff --git a/experimental/Schemes/src/ToricBlowups/methods.jl b/experimental/Schemes/src/ToricBlowups/methods.jl index 0ffc06828b4..5dd43c73f53 100644 --- a/experimental/Schemes/src/ToricBlowups/methods.jl +++ b/experimental/Schemes/src/ToricBlowups/methods.jl @@ -1,5 +1,6 @@ @doc raw""" strict_transform(f::ToricBlowupMorphism, I::MPolyIdeal) -> MPolyIdeal + strict_transform(f::ToricBlowupMorphism, g::MPolyDecRingElem) -> MPolyDecRingElem Let $f\colon Y \to X$ be the toric blowup corresponding to a star subdivision along a ray. Let $R$ and $S$ be the Cox rings of $X$ and @@ -7,14 +8,19 @@ $Y$, respectively. Here "strict transform" means the "scheme-theoretic closure of the complement of the exceptional divisor in the scheme-theoretic inverse image". -This function returns a homogeneous ideal in $S$ corresponding to the -strict transform under $f$ of the closed subscheme of $X$ defined by the -homogeneous ideal $I$ in $R$. +This function returns a homogeneous ideal (or a polynomial generating a +principal ideal) in $S$ corresponding to the strict transform under $f$ +of the closed subscheme of $X$ defined by the homogeneous ideal $I$ (or +by the homogeneous principal ideal generated by $g$) in $R$. This is implemented under the following assumptions: * the variety $X$ has no torus factors (meaning the rays span $N_{\mathbb{R}}$). +!!! note + Computing `strict_transform(f, g)` is faster than computing + `strict_transform(f, ideal(g))[1]`. + # Examples ```jldoctest julia> X = affine_space(NormalToricVariety, 2) @@ -40,6 +46,8 @@ Ideal generated by x1 + x2*e ``` """ +strict_transform(f::ToricBlowupMorphism, I::Union{MPolyIdeal, MPolyDecRingElem}) + function strict_transform(f::ToricBlowupMorphism, I::MPolyIdeal) X = codomain(f) @req !has_torusfactor(X) "Only implemented when there are no torus factors" @@ -49,6 +57,15 @@ function strict_transform(f::ToricBlowupMorphism, I::MPolyIdeal) return saturation(J, ideal(S, exceptional_var)) end +function strict_transform(f::ToricBlowupMorphism, g::MPolyDecRingElem) + X = codomain(f) + @req !has_torusfactor(X) "Only implemented when there are no torus factors" + S = cox_ring(domain(f)) + exceptional_var = S[index_of_exceptional_ray(f)] + h = cox_ring_module_homomorphism(f, g) + return remove(h, exceptional_var)[2] +end + @doc raw""" total_transform(f::ToricBlowupMorphism, I::MPolyIdeal) -> MPolyIdeal From 53ae410eb2421975961b3ba8c9c0a1ce2856993e Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Mon, 27 Jan 2025 09:51:03 +0100 Subject: [PATCH 2/4] Add all strict and total transforms on polynomials Adding `strict_transform_with_index` and `total_transform` on polynomials. Also adding corresponding tests. --- .../Schemes/src/ToricBlowups/methods.jl | 45 +++++++++++++++---- experimental/Schemes/test/runtests.jl | 9 ++++ 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/experimental/Schemes/src/ToricBlowups/methods.jl b/experimental/Schemes/src/ToricBlowups/methods.jl index 5dd43c73f53..db0e76630d6 100644 --- a/experimental/Schemes/src/ToricBlowups/methods.jl +++ b/experimental/Schemes/src/ToricBlowups/methods.jl @@ -19,7 +19,8 @@ This is implemented under the following assumptions: !!! note Computing `strict_transform(f, g)` is faster than computing - `strict_transform(f, ideal(g))[1]`. + `strict_transform(f, ideal(g))[1]` since it avoids creating an + ideal. # Examples ```jldoctest @@ -68,20 +69,26 @@ end @doc raw""" total_transform(f::ToricBlowupMorphism, I::MPolyIdeal) -> MPolyIdeal + total_transform(f::ToricBlowupMorphism, g::MPolyDecRingElem) -> MPolyDecRingElem Let $f\colon Y \to X$ be the toric blowup corresponding to a star subdivision along a ray. Let $R$ and $S$ be the Cox rings of $X$ and $Y$, respectively. -This function returns a homogeneous ideal in $S$ corresponding to the -total transform (meaning the scheme-theoretic inverse image) under $f$ -of the closed subscheme of $X$ defined by the homogeneous ideal $I$ in -$R$. +Here "total transform" means the "scheme-theoretic inverse image". +This function returns a homogeneous ideal (or a polynomial generating a +principal ideal) in $S$ corresponding to the total transform under $f$ +of the closed subscheme of $X$ defined by the homogeneous ideal $I$ (or +by the homogeneous principal ideal generated by $g$) in $R$. This is implemented under the following assumptions: * the variety $X$ has no torus factors (meaning the rays span $N_{\mathbb{R}}$), and * the variety $X$ is an orbifold (meaning its fan is simplicial). +!!! note + Computing `total_transform(f, g)` is faster than computing + `total_transform(f, ideal(g))[1]` since it avoids creating an ideal. + # Examples ```jldoctest julia> X = affine_space(NormalToricVariety, 2) @@ -107,7 +114,7 @@ Ideal generated by x1*e^2 + x2*e^3 ``` """ -function total_transform(f::ToricBlowupMorphism, I::MPolyIdeal) +function total_transform(f::ToricBlowupMorphism, I::Union{MPolyIdeal, MPolyDecRingElem}) X = codomain(f) @req !has_torusfactor(X) "Only implemented when there are no torus factors" @req is_orbifold(X) "Only implemented when the fan is simplicial" @@ -116,10 +123,11 @@ end @doc raw""" strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) -> (MPolyIdeal, Int) + strict_transform_with_index(f::ToricBlowupMorphism, g::MPolyDecRingElem) -> (MPolyDecRingElem, Int) -Returns the pair $(J, k)$, where $J$ coincides with `strict_transform(f, I)` -and where $k$ is the multiplicity of the total transform along the -exceptional prime divisor. +Returns the pair $(J, k)$, where $J$ coincides with `strict_transform(f, +I)` (or with `strict_transform(f, g)`) and where $k$ is the multiplicity +of the total transform along the exceptional prime divisor. This is implemented under the following assumptions: * the variety $X$ has no torus factors (meaning the rays span @@ -130,6 +138,11 @@ This is implemented under the following assumptions: If the multiplicity $k$ is not needed, we recommend to use `strict_transform(f, I)` which is typically faster. +!!! note + Computing `strict_transform_with_index(f, g)` is faster than + computing `strict_transform_with_index(f, ideal(g))` since it avoids + creating an ideal. + # Examples ```jldoctest julia> X = affine_space(NormalToricVariety, 2) @@ -154,6 +167,8 @@ julia> strict_transform_with_index(f, I) (Ideal (x1 + x2*e), 2) ``` """ +strict_transform_with_index(f::ToricBlowupMorphism, I::Union{MPolyIdeal, MPolyDecRingElem}) + function strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) X = codomain(f) @req !has_torusfactor(X) "Only implemented when there are no torus factors" @@ -164,6 +179,18 @@ function strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) return saturation_with_index(J, ideal(exceptional_var)) end +function strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) + X = codomain(f) + @req !has_torusfactor(X) "Only implemented when there are no torus factors" + @req is_smooth(X) "Only implemented when the fan is smooth" + S = cox_ring(domain(f)) + exceptional_var = S[index_of_exceptional_ray(f)] + h = cox_ring_module_homomorphism(f, g) + pair = remove(h, exceptional_var) + return pair[2], pair[1] + return remove(h, exceptional_var)[2] +end + @doc raw""" cox_ring_module_homomorphism(f::ToricBlowupMorphism, g::MPolyDecRingElem) -> MPolyDecRingElem cox_ring_module_homomorphism(f::ToricBlowupMorphism, I::MPolyIdeal) -> MPolyIdeal diff --git a/experimental/Schemes/test/runtests.jl b/experimental/Schemes/test/runtests.jl index 892675f745c..8087b3281cd 100644 --- a/experimental/Schemes/test/runtests.jl +++ b/experimental/Schemes/test/runtests.jl @@ -44,6 +44,10 @@ end J, k = strict_transform_with_index(f, I) @test J == ideal(S, [x_^3 + y_^3*u^3]) @test k == 6 + g = x^3 + y^3 + h, k_poly = strict_transform_with_index(f, g) + @test ideal(h) == J + @test k == k_poly # 1/2(1, 1) quotient singularity, (1/2, 1/2)-blowup ray_generators = [[2, -1], [0, 1]] @@ -69,6 +73,11 @@ end J_total = total_transform(f, I) @test J_total == ideal(S, [x_*u + y_^3*u^2]) @test ideal_sheaf(Y, J_total) == total_transform(f, ideal_sheaf(X, I)) + g = x + y^3 + h_strict = strict_transform(f, g) + @test ideal(h_strict) == J_strict + h_total = total_transform(f, g) + @test ideal(h_total) == J_total ## Subscheme is a zero-dimensional scheme, topologically three points I = ideal(R, [x - y^3, x - y^5]) From 25a12aa8cc4584c97dfe268ac1f2f7cbe929dc93 Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Mon, 27 Jan 2025 10:19:14 +0100 Subject: [PATCH 3/4] Fix type --- experimental/Schemes/src/ToricBlowups/methods.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/experimental/Schemes/src/ToricBlowups/methods.jl b/experimental/Schemes/src/ToricBlowups/methods.jl index db0e76630d6..6555ef64589 100644 --- a/experimental/Schemes/src/ToricBlowups/methods.jl +++ b/experimental/Schemes/src/ToricBlowups/methods.jl @@ -179,7 +179,7 @@ function strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) return saturation_with_index(J, ideal(exceptional_var)) end -function strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) +function strict_transform_with_index(f::ToricBlowupMorphism, g::MPolyDecRingElem) X = codomain(f) @req !has_torusfactor(X) "Only implemented when there are no torus factors" @req is_smooth(X) "Only implemented when the fan is smooth" @@ -188,7 +188,6 @@ function strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) h = cox_ring_module_homomorphism(f, g) pair = remove(h, exceptional_var) return pair[2], pair[1] - return remove(h, exceptional_var)[2] end @doc raw""" From df354a2ac241a0530275b3781cafe55a35077a47 Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Wed, 29 Jan 2025 18:21:30 +0100 Subject: [PATCH 4/4] Docstrings and docs --- docs/src/AlgebraicGeometry/ToricVarieties/BlowupMorphisms.md | 2 +- experimental/Schemes/src/ToricBlowups/methods.jl | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/src/AlgebraicGeometry/ToricVarieties/BlowupMorphisms.md b/docs/src/AlgebraicGeometry/ToricVarieties/BlowupMorphisms.md index f38e0ce9274..cad063541d6 100644 --- a/docs/src/AlgebraicGeometry/ToricVarieties/BlowupMorphisms.md +++ b/docs/src/AlgebraicGeometry/ToricVarieties/BlowupMorphisms.md @@ -91,7 +91,7 @@ We can compute the total and strict transforms of homogeneous ideals in Cox ring ```@docs strict_transform(f::ToricBlowupMorphism, I::MPolyIdeal) strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) -total_transform(f::ToricBlowupMorphism, I::MPolyIdeal) +total_transform(f::ToricBlowupMorphism, I::Union{MPolyIdeal, MPolyDecRingElem}) ``` The above functions are implemented using a $\mathbb{C}$-module homomorphism between the Cox rings, considered as $\mathbb{C}$-modules, diff --git a/experimental/Schemes/src/ToricBlowups/methods.jl b/experimental/Schemes/src/ToricBlowups/methods.jl index 6555ef64589..1c261ed2ce3 100644 --- a/experimental/Schemes/src/ToricBlowups/methods.jl +++ b/experimental/Schemes/src/ToricBlowups/methods.jl @@ -47,8 +47,6 @@ Ideal generated by x1 + x2*e ``` """ -strict_transform(f::ToricBlowupMorphism, I::Union{MPolyIdeal, MPolyDecRingElem}) - function strict_transform(f::ToricBlowupMorphism, I::MPolyIdeal) X = codomain(f) @req !has_torusfactor(X) "Only implemented when there are no torus factors" @@ -167,8 +165,6 @@ julia> strict_transform_with_index(f, I) (Ideal (x1 + x2*e), 2) ``` """ -strict_transform_with_index(f::ToricBlowupMorphism, I::Union{MPolyIdeal, MPolyDecRingElem}) - function strict_transform_with_index(f::ToricBlowupMorphism, I::MPolyIdeal) X = codomain(f) @req !has_torusfactor(X) "Only implemented when there are no torus factors"