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

[FTheoryTools] Improve computation of refined Tate fiber types #4062

Merged
merged 3 commits into from
Sep 9, 2024

Conversation

apturner
Copy link
Collaborator

This adds Mohab's proposed calculation method, except in the case of Type I_0^* fibers, addressing the issue that models over concrete bases are often too complicated and seem "accidentally nonsplit". However, models over arbitrary bases are typically too simple and appear "accidentally split", so the code currently checks if the base is concrete are not and then decides whether to use the old or the new version of the calculation. This is not ideal.

Tests should also be added to more thoroughly check this.

@HereAround, @emikelsons

Copy link

codecov bot commented Aug 30, 2024

Codecov Report

Attention: Patch coverage is 95.71429% with 3 lines in your changes missing coverage. Please review.

Project coverage is 84.62%. Comparing base (74b517b) to head (875d606).
Report is 5 commits behind head on master.

Files with missing lines Patch % Lines
.../FTheoryTools/src/AbstractFTheoryModels/methods.jl 85.71% 1 Missing ⚠️
.../FTheoryTools/src/HypersurfaceModels/attributes.jl 50.00% 1 Missing ⚠️
experimental/FTheoryTools/src/auxiliary.jl 98.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4062      +/-   ##
==========================================
+ Coverage   84.58%   84.62%   +0.04%     
==========================================
  Files         612      612              
  Lines       83125    83191      +66     
==========================================
+ Hits        70312    70404      +92     
+ Misses      12813    12787      -26     
Files with missing lines Coverage Δ
.../FTheoryTools/src/LiteratureModels/constructors.jl 93.77% <ø> (ø)
...l/FTheoryTools/src/WeierstrassModels/attributes.jl 86.53% <100.00%> (ø)
experimental/FTheoryTools/test/tate_models.jl 100.00% <ø> (ø)
.../FTheoryTools/src/AbstractFTheoryModels/methods.jl 77.81% <85.71%> (+3.42%) ⬆️
.../FTheoryTools/src/HypersurfaceModels/attributes.jl 93.10% <50.00%> (ø)
experimental/FTheoryTools/src/auxiliary.jl 76.00% <98.33%> (+2.97%) ⬆️

... and 9 files with indirect coverage changes

num_gens = length(gens(parent(f)))
first_coord_inds = collect(1:num_gens - 2)
last_coord_inds = collect(3:num_gens)
rand_ints_ab2 = rand(-100:100, num_gens - 2)
Copy link
Member

@HereAround HereAround Aug 31, 2024

Choose a reason for hiding this comment

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

Are we guaranteed that the method always works? Or could these random numbers sometimes fail us? If so, we would have random failures, which is likely not good.

(There were discussions elsewhere regarding fixed seeds etc., so as to make tests/failures reproducible. If random numbers are truly needed, then we should investigate more.)

Copy link
Member

Choose a reason for hiding this comment

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

Discussed this in triage.

If you really need randomness here, I would strongly suggest to add a comment that explains the background.

Also: are the given ranges really always sufficient? If so this should be justified. If not then one should at least describe what might go wrong if the random value is "insufficient" (whatever that means). You could also add checks or loop to try multiple random values until some criterion proves it is correct; or until a consistent result value has been produced several times for different random choices...

More was said and discussed with @HereAround but that's the gist.

Copy link
Member

@HereAround HereAround Sep 4, 2024

Choose a reason for hiding this comment

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

@apturner @emikelsons and I just discussed more on this. Here is the summary:

What this function is actually deciding is if certain ideals are radical or not. However, for the geometries encountered in FTheory, these computations are too hard/time consuming. The random numbers serve as shortcut as follows:

  1. Keep exactly two variable (in the polynomial generators of the ideals in question), and evaluate all remaining variables at integer values. Then check whether the result is radical or not.
  2. Currently, this step is executed twice - once by keeping the very first two variables as symbols (and evaluating all other variables to random integer values), and once by keeping the very last two variables as symbols.

We just agreed on the following:

  • Instead of always keeping the first two/last two variables as symbols, do so for random pairs of variables.
  • Repeat the evaluation and subsequent radical check five times (instead of currently only two times).
  • Add tests, to gauge if this algorithm succeeds.
  • The current implementation corrects for a tendency of this algorithm to favor non-split over split. This could be made stricter. But then, we need to tests if such a stricter test/algorithm still yields correct answers, or tends to fail.
  • @apturner and @emikelsons seemed to favor the choice of a seed. So I understand @apturner will work this in as an optional argument to this method. Thereby, the tests should become reproducible.
  • We were also thinking of using put_over_concrete_base(P3, some_model_over_a_non_concrete_base). Then we can run the new algorithm also for models that are defined over non-concrete bases. However, there is unfortunately always a chance that this step would introduce a gauge enhancement, and so the results computed from this method would disagree with the "generic model". This is to be played with/tested. Our feeling is that the projective space P3 minimized this potential of failure though.

I believe this is all the points that we came to think of and @apturner will work on this. Let us know once this is ready to be reviewed again. Thank you for working on this!

if f_ord == 0 && g_ord == 0
q_first = quotient(ideal([9 * g_first_2, w_first_2]), ideal([2 * f_first_2, w_first_2]))
q_last = quotient(ideal([9 * g_last_2, w_last_2]), ideal([2 * f_last_2, w_last_2]))

Copy link
Member

@HereAround HereAround Aug 31, 2024

Choose a reason for hiding this comment

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

Just for my curiosity: Why is there a line break here (and in similar placed below)? I am not sure if it enhances readability.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Only for readability. I generally prefer to break up the logical steps of the calculation rather than have a solid block of code. For some of these cases, the first step is many lines, and for consistency I line break even the shorter cases

@HereAround
Copy link
Member

Thank you for working on this @apturner !

Generally speaking, this looks great. However, I believe all of the following points should be addressed before we merge this PR:

  1. Could the random numbers (see above) lead to random failures? If yes, then we need to make this reproducible (e.g. by remembering the seed). This was discussed elsewhere. I do not recall at the top of my head where.
  2. Let us add tests to this PR. If I am not mistaken, @emikelsons brought forward examples, where the current implementation yields the wrong Kodaira type. I strongly suggest to add those examples as tests (be it CI-tests or doc-tests). Thereby, we can truly appreciate this improvement and we have non-trivial tests.
  3. I recall that we wanted to add a text to the documentation, in which we thank Mohab. However, this is currently missing in this PR.

Copy link
Member

@HereAround HereAround left a comment

Choose a reason for hiding this comment

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

See above.

@apturner
Copy link
Collaborator Author

  1. You are correct that the random numbers could result in a random failure. Are you proposing that we always use the same seed, or that we have the ability to provide a seed? If we fix a seed, that's just as likely to randomly fail on any given model as any other seed is. In that sense, the ability to rerun the code several times and use it as a probabilistic method is actually something of a boon. Let me know your thoughts.
  2. I will add tests, and the toric hypersurface models provide perfect examples, so I'll probably run through those.
  3. I can add the acknowledgement to Mohad, good call.

@HereAround
Copy link
Member

HereAround commented Aug 31, 2024

  1. You are correct that the random numbers could result in a random failure. Are you proposing that we always use the same seed, or that we have the ability to provide a seed? If we fix a seed, that's just as likely to randomly fail on any given model as any other seed is. In that sense, the ability to rerun the code several times and use it as a probabilistic method is actually something of a boon. Let me know your thoughts.

Let me ping in @benlorenz. Maybe @lgoettgens knows as well.

@apturner wants to add a function, the outcome of which depends on random numbers. In the worst case scenario, this leads to random failures. I am certain similar situations did arise already and have been discussed. Suggestions?

@HereAround
Copy link
Member

I just realized that my response/status of this PR is somewhat hidden, as I added it to an above conversation. So, for convenience, here is the current (Friday, September 6) status:

@apturner @emikelsons and I just discussed more on this. Here is the summary:

What this function is actually deciding is if certain ideals are radical or not. However, for the geometries encountered in FTheory, these computations are too hard/time consuming. The random numbers serve as shortcut as follows:

  1. Keep exactly two variable (in the polynomial generators of the ideals in question), and evaluate all remaining variables at integer values. Then check whether the result is radical or not.
  2. Currently, this step is executed twice - once by keeping the very first two variables as symbols (and evaluating all other variables to random integer values), and once by keeping the very last two variables as symbols.

We just agreed on the following:

  • Instead of always keeping the first two/last two variables as symbols, do so for random pairs of variables.
  • Repeat the evaluation and subsequent radical check five times (instead of currently only two times).
  • Add tests, to gauge if this algorithm succeeds.
  • The current implementation corrects for a tendency of this algorithm to favor non-split over split. This could be made stricter. But then, we need to tests if such a stricter test/algorithm still yields correct answers, or tends to fail.
  • @apturner and @emikelsons seemed to favor the choice of a seed. So I understand @apturner will work this in as an optional argument to this method. Thereby, the tests should become reproducible.
  • We were also thinking of using put_over_concrete_base(P3, some_model_over_a_non_concrete_base). Then we can run the new algorithm also for models that are defined over non-concrete bases. However, there is unfortunately always a chance that this step would introduce a gauge enhancement, and so the results computed from this method would disagree with the "generic model". This is to be played with/tested. Our feeling is that the projective space P3 minimized this potential of failure though.

I believe this is all the points that we came to think of and @apturner will work on this. Let us know once this is ready to be reviewed again. Thank you for working on this!

@apturner
Copy link
Collaborator Author

apturner commented Sep 6, 2024

I believe I have addressed everything in the recent commit.

  1. I have added further comments to explain the use of random numbers.
  2. I now run the random process five times and compare the results.
  3. Each random run now picks a random two variables to keep unevaluated.
  4. I still default to "split" if there is disagreement in the results, to counteract the tendency for the method to fail toward "non-split".
  5. I put all models over a concrete base (projective space, if it's not already over a concrete base) so that the same method can always be used.
  6. I have included an optional seed argument for debugging purposes.
  7. With the change to always do the computation over concrete bases, the existing tests all test the new code now, but I have also included new tests that try the code out on all of the Weierstrass models from the F-theory on All Toric Hypersurface models.
  8. I added the acknowledgement of Mohab for his help devising this algorithm.
  9. I added some minor fixes to the put_over_concrete_base function.
  10. In the process of working on this commit, I discovered errors in the existing tests of Tate models over arbitrary bases, which I have fixed in this commit.

@HereAround

@apturner
Copy link
Collaborator Author

apturner commented Sep 6, 2024

Currently, the optional keyword argument to provide a seed is only available in the internal function _kodaira_type, which is normally only called by other user-facing functions. Testing this function using a given seed can be performed as in the following example:

julia> B3 = projective_space(NormalToricVariety, 3)
Normal toric variety

julia> Kbar = anticanonical_divisor(B3)
Torus-invariant, non-prime divisor on a normal toric variety

julia> foah16_B3_weier = literature_model(arxiv_id = "1408.4808", equation = "3.203", type = "weierstrass", base_space = B3, defining_classes = Dict("s7" => Kbar, "s9" => Kbar), completeness_check = false)
Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!

Weierstrass model over a concrete base -- F-theory weierstrass model dual to hypersurface model with fiber ambient space F_16 based on arXiv paper 1408.4808 Eq. (3.203)

julia> sl = singular_loci(foah16_B3_weier)
4-element Vector{Tuple{MPolyIdeal{<:MPolyRingElem}, Tuple{Int64, Int64, Int64}, String}}:
 (Ideal with 1 generator, (0, 0, 1), "I_1")
 (Ideal with 1 generator, (0, 0, 3), "Split I_3")
 (Ideal with 1 generator, (0, 0, 3), "Split I_3")
 (Ideal with 1 generator, (0, 0, 3), "Split I_3")

julia> Oscar._kodaira_type(sl[2][1], sl[2][2], foah16_B3_weier, rand_seed = 1234)
"Split I_3"

Comment on lines +786 to +801
@test length(singular_loci(foah1_B3_weier)) == 1
@test length(singular_loci(foah2_B3_weier)) == 1
@test length(singular_loci(foah3_B3_weier)) == 1
@test length(singular_loci(foah4_B3_weier)) == 2
@test length(singular_loci(foah5_B3_weier)) == 1
@test length(singular_loci(foah6_B3_weier)) == 2
@test length(singular_loci(foah7_B3_weier)) == 1
@test length(singular_loci(foah8_B3_weier)) == 3
@test length(singular_loci(foah9_B3_weier)) == 2
@test length(singular_loci(foah10_B3_weier)) == 3
@test length(singular_loci(foah11_B3_weier)) == 3
@test length(singular_loci(foah12_B3_weier)) == 3
@test length(singular_loci(foah13_B3_weier)) == 4
@test length(singular_loci(foah14_B3_weier)) == 4
@test length(singular_loci(foah15_B3_weier)) == 5
@test length(singular_loci(foah16_B3_weier)) == 4
Copy link
Member

Choose a reason for hiding this comment

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

For my curiosity - how long do you think those tests take now?

I believe we even raise a warning somewhere about singular_loci being potentially super slow. So I just want to gauge how much this slows down the OSCAR tests.

The tests are green - at least for now. That of course is a good indication.

Copy link
Collaborator Author

@apturner apturner Sep 9, 2024

Choose a reason for hiding this comment

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

On my laptop, running all of the tests for FTheoryTools, including these new ones, takes 6.5 minutes.

Copy link
Member

Choose a reason for hiding this comment

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

That sounds good to me.

@@ -128,39 +128,39 @@ istar0_s_auxiliary_base_ring, (a1pp, a2pp, a3pp, a4pp, a6pp, vp, wp, mp) = QQ["a
tate_auxiliary_base_ring, (a1p, a2p, a3p, a4p, a6p, v, w) = QQ["a1p", "a2p", "a3p", "a4p", "a6p", "v", "w"];

# construct Tate models over arbitrary base
t_istar0_s = global_tate_model(istar0_s_auxiliary_base_ring, [1 2 3 4 6 0 2; -1 -2 -2 -3 -4 1 -1], 3, [a1pp * (vp^2 + wp)^1, mp * (vp^2 + wp)^1 + a2pp * (vp^2 + wp)^2, a3pp * (vp^2 + wp)^2, mp^2 * (vp^2 + wp)^2 + a4pp * (vp^2 + wp)^3, a6pp * (vp^2 + wp)^4]);
Copy link
Member

Choose a reason for hiding this comment

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

Why have the gradings changed? (At least it looks so to me right now.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

All of the gradings in these tests were incorrect in multiple ways:

  1. The number of columns in the grading matrices did not match the number of coordinates of the base. This also indicates an "error" of the functions that construct arbitrary bases, as they should probably require that this be the case. I didn't fix that issue in this PR, but I did update all the gradings in these tests.
  2. Even setting that aside, the gradings were not updated when we changed the tests to use gauge divisor v^2 + w = 0 rather than just w = 0. Where previously a given variable had grade n under [w], now it really should have grade 2 n under [v], and w itself should have grade 2 under [v]. I've updated the gradings to make this the case.

Copy link
Member

Choose a reason for hiding this comment

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

I see. Thx!

@test_throws ArgumentError global_tate_model(tate_auxiliary_base_ring, [1 2 3 4 6 0; 0 -1 -2 -3 -5 1], 3, [a1p])
@test_throws ArgumentError global_tate_model(tate_auxiliary_base_ring, [1 2 3 4 6 0; 0 -1 -2 -3 -5 1], 3, [a1p * v^0, a2p * v^1, a3p * v^2, a4p * v^3, sec_a6])
@test_throws ArgumentError global_tate_model(tate_auxiliary_base_ring, [1 2 3 4 6 0; 0 -1 -2 -3 -5 1], -1, [a1p * v^0, a2p * v^1, a3p * v^2, a4p * v^3, a6p * v^5])
@test_throws ArgumentError global_tate_model(tate_auxiliary_base_ring, [1 2 3 4 6 0 0; 0 -1 -2 -3 -5 1 2], 3, [a1p])
Copy link
Member

Choose a reason for hiding this comment

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

Here the gradings also did change. Why?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

See above.

Copy link
Member

@HereAround HereAround left a comment

Choose a reason for hiding this comment

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

Thank you for working on this delicate matter @apturner . This looks very good now!

I left a few minor questions (see above).

For which models will we now be able to work out the (refined) singularity type? For instance, will it work for a hypersurface model without known associated Weierstrass/Tate model? What about hypersurface models with an associated Tate model? Do we maybe want to add more req statements to catch cases which are currently not (yet) covered?

Another question: Will the "identify the singularity type" functionality benefit from put_over_concrete_base working for hypersurface models also?

@HereAround
Copy link
Member

(I will not merge this PR just yet, because I am curious about the responses of @apturner . Other than that, there is no reason - as I see it - to hold this PR.)

@HereAround
Copy link
Member

HereAround commented Sep 9, 2024

(Another question: Are you using #4075 in this PR? I assume not/cannot see it. But just wanted to double check.)

@apturner
Copy link
Collaborator Author

apturner commented Sep 9, 2024

In regards to your top-level questions:

  1. This algorithm only works for Weierstrass models. By extension, we can use it for any Tate model, because we know how to construct the Weierstrass model from a Tate model. Thus, we can use this algorithm for any model for which we know a Tate or Weierstrass model. If we have a hypersurface model for which we don't know either, then we cannot use this method. The use of put_over_concrete_base does not improve this fact, unfortunately.
  2. I am not using [ToricVariety] Support coordinate_ring as reference to cox_ring #4075 currently. The function put_over_concrete_base uses cox_ring throughout, which originally led me to bring this up to you, but I have not changed it there because the use of degree in the same function (instead of degrees or some other related function, I'm not exactly sure) does not generalize to non-toric cases properly, from my experimentation. So instead, I included a @req call that requires the concrete base be toric, for the time being.

@HereAround
Copy link
Member

Currently, the optional keyword argument to provide a seed is only available in the internal function _kodaira_type, which is normally only called by other user-facing functions. Testing this function using a given seed can be performed as in the following example:

julia> B3 = projective_space(NormalToricVariety, 3)
Normal toric variety

julia> Kbar = anticanonical_divisor(B3)
Torus-invariant, non-prime divisor on a normal toric variety

julia> foah16_B3_weier = literature_model(arxiv_id = "1408.4808", equation = "3.203", type = "weierstrass", base_space = B3, defining_classes = Dict("s7" => Kbar, "s9" => Kbar), completeness_check = false)
Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time!

Weierstrass model over a concrete base -- F-theory weierstrass model dual to hypersurface model with fiber ambient space F_16 based on arXiv paper 1408.4808 Eq. (3.203)

julia> sl = singular_loci(foah16_B3_weier)
4-element Vector{Tuple{MPolyIdeal{<:MPolyRingElem}, Tuple{Int64, Int64, Int64}, String}}:
 (Ideal with 1 generator, (0, 0, 1), "I_1")
 (Ideal with 1 generator, (0, 0, 3), "Split I_3")
 (Ideal with 1 generator, (0, 0, 3), "Split I_3")
 (Ideal with 1 generator, (0, 0, 3), "Split I_3")

julia> Oscar._kodaira_type(sl[2][1], sl[2][2], foah16_B3_weier, rand_seed = 1234)
"Split I_3"

I wonder if we might want to add this as comment? Or even make it part of the documentation?

@HereAround
Copy link
Member

In regards to your top-level questions:

1. This algorithm only works for Weierstrass models. By extension, we can use it for any Tate model, because we know how to construct the Weierstrass model from a Tate model. Thus, we can use this algorithm for any model for which we know a Tate or Weierstrass model. If we have a hypersurface model for which we don't know either, then we cannot use this method. The use of `put_over_concrete_base` does not improve this fact, unfortunately.

Is this something to be mentioned in the documentation of singular_loci (maybe I overlooked it)? Maybe it is not too hard to extend to Tate models and hypersurface models with known Weierstrass and/or Tate model. To be reserved for another PR?

2. I am not using [[ToricVariety] Support coordinate_ring as reference to cox_ring #4075](https://github.com/oscar-system/Oscar.jl/pull/4075) currently. The function `put_over_concrete_base` uses `cox_ring` throughout, which originally led me to bring this up to you, but I have not changed it there because the use of `degree` in the same function (instead of `degrees` or some other related function, I'm not exactly sure) does not generalize to non-toric cases properly, from my experimentation. So instead, I included a `@req` call that requires the concrete base be toric, for the time being.

Ok.

@HereAround
Copy link
Member

@apturner It seems there are quite a few other points that you found need attention. Maybe you could add those to #2699, so we do not forget about them after merging this PR?

@apturner
Copy link
Collaborator Author

apturner commented Sep 9, 2024

Is this something to be mentioned in the documentation of singular_loci (maybe I overlooked it)? Maybe it is not too hard to extend to Tate models and hypersurface models with known Weierstrass and/or Tate model. To be reserved for another PR?

This already works for any model that has a known Weierstrass model, but doesn't automatically work if it has a known Tate model but no directly known Weierstrass model. That is a simple fix I can add here.

@apturner
Copy link
Collaborator Author

apturner commented Sep 9, 2024

@apturner It seems there are quite a few other points that you found need attention. Maybe you could add those to #2699, so we do not forget about them after merging this PR?

Yes, I can add all the relevant points there.

Comment on lines +179 to +180
@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))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This change allows for hypersurface models with known Weierstrass or global Tate models to utilize singular_loci. I think this is all ready to merge, once the tests pass again.

@HereAround

Copy link
Member

Choose a reason for hiding this comment

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

Thank you @apturner . Awesome!

@HereAround HereAround enabled auto-merge (squash) September 9, 2024 16:46
@HereAround HereAround merged commit e51c12d into oscar-system:master Sep 9, 2024
26 of 28 checks passed
@apturner apturner deleted the tate-monodromy branch September 11, 2024 17:42
HechtiDerLachs pushed a commit to HechtiDerLachs/Oscar.jl that referenced this pull request Sep 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants