From 1b609ae8aaab66fe0a444f1269b65de50f3aa6c6 Mon Sep 17 00:00:00 2001 From: Martin Bies Date: Thu, 24 Jul 2025 17:13:23 +0200 Subject: [PATCH 1/3] [FTheoryTools] Optimize global Tate model tests --- experimental/FTheoryTools/test/tate_models.jl | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/experimental/FTheoryTools/test/tate_models.jl b/experimental/FTheoryTools/test/tate_models.jl index 57fea8ba5b33..d570ab8a4465 100644 --- a/experimental/FTheoryTools/test/tate_models.jl +++ b/experimental/FTheoryTools/test/tate_models.jl @@ -193,39 +193,6 @@ end end @testset "Singular loci of global Tate models over generic base space" begin - @test length(singular_loci(t_i1)) == 2 - @test length(singular_loci(t_i2_ns)) == 2 - @test length(singular_loci(t_i2_s)) == 2 - @test length(singular_loci(t_i3_ns)) == 2 - @test length(singular_loci(t_i3_s)) == 2 - @test length(singular_loci(t_i4_ns)) == 2 - @test length(singular_loci(t_i4_s)) == 2 - @test length(singular_loci(t_i5_ns)) == 2 - @test length(singular_loci(t_i5_s)) == 2 - @test length(singular_loci(t_i6_ns)) == 2 - @test length(singular_loci(t_i6_s)) == 2 - @test length(singular_loci(t_i7_ns)) == 2 - @test length(singular_loci(t_i7_s)) == 2 - @test length(singular_loci(t_ii)) == 2 - @test length(singular_loci(t_iii)) == 2 - @test length(singular_loci(t_iv_ns)) == 2 - @test length(singular_loci(t_iv_s)) == 2 - @test length(singular_loci(t_istar0_ns)) == 2 - @test length(singular_loci(t_istar0_ss)) == 2 - @test length(singular_loci(t_istar0_s)) == 2 - @test length(singular_loci(t_istar1_ns)) == 2 - @test length(singular_loci(t_istar1_s)) == 2 - @test length(singular_loci(t_istar2_ns)) == 2 - @test length(singular_loci(t_istar2_s)) == 2 - @test length(singular_loci(t_istar3_ns)) == 2 - @test length(singular_loci(t_istar3_s)) == 2 - @test length(singular_loci(t_istar4_ns)) == 2 - @test length(singular_loci(t_istar4_s)) == 2 - @test length(singular_loci(t_ivstar_ns)) == 2 - @test length(singular_loci(t_ivstar_s)) == 2 - @test length(singular_loci(t_iiistar)) == 2 - @test length(singular_loci(t_iistar)) == 2 - @test length(singular_loci(t_nm)) == 2 @test [k[2:3] for k in singular_loci(t_i1)] == [((0, 0, 1), "I_1"), ((0, 0, 1), "I_1")] @test [k[2:3] for k in singular_loci(t_i2_ns)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] @test [k[2:3] for k in singular_loci(t_i2_s)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Split I_2")] From 7ded9f0fc5a16d7fdff66e9d4525fda249ef5f33 Mon Sep 17 00:00:00 2001 From: Martin Bies Date: Thu, 24 Jul 2025 17:24:16 +0200 Subject: [PATCH 2/3] [FTheoryTools] Improve Monte-Carlo method --- .../src/HypersurfaceModels/attributes.jl | 11 +-- .../src/LiteratureModels/constructors.jl | 8 ++- .../FTheoryTools/src/TateModels/attributes.jl | 11 +-- .../FTheoryTools/src/TateModels/methods.jl | 4 +- .../src/WeierstrassModels/attributes.jl | 11 +-- experimental/FTheoryTools/src/auxiliary.jl | 10 ++- .../FTheoryTools/test/hypersurface_models.jl | 5 +- .../FTheoryTools/test/literature_models.jl | 47 +++++++------ experimental/FTheoryTools/test/tate_models.jl | 69 ++++++++++--------- .../FTheoryTools/test/weierstrass_models.jl | 5 +- 10 files changed, 102 insertions(+), 79 deletions(-) diff --git a/experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl b/experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl index b3a4bdf2b2b9..4153af4415d8 100644 --- a/experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl +++ b/experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl @@ -287,7 +287,7 @@ end Return the singular loci of the Weierstrass model equivalent to the given hypersurface model, along with the order of vanishing of ``(f, g, \Delta)`` at each locus and the corresponding -refined Tate fiber type. See [singular_loci(w::WeierstrassModel)](@ref) for more details. +refined Tate fiber type. See [`singular_loci(w::WeierstrassModel)`](@ref) for more details. Raises an error if no such Weierstrass model is known. @@ -297,6 +297,7 @@ model (see [BMT25](@cite BMT25) for background), in order to demonstrate this fu !!! warning The classification of singularities is performed using a Monte Carlo algorithm, involving randomized sampling. While reliable in practice, this probabilistic method may occasionally yield non-deterministic results. + The random seed can be set with the optional argument `rng`. # Examples ```jldoctest @@ -324,12 +325,14 @@ Weierstrass model over a concrete base julia> set_weierstrass_model(h, w) -julia> length(singular_loci(h)) +julia> using Random; + +julia> length(singular_loci(h; rng = Random.Xoshiro(1234))) 2 ``` """ -@attr Vector{<:Tuple{<:MPolyIdeal{<:MPolyRingElem}, Tuple{Int64, Int64, Int64}, String}} function singular_loci(h::HypersurfaceModel) +@attr Vector{<:Tuple{<:MPolyIdeal{<:MPolyRingElem}, Tuple{Int64, Int64, Int64}, String}} function singular_loci(h::HypersurfaceModel; rng::AbstractRNG = Random.default_rng()) @req base_space(h) isa NormalToricVariety "Singular loci currently only supported for toric varieties as base space" @req has_attribute(h, :weierstrass_model) || has_attribute(h, :global_tate_model) "No corresponding Weierstrass model or global Tate model is known" - return has_attribute(h, :weierstrass_model) ? singular_loci(weierstrass_model(h)) : singular_loci(global_tate_model(h)) + return has_attribute(h, :weierstrass_model) ? singular_loci(weierstrass_model(h); rng) : singular_loci(global_tate_model(h); rng) end diff --git a/experimental/FTheoryTools/src/LiteratureModels/constructors.jl b/experimental/FTheoryTools/src/LiteratureModels/constructors.jl index 1849bf04612e..537e2f7acb1d 100644 --- a/experimental/FTheoryTools/src/LiteratureModels/constructors.jl +++ b/experimental/FTheoryTools/src/LiteratureModels/constructors.jl @@ -81,7 +81,9 @@ Construction over concrete base may lead to singularity enhancement. Consider co Weierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19) -julia> length(singular_loci(w)) +julia> using Random; + +julia> length(singular_loci(w; rng = Random.Xoshiro(1234))) 1 ``` @@ -102,7 +104,9 @@ Construction over concrete base may lead to singularity enhancement. Consider co Weierstrass model over a concrete base -- U(1) Weierstrass model based on arXiv paper 1208.2695 Eq. (B.19) -julia> length(singular_loci(w)) +julia> using Random; + +julia> length(singular_loci(w; rng = Random.Xoshiro(1234))) 1 ``` diff --git a/experimental/FTheoryTools/src/TateModels/attributes.jl b/experimental/FTheoryTools/src/TateModels/attributes.jl index 52bf58978cfb..2a9db3cc2a02 100644 --- a/experimental/FTheoryTools/src/TateModels/attributes.jl +++ b/experimental/FTheoryTools/src/TateModels/attributes.jl @@ -320,11 +320,12 @@ end Return the singular loci of the Weierstrass model equivalent to the given Tate model, along with the order of vanishing of ``(f, g, \Delta)`` at each locus and the corresponding -refined Tate fiber type. See [singular_loci(w::WeierstrassModel)](@ref) for more details. +refined Tate fiber type. See [`singular_loci(w::WeierstrassModel)`](@ref) for more details. !!! warning The classification of singularities is performed using a Monte Carlo algorithm, involving randomized sampling. While reliable in practice, this probabilistic method may occasionally yield non-deterministic results. + The random seed can be set with the optional argument `rng`. Below, we demonstrate this functionality by computing the singular loci of a Type ``III`` Tate model [KMSS11](@cite). In this case, the Tate sections are factored as follows: @@ -360,13 +361,15 @@ Assuming that the first row of the given grading is the grading under Kbar Global Tate model over a not fully specified base -julia> sort([k[2:3] for k in singular_loci(t)]) +julia> using Random; + +julia> sort([k[2:3] for k in singular_loci(t; rng = Random.Xoshiro(1234))]) 2-element Vector{Tuple{Tuple{Int64, Int64, Int64}, String}}: ((0, 0, 1), "I_1") ((1, 2, 3), "III") ``` """ -@attr Vector{<:Tuple{<:MPolyIdeal{<:MPolyRingElem}, Tuple{Int64, Int64, Int64}, String}} function singular_loci(t::GlobalTateModel) +@attr Vector{<:Tuple{<:MPolyIdeal{<:MPolyRingElem}, Tuple{Int64, Int64, Int64}, String}} function singular_loci(t::GlobalTateModel; rng::AbstractRNG = Random.default_rng()) @req (base_space(t) isa NormalToricVariety || base_space(t) isa FamilyOfSpaces) "Singular loci of global Tate model currently only supported for toric varieties and families of spaces as base space" - return singular_loci(weierstrass_model(t)) + return singular_loci(weierstrass_model(t); rng) end diff --git a/experimental/FTheoryTools/src/TateModels/methods.jl b/experimental/FTheoryTools/src/TateModels/methods.jl index 2bc3cecb573a..87848abc381d 100644 --- a/experimental/FTheoryTools/src/TateModels/methods.jl +++ b/experimental/FTheoryTools/src/TateModels/methods.jl @@ -6,7 +6,7 @@ Determine the fiber of a (singular) global Tate model over a particular base loc !!! warning This method may run for very long time and is currently not tested as part of the regular OSCAR CI due to its excessive run times. """ -function analyze_fibers(model::GlobalTateModel, centers::Vector{<:Vector{<:Integer}}) +function analyze_fibers(model::GlobalTateModel, centers::Vector{<:Vector{<:Integer}}; rng::AbstractRNG = Random.default_rng()) # This method only works if the model is defined over a toric variety over toric scheme @req base_space(model) isa NormalToricVariety "Analysis of fibers currently only supported for toric variety as base space" @@ -23,7 +23,7 @@ function analyze_fibers(model::GlobalTateModel, centers::Vector{<:Vector{<:Integ lin = ideal_of_linear_relations(tas); # Singular loci - sing_loc = singular_loci(model) + sing_loc = singular_loci(model; rng) # Pick out the singular loci that are more singular than an I_1 # Then keep only the locus and not the extra info about it diff --git a/experimental/FTheoryTools/src/WeierstrassModels/attributes.jl b/experimental/FTheoryTools/src/WeierstrassModels/attributes.jl index 6841cd6f652c..50ef19220ede 100644 --- a/experimental/FTheoryTools/src/WeierstrassModels/attributes.jl +++ b/experimental/FTheoryTools/src/WeierstrassModels/attributes.jl @@ -178,18 +178,21 @@ Advanced technical details are available in [BMT25](@cite BMT25). !!! warning The classification of singularities is based on a Monte Carlo algorithm, which involves random sampling. - While extensively tested and highly reliable, the method’s probabilistic nature may lead to non-deterministic results in rare cases. + While reliable in practice, this probabilistic method may occasionally yield non-deterministic results. + The random seed can be set with the optional argument `rng`. # Examples ```jldoctest julia> w = weierstrass_model_over_projective_space(3) Weierstrass model over a concrete base -julia> length(singular_loci(w)) +julia> using Random; + +julia> length(singular_loci(w; rng = Random.Xoshiro(1234))) 1 ``` """ -@attr Vector{<:Tuple{<:MPolyIdeal{<:MPolyRingElem}, Tuple{Int64, Int64, Int64}, String}} function singular_loci(w::WeierstrassModel) +@attr Vector{<:Tuple{<:MPolyIdeal{<:MPolyRingElem}, Tuple{Int64, Int64, Int64}, String}} function singular_loci(w::WeierstrassModel; rng::AbstractRNG = Random.default_rng()) @req (base_space(w) isa NormalToricVariety || base_space(w) isa FamilyOfSpaces) "Singular loci of Weierstrass model is currently only supported for toric varieties and families of spaces as base space" B = irrelevant_ideal(base_space(w)) d_primes = factor(discriminant(w)) @@ -202,7 +205,7 @@ julia> length(singular_loci(w)) g_order = valuation(g, p) ords = (f_order, g_order, d_order) I = ideal([p]) - kodaira_types[i] = (I, ords, _kodaira_type(I, ords, w)) + kodaira_types[i] = (I, ords, _kodaira_type(I, ords, w; rng)) end sort!(kodaira_types, by = x -> (x[2][2], x[2][3])) return kodaira_types diff --git a/experimental/FTheoryTools/src/auxiliary.jl b/experimental/FTheoryTools/src/auxiliary.jl index adf314ad9b81..8c76796f8d5e 100644 --- a/experimental/FTheoryTools/src/auxiliary.jl +++ b/experimental/FTheoryTools/src/auxiliary.jl @@ -114,7 +114,7 @@ _count_factors(poly::QQMPolyRingElem) = mapreduce(p -> p[end], +, absolute_prima _string_from_factor_count(poly::QQMPolyRingElem, string_list::Vector{String}) = string_list[_count_factors(poly)] -function _kodaira_type(id::MPolyIdeal{<:MPolyRingElem}, ords::Tuple{Int64, Int64, Int64}, w::WeierstrassModel; rand_seed::Union{Int64, Nothing} = nothing) +function _kodaira_type(id::MPolyIdeal{<:MPolyRingElem}, ords::Tuple{Int64, Int64, Int64}, w::WeierstrassModel; rng::AbstractRNG = Random.default_rng()) f_ord = ords[1] g_ord = ords[2] d_ord = ords[3] @@ -198,12 +198,10 @@ function _kodaira_type(id::MPolyIdeal{<:MPolyRingElem}, ords::Tuple{Int64, Int64 # five times and see if we get agreement among all of the results num_gens = ngens(parent(f)) gauge2s, f2s, g2s, d2s = [], [], [], [] - if rand_seed != nothing - Random.seed!(rand_seed) - end + rng = MersenneTwister() for _ in 1:5 - coord_inds = randperm(num_gens)[1:end-2] - rand_ints = rand(-100:100, num_gens - 2) + coord_inds = randperm(rng, num_gens)[1:end-2] + rand_ints = rand(rng, -100:100, num_gens - 2) push!(gauge2s, evaluate(forget_decoration(gens(id)[1]), coord_inds, rand_ints)) push!(f2s, evaluate(forget_decoration(f), coord_inds, rand_ints)) diff --git a/experimental/FTheoryTools/test/hypersurface_models.jl b/experimental/FTheoryTools/test/hypersurface_models.jl index 4a93995054db..1952ac0a8f01 100644 --- a/experimental/FTheoryTools/test/hypersurface_models.jl +++ b/experimental/FTheoryTools/test/hypersurface_models.jl @@ -2,6 +2,9 @@ # 1: Hypersurface models over concrete bases ############################################################# +using Random +our_rng = Random.Xoshiro(1234) + B3 = projective_space(NormalToricVariety, 3) ambient_space_of_fiber = weighted_projective_space(NormalToricVariety, [2,3,1]) set_coordinate_names(ambient_space_of_fiber, ["x", "y", "z"]) @@ -25,7 +28,7 @@ end @test_throws ArgumentError weierstrass_model(h) @test_throws ArgumentError global_tate_model(h) @test_throws ArgumentError discriminant(h) - @test_throws ArgumentError singular_loci(h) + @test_throws ArgumentError singular_loci(h; rng = our_rng) end @testset "Saving and loading hypersurface models over concrete base space" begin diff --git a/experimental/FTheoryTools/test/literature_models.jl b/experimental/FTheoryTools/test/literature_models.jl index b193dad1dcc0..b9fc5bc7926e 100644 --- a/experimental/FTheoryTools/test/literature_models.jl +++ b/experimental/FTheoryTools/test/literature_models.jl @@ -2,6 +2,9 @@ # 1: Literature Tate model over concrete base ############################################################# +using Random +our_rng = Random.Xoshiro(1234) + B3 = projective_space(NormalToricVariety, 3) Kbar = anticanonical_divisor_class(B3) w = torusinvariant_prime_divisors(B3)[1] @@ -16,7 +19,7 @@ D = classes_of_tunable_sections_in_basis_of_Kbar_and_defining_classes(t1) @test parent(tate_section_a6(t1)) == cox_ring(base_space(t1)) @test parent(tate_polynomial(t1)) == cox_ring(ambient_space(t1)) @test parent(discriminant(t1)) == cox_ring(base_space(t1)) - @test length(singular_loci(t1)) == 2 + @test length(singular_loci(t1; rng = our_rng)) == 2 @test dim(base_space(t1)) == 3 @test dim(ambient_space(t1)) == 5 @test is_base_space_fully_specified(t1) == true @@ -97,7 +100,7 @@ w1 = literature_model(arxiv_id = "1208.2695", equation = "B.19", base_space = B2 @test parent(weierstrass_section_g(w1)) == cox_ring(base_space(w1)) @test parent(weierstrass_polynomial(w1)) == cox_ring(ambient_space(w1)) @test parent(discriminant(w1)) == cox_ring(base_space(w1)) - @test length(singular_loci(w1)) == 1 + @test length(singular_loci(w1; rng = our_rng)) == 1 @test dim(base_space(w1)) == 2 @test dim(ambient_space(w1)) == 4 @test is_base_space_fully_specified(w1) == true @@ -160,7 +163,7 @@ t3 = literature_model(arxiv_id = "1109.3454", equation = "3.1") @test parent(tate_section_a6(t3)) == cox_ring(base_space(t3)) @test parent(tate_polynomial(t3)) == cox_ring(ambient_space(t3)) @test parent(discriminant(t3)) == cox_ring(base_space(t3)) - @test length(singular_loci(t3)) == 2 + @test length(singular_loci(t3; rng = our_rng)) == 2 @test dim(base_space(t3)) == 3 @test dim(ambient_space(t3)) == 5 @test is_base_space_fully_specified(t3) == false @@ -261,7 +264,7 @@ w2 = literature_model(arxiv_id = "1208.2695", equation = "B.19", completeness_ch @test parent(weierstrass_section_g(w2)) == cox_ring(base_space(w2)) @test parent(weierstrass_polynomial(w2)) == cox_ring(ambient_space(w2)) @test parent(discriminant(w2)) == cox_ring(base_space(w2)) - @test length(singular_loci(w2)) == 1 + @test length(singular_loci(w2; rng = our_rng)) == 1 @test dim(base_space(w2)) == 2 @test dim(ambient_space(w2)) == 4 @test is_base_space_fully_specified(w2) == false @@ -326,7 +329,7 @@ b2 = anticanonical_divisor(B2) w5 = literature_model(arxiv_id = "1507.05954", equation = "A.1", completeness_check = false, base_space = B2, defining_classes = Dict("s8" => b2, "a1" => b, "a2" => b, "a3" => b)) @testset "Test defining data for literature Weierstrass model over concrete base" begin - @test length(singular_loci(w4)) == 1 + @test length(singular_loci(w4; rng = our_rng)) == 1 @test dim(base_space(w4)) == 2 @test dim(ambient_space(w4)) == 4 @test is_base_space_fully_specified(w4) == true @@ -344,7 +347,7 @@ b = torusinvariant_prime_divisors(B2)[1] w6 = literature_model(3, base_space = B2, defining_classes = Dict("b" => b), completeness_check = false) @testset "Test defining data for literature model defined by model index" begin - @test length(singular_loci(w6)) == 1 + @test length(singular_loci(w6; rng = our_rng)) == 1 @test dim(base_space(w6)) == 2 @test dim(ambient_space(w6)) == 4 @test is_base_space_fully_specified(w6) == true @@ -783,20 +786,20 @@ foah16_B3_weier = literature_model(arxiv_id = "1408.4808", equation = "3.203", t @test parent(explicit_model_sections(foah14_B3_weier)["s7"]) == cox_ring(base_space(foah14_B3_weier)) @test parent(explicit_model_sections(foah15_B3_weier)["s7"]) == cox_ring(base_space(foah15_B3_weier)) @test parent(explicit_model_sections(foah16_B3_weier)["s7"]) == cox_ring(base_space(foah16_B3_weier)) - @test [k[2:3] for k in singular_loci(foah1_B3_weier)] == [((0, 0, 1), "I_1")] - @test [k[2:3] for k in singular_loci(foah2_B3_weier)] == [((0, 0, 1), "I_1")] - @test [k[2:3] for k in singular_loci(foah3_B3_weier)] == [((0, 0, 1), "I_1")] - @test [k[2:3] for k in singular_loci(foah4_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] - @test [k[2:3] for k in singular_loci(foah5_B3_weier)] == [((0, 0, 1), "I_1")] - @test [k[2:3] for k in singular_loci(foah6_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] - @test [k[2:3] for k in singular_loci(foah7_B3_weier)] == [((0, 0, 1), "I_1")] - @test [k[2:3] for k in singular_loci(foah8_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2")] - @test [k[2:3] for k in singular_loci(foah9_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] - @test [k[2:3] for k in singular_loci(foah10_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 3), "Split I_3")] - @test [k[2:3] for k in singular_loci(foah11_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 3), "Split I_3")] - @test [k[2:3] for k in singular_loci(foah12_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2")] - @test [k[2:3] for k in singular_loci(foah13_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 4), "Split I_4")] - @test [k[2:3] for k in singular_loci(foah14_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 3), "Split I_3")] - @test [k[2:3] for k in singular_loci(foah15_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2")] - @test [k[2:3] for k in singular_loci(foah16_B3_weier)] == [((0, 0, 1), "I_1"), ((0, 0, 3), "Split I_3"), ((0, 0, 3), "Split I_3"), ((0, 0, 3), "Split I_3")] + @test [k[2:3] for k in singular_loci(foah1_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1")] + @test [k[2:3] for k in singular_loci(foah2_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1")] + @test [k[2:3] for k in singular_loci(foah3_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1")] + @test [k[2:3] for k in singular_loci(foah4_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] + @test [k[2:3] for k in singular_loci(foah5_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1")] + @test [k[2:3] for k in singular_loci(foah6_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] + @test [k[2:3] for k in singular_loci(foah7_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1")] + @test [k[2:3] for k in singular_loci(foah8_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2")] + @test [k[2:3] for k in singular_loci(foah9_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] + @test [k[2:3] for k in singular_loci(foah10_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 3), "Split I_3")] + @test [k[2:3] for k in singular_loci(foah11_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 3), "Split I_3")] + @test [k[2:3] for k in singular_loci(foah12_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2")] + @test [k[2:3] for k in singular_loci(foah13_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 4), "Split I_4")] + @test [k[2:3] for k in singular_loci(foah14_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 3), "Split I_3")] + @test [k[2:3] for k in singular_loci(foah15_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2"), ((0, 0, 2), "Non-split I_2")] + @test [k[2:3] for k in singular_loci(foah16_B3_weier; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 3), "Split I_3"), ((0, 0, 3), "Split I_3"), ((0, 0, 3), "Split I_3")] end diff --git a/experimental/FTheoryTools/test/tate_models.jl b/experimental/FTheoryTools/test/tate_models.jl index d570ab8a4465..f99affd11569 100644 --- a/experimental/FTheoryTools/test/tate_models.jl +++ b/experimental/FTheoryTools/test/tate_models.jl @@ -2,6 +2,9 @@ # 1: Global Tate models over concrete base space ############################################################# +using Random +our_rng = Random.Xoshiro(1234) + my_base = projective_space(NormalToricVariety, 3) sec_a1 = generic_section(anticanonical_bundle(projective_space(NormalToricVariety,3))) sec_a2 = generic_section(anticanonical_bundle(my_base)^2) @@ -193,39 +196,39 @@ end end @testset "Singular loci of global Tate models over generic base space" begin - @test [k[2:3] for k in singular_loci(t_i1)] == [((0, 0, 1), "I_1"), ((0, 0, 1), "I_1")] - @test [k[2:3] for k in singular_loci(t_i2_ns)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] - @test [k[2:3] for k in singular_loci(t_i2_s)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Split I_2")] - @test [k[2:3] for k in singular_loci(t_i3_ns)] == [((0, 0, 1), "I_1"), ((0, 0, 3), "Non-split I_3")] - @test [k[2:3] for k in singular_loci(t_i3_s)] == [((0, 0, 1), "I_1"), ((0, 0, 3), "Split I_3")] - @test [k[2:3] for k in singular_loci(t_i4_ns)] == [((0, 0, 1), "I_1"), ((0, 0, 4), "Non-split I_4")] - @test [k[2:3] for k in singular_loci(t_i4_s)] == [((0, 0, 1), "I_1"), ((0, 0, 4), "Split I_4")] - @test [k[2:3] for k in singular_loci(t_i5_ns)] == [((0, 0, 1), "I_1"), ((0, 0, 5), "Non-split I_5")] - @test [k[2:3] for k in singular_loci(t_i5_s)] == [((0, 0, 1), "I_1"), ((0, 0, 5), "Split I_5")] - @test [k[2:3] for k in singular_loci(t_i6_ns)] == [((0, 0, 1), "I_1"), ((0, 0, 6), "Non-split I_6")] - @test [k[2:3] for k in singular_loci(t_i6_s)] == [((0, 0, 1), "I_1"), ((0, 0, 6), "Split I_6")] - @test [k[2:3] for k in singular_loci(t_i7_ns)] == [((0, 0, 1), "I_1"), ((0, 0, 7), "Non-split I_7")] - @test [k[2:3] for k in singular_loci(t_i7_s)] == [((0, 0, 1), "I_1"), ((0, 0, 7), "Split I_7")] - @test [k[2:3] for k in singular_loci(t_ii)] == [((0, 0, 1), "I_1"), ((1, 1, 2), "II")] - @test [k[2:3] for k in singular_loci(t_iii)] == [((0, 0, 1), "I_1"), ((1, 2, 3), "III")] - @test [k[2:3] for k in singular_loci(t_iv_ns)] == [((0, 0, 1), "I_1"), ((2, 2, 4), "Non-split IV")] - @test [k[2:3] for k in singular_loci(t_iv_s)] == [((0, 0, 1), "I_1"), ((2, 2, 4), "Split IV")] - @test [k[2:3] for k in singular_loci(t_istar0_ns)] == [((0, 0, 1), "I_1"), ((2, 3, 6), "Non-split I^*_0")] - @test [k[2:3] for k in singular_loci(t_istar0_ss)] == [((0, 0, 1), "I_1"), ((2, 3, 6), "Semi-split I^*_0")] - @test [k[2:3] for k in singular_loci(t_istar0_s)] == [((0, 0, 1), "I_1"), ((2, 3, 6), "Split I^*_0")] - @test [k[2:3] for k in singular_loci(t_istar1_ns)] == [((0, 0, 1), "I_1"), ((2, 3, 7), "Non-split I^*_1")] - @test [k[2:3] for k in singular_loci(t_istar1_s)] == [((0, 0, 1), "I_1"), ((2, 3, 7), "Split I^*_1")] - @test [k[2:3] for k in singular_loci(t_istar2_ns)] == [((0, 0, 1), "I_1"), ((2, 3, 8), "Non-split I^*_2")] - @test [k[2:3] for k in singular_loci(t_istar2_s)] == [((0, 0, 1), "I_1"), ((2, 3, 8), "Split I^*_2")] - @test [k[2:3] for k in singular_loci(t_istar3_ns)] == [((0, 0, 1), "I_1"), ((2, 3, 9), "Non-split I^*_3")] - @test [k[2:3] for k in singular_loci(t_istar3_s)] == [((0, 0, 1), "I_1"), ((2, 3, 9), "Split I^*_3")] - @test [k[2:3] for k in singular_loci(t_istar4_ns)] == [((0, 0, 1), "I_1"), ((2, 3, 10), "Non-split I^*_4")] - @test [k[2:3] for k in singular_loci(t_istar4_s)] == [((0, 0, 1), "I_1"), ((2, 3, 10), "Split I^*_4")] - @test [k[2:3] for k in singular_loci(t_ivstar_ns)] == [((0, 0, 1), "I_1"), ((3, 4, 8), "Non-split IV^*")] - @test [k[2:3] for k in singular_loci(t_ivstar_s)] == [((0, 0, 1), "I_1"), ((3, 4, 8), "Split IV^*")] - @test [k[2:3] for k in singular_loci(t_iiistar)] == [((0, 0, 1), "I_1"), ((3, 5, 9), "III^*")] - @test [k[2:3] for k in singular_loci(t_iistar)] == [((0, 0, 1), "I_1"), ((4, 5, 10), "II^*")] - @test [k[2:3] for k in singular_loci(t_nm)] == [((0, 0, 1), "I_1"), ((4, 6, 12), "Non-minimal")] + @test [k[2:3] for k in singular_loci(t_i1; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 1), "I_1")] + @test [k[2:3] for k in singular_loci(t_i2_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Non-split I_2")] + @test [k[2:3] for k in singular_loci(t_i2_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 2), "Split I_2")] + @test [k[2:3] for k in singular_loci(t_i3_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 3), "Non-split I_3")] + @test [k[2:3] for k in singular_loci(t_i3_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 3), "Split I_3")] + @test [k[2:3] for k in singular_loci(t_i4_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 4), "Non-split I_4")] + @test [k[2:3] for k in singular_loci(t_i4_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 4), "Split I_4")] + @test [k[2:3] for k in singular_loci(t_i5_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 5), "Non-split I_5")] + @test [k[2:3] for k in singular_loci(t_i5_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 5), "Split I_5")] + @test [k[2:3] for k in singular_loci(t_i6_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 6), "Non-split I_6")] + @test [k[2:3] for k in singular_loci(t_i6_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 6), "Split I_6")] + @test [k[2:3] for k in singular_loci(t_i7_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 7), "Non-split I_7")] + @test [k[2:3] for k in singular_loci(t_i7_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((0, 0, 7), "Split I_7")] + @test [k[2:3] for k in singular_loci(t_ii; rng = our_rng)] == [((0, 0, 1), "I_1"), ((1, 1, 2), "II")] + @test [k[2:3] for k in singular_loci(t_iii; rng = our_rng)] == [((0, 0, 1), "I_1"), ((1, 2, 3), "III")] + @test [k[2:3] for k in singular_loci(t_iv_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 2, 4), "Non-split IV")] + @test [k[2:3] for k in singular_loci(t_iv_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 2, 4), "Split IV")] + @test [k[2:3] for k in singular_loci(t_istar0_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 6), "Non-split I^*_0")] + @test [k[2:3] for k in singular_loci(t_istar0_ss; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 6), "Semi-split I^*_0")] + @test [k[2:3] for k in singular_loci(t_istar0_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 6), "Split I^*_0")] + @test [k[2:3] for k in singular_loci(t_istar1_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 7), "Non-split I^*_1")] + @test [k[2:3] for k in singular_loci(t_istar1_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 7), "Split I^*_1")] + @test [k[2:3] for k in singular_loci(t_istar2_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 8), "Non-split I^*_2")] + @test [k[2:3] for k in singular_loci(t_istar2_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 8), "Split I^*_2")] + @test [k[2:3] for k in singular_loci(t_istar3_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 9), "Non-split I^*_3")] + @test [k[2:3] for k in singular_loci(t_istar3_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 9), "Split I^*_3")] + @test [k[2:3] for k in singular_loci(t_istar4_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 10), "Non-split I^*_4")] + @test [k[2:3] for k in singular_loci(t_istar4_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((2, 3, 10), "Split I^*_4")] + @test [k[2:3] for k in singular_loci(t_ivstar_ns; rng = our_rng)] == [((0, 0, 1), "I_1"), ((3, 4, 8), "Non-split IV^*")] + @test [k[2:3] for k in singular_loci(t_ivstar_s; rng = our_rng)] == [((0, 0, 1), "I_1"), ((3, 4, 8), "Split IV^*")] + @test [k[2:3] for k in singular_loci(t_iiistar; rng = our_rng)] == [((0, 0, 1), "I_1"), ((3, 5, 9), "III^*")] + @test [k[2:3] for k in singular_loci(t_iistar; rng = our_rng)] == [((0, 0, 1), "I_1"), ((4, 5, 10), "II^*")] + @test [k[2:3] for k in singular_loci(t_nm; rng = our_rng)] == [((0, 0, 1), "I_1"), ((4, 6, 12), "Non-minimal")] end #@testset "Blowups of global Tate models" begin diff --git a/experimental/FTheoryTools/test/weierstrass_models.jl b/experimental/FTheoryTools/test/weierstrass_models.jl index 6f9f86080a68..5c291a383c48 100644 --- a/experimental/FTheoryTools/test/weierstrass_models.jl +++ b/experimental/FTheoryTools/test/weierstrass_models.jl @@ -2,6 +2,9 @@ # 1: Weierstrass models over concrete base space ############################################################# +using Random +our_rng = Random.Xoshiro(1234) + my_base = projective_space(NormalToricVariety, 3) sec_f = generic_section(anticanonical_bundle(projective_space(NormalToricVariety,3))^4) sec_g = generic_section(anticanonical_bundle(my_base)^6) @@ -16,7 +19,7 @@ w = weierstrass_model(my_base; completeness_check = false) @test dim(ambient_space(w)) == 5 @test is_smooth(ambient_space(w)) == false @test toric_variety(calabi_yau_hypersurface(w)) == ambient_space(w) - @test length(singular_loci(w)) == 1 + @test length(singular_loci(w; rng = our_rng)) == 1 @test is_base_space_fully_specified(w) == true @test is_partially_resolved(w) == false end From d16c4291e787008cb0657ed7ccf082fe9ad0e488 Mon Sep 17 00:00:00 2001 From: Martin Bies Date: Mon, 28 Jul 2025 14:52:08 +0200 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Benjamin Lorenz --- experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl | 2 +- experimental/FTheoryTools/src/TateModels/attributes.jl | 2 +- experimental/FTheoryTools/src/WeierstrassModels/attributes.jl | 2 +- experimental/FTheoryTools/src/auxiliary.jl | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl b/experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl index 4153af4415d8..69aea4de7296 100644 --- a/experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl +++ b/experimental/FTheoryTools/src/HypersurfaceModels/attributes.jl @@ -297,7 +297,7 @@ model (see [BMT25](@cite BMT25) for background), in order to demonstrate this fu !!! warning The classification of singularities is performed using a Monte Carlo algorithm, involving randomized sampling. While reliable in practice, this probabilistic method may occasionally yield non-deterministic results. - The random seed can be set with the optional argument `rng`. + The random source can be set with the optional argument `rng`. # Examples ```jldoctest diff --git a/experimental/FTheoryTools/src/TateModels/attributes.jl b/experimental/FTheoryTools/src/TateModels/attributes.jl index 2a9db3cc2a02..bc273f7a3753 100644 --- a/experimental/FTheoryTools/src/TateModels/attributes.jl +++ b/experimental/FTheoryTools/src/TateModels/attributes.jl @@ -325,7 +325,7 @@ refined Tate fiber type. See [`singular_loci(w::WeierstrassModel)`](@ref) for mo !!! warning The classification of singularities is performed using a Monte Carlo algorithm, involving randomized sampling. While reliable in practice, this probabilistic method may occasionally yield non-deterministic results. - The random seed can be set with the optional argument `rng`. + The random source can be set with the optional argument `rng`. Below, we demonstrate this functionality by computing the singular loci of a Type ``III`` Tate model [KMSS11](@cite). In this case, the Tate sections are factored as follows: diff --git a/experimental/FTheoryTools/src/WeierstrassModels/attributes.jl b/experimental/FTheoryTools/src/WeierstrassModels/attributes.jl index 50ef19220ede..96a79790afae 100644 --- a/experimental/FTheoryTools/src/WeierstrassModels/attributes.jl +++ b/experimental/FTheoryTools/src/WeierstrassModels/attributes.jl @@ -179,7 +179,7 @@ Advanced technical details are available in [BMT25](@cite BMT25). !!! warning The classification of singularities is based on a Monte Carlo algorithm, which involves random sampling. While reliable in practice, this probabilistic method may occasionally yield non-deterministic results. - The random seed can be set with the optional argument `rng`. + The random source can be set with the optional argument `rng`. # Examples ```jldoctest diff --git a/experimental/FTheoryTools/src/auxiliary.jl b/experimental/FTheoryTools/src/auxiliary.jl index 8c76796f8d5e..9d292fe9f7ad 100644 --- a/experimental/FTheoryTools/src/auxiliary.jl +++ b/experimental/FTheoryTools/src/auxiliary.jl @@ -198,7 +198,6 @@ function _kodaira_type(id::MPolyIdeal{<:MPolyRingElem}, ords::Tuple{Int64, Int64 # five times and see if we get agreement among all of the results num_gens = ngens(parent(f)) gauge2s, f2s, g2s, d2s = [], [], [], [] - rng = MersenneTwister() for _ in 1:5 coord_inds = randperm(rng, num_gens)[1:end-2] rand_ints = rand(rng, -100:100, num_gens - 2)