Skip to content

Commit 512a022

Browse files
HereAroundfieker
authored andcommitted
[FTheoryTools] Bugfix in G4-flux computation and allow converting fluxes into basis chosen by FTheoryTools (#4647)
1 parent 454b8ff commit 512a022

4 files changed

Lines changed: 234 additions & 13 deletions

File tree

experimental/FTheoryTools/src/FamilyOfG4Fluxes/special_constructors.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ end
592592

593593

594594
# (5) The following is fragile, but hopefully is a starting point
595-
exceptional_divisor_positions = findall(x -> occursin(r"^e\d+$", x), string.(symbols(S)))
595+
exceptional_divisor_positions = findall(x -> occursin(r"^e\d+(_\d+)?$", x), string.(symbols(S)))
596596

597597

598598
# (6) Work out the relevant intersection numbers to tell if a flux is vertical
@@ -622,7 +622,7 @@ end
622622
# Compute against exceptional divisors
623623
for j in 1:n_rays(base_space(m))
624624
for k in 1:length(exceptional_divisor_positions)
625-
my_tuple = Tuple(sort([ambient_space_flux_candidates_basis_indices[i]..., j, exceptional_divisor_positions[k]...]))
625+
my_tuple = Tuple(sort([ambient_space_flux_candidates_basis_indices[i]..., [j, exceptional_divisor_positions[k]]...]))
626626
push!(condition, sophisticated_intersection_product(ambient_space(m), my_tuple, hypersurface_equation(m), inter_dict, s_inter_dict, data))
627627
end
628628
end

experimental/FTheoryTools/src/G4Fluxes/auxiliary.jl

Lines changed: 182 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ true
4242
```
4343
"""
4444
@attr Vector{CohomologyClass} function basis_of_h22(v::NormalToricVariety; check::Bool = true)
45+
4546
# (0) Some initial checks
4647
if check
4748
@req is_complete(v) "Computation of basis of H22 is currently only supported for complete toric varieties"
@@ -50,11 +51,25 @@ true
5051
if dim(v) < 4
5152
return Vector{CohomologyClass}()
5253
end
54+
5355
# (1) Prepare some data of the variety
5456
mnf = Oscar._minimal_nonfaces(v)
5557
ignored_sets = Set([Tuple(sort(Vector{Int}(Polymake.row(mnf, i)))) for i in 1:Polymake.nrows(mnf)])
5658

57-
# (2) Prepare the linear relations
59+
# (2) Prepare a dict that converts the "naive" generating set into our chosen basis
60+
converter_dict = Dict{Tuple{Int, Int}, Any}()
61+
for k in 1:n_rays(v)
62+
for l in k:n_rays(v)
63+
my_tuple = (k, l)
64+
if (my_tuple in ignored_sets)
65+
converter_dict[my_tuple] = 0
66+
else
67+
converter_dict[my_tuple] = nothing
68+
end
69+
end
70+
end
71+
72+
# (3) Prepare the linear relations
5873
N_lin_rel, my_mat = rref(transpose(matrix(QQ, rays(v))))
5974
@req N_lin_rel == nrows(my_mat) "Cannot remove as many variables as there are linear relations - weird!"
6075
bad_positions = [findfirst(!iszero, row) for row in eachrow(my_mat)]
@@ -66,11 +81,68 @@ true
6681
lin_rels[bad_positions[k]] = my_relation
6782
end
6883

69-
# (3) Prepare a list of those variables that we keep, a.k.a. a basis of H^(1,1)
84+
# (4) Apply linear relations to remaining entries in converter_dict
85+
# (4) The code within the following for loop might need optimizing.
86+
crg = gens(base_ring(cohomology_ring(v)))
87+
for (key, value) in converter_dict
88+
if value === nothing
89+
image = Vector{Any}()
90+
91+
# Only the first entry needs replacing by the linear relations
92+
if (key[1] in keys(lin_rels)) && (key[2] in keys(lin_rels)) == false
93+
my_relation = lin_rels[key[1]]
94+
posi = findall(k -> k != 0, my_relation)
95+
coeffs = my_relation[posi]
96+
for k in 1:length(posi)
97+
push!(image, [coeffs[k], (posi[k], key[2])])
98+
end
99+
end
100+
101+
# Only the second entry needs replacing by the linear relations
102+
if (key[2] in keys(lin_rels)) && (key[1] in keys(lin_rels)) == false
103+
my_relation = lin_rels[key[2]]
104+
posi = findall(k -> k != 0, my_relation)
105+
coeffs = my_relation[posi]
106+
for k in 1:length(posi)
107+
push!(image, [coeffs[k], (key[1], posi[k])])
108+
end
109+
end
110+
111+
# Both entry needs replacing by the linear relations
112+
if (key[1] in keys(lin_rels)) && key[2] in keys(lin_rels)
113+
my_relation = lin_rels[key[1]]
114+
posi = findall(k -> k != 0, my_relation)
115+
coeffs = my_relation[posi]
116+
for k in 1:length(posi)
117+
push!(image, [coeffs[k], (posi[k], key[2])])
118+
end
119+
my_relation = lin_rels[key[2]]
120+
posi = findall(k -> k != 0, my_relation)
121+
coeffs = my_relation[posi]
122+
old_image = copy(image)
123+
image = Vector{Any}()
124+
for i in 1:length(old_image)
125+
for k in 1:length(posi)
126+
old_coeff = old_image[i][1]
127+
push!(image, [old_coeff * coeffs[k], (old_image[i][2][1], posi[k])])
128+
end
129+
end
130+
end
131+
132+
# If there was a replacement, update the key in the dict
133+
if length(image) > 0
134+
#image_as_cohomology_class = CohomologyClass(v, cohomology_ring(v)(sum(i[1] * crg[i[2][1]] * crg[i[2][2]] for i in image)))
135+
#converter_dict[key] = image_as_cohomology_class
136+
converter_dict[key] = image
137+
end
138+
end
139+
end
140+
141+
# (5) Prepare a list of those variables that we keep, a.k.a. a basis of H^(1,1)
70142
good_positions = setdiff(1:n_rays(v), bad_positions)
71143
n_good_positions = length(good_positions)
72144

73-
# (4) Make a list of all quadratic elements in the cohomology ring, which are not generators of the SR-ideal.
145+
# (6) Make a list of all quadratic elements in the cohomology ring, which are not generators of the SR-ideal.
74146
N_filtered_quadratic_elements = 0
75147
dict_of_filtered_quadratic_elements = Dict{Tuple{Int64, Int64}, Int64}()
76148
for k in 1:n_good_positions
@@ -83,9 +155,14 @@ true
83155
end
84156
end
85157

86-
# (5) We only care about the SR-ideal gens of degree 2. Above, we took care of all relations,
87-
# (5) for which both variables are not replaced by one of the linear relations. So, let us identify
88-
# (5) all remaining relations of the SR-ideal, and apply the linear relations to them.
158+
# (7) Consistency check
159+
l1 = sort(collect(keys(converter_dict))[findall(k -> converter_dict[k] === nothing, collect(keys(converter_dict)))])
160+
l2 = sort(collect(keys(dict_of_filtered_quadratic_elements)))
161+
@req l1 == l2 "Inconsistency found"
162+
163+
# (8) We only care about the SR-ideal gens of degree 2. Above, we took care of all relations,
164+
# (8) for which both variables are not replaced by one of the linear relations. So, let us identify
165+
# (8) all remaining relations of the SR-ideal, and apply the linear relations to them.
89166
remaining_relations = Vector{Vector{QQFieldElem}}()
90167
for my_tuple in ignored_sets
91168

@@ -137,8 +214,84 @@ true
137214
new_bad_positions = [findfirst(!iszero, row) for row in eachrow(new_mat)]
138215
new_good_positions = setdiff(1:N_filtered_quadratic_elements, new_bad_positions)
139216
end
140-
141-
# (10) Return the basis elements in terms of cohomology classes
217+
218+
# (10) Some of the remaining variables are replaced by the final remaining variables
219+
# (10) Above, we identified the remaining variables. Now we identify how the other variables
220+
# (10) that appear in dict_of_filtered_quadratic_elements are replaced.
221+
if length(remaining_relations) != 0
222+
new_basis = collect(keys(dict_of_filtered_quadratic_elements))
223+
for (key, value) in dict_of_filtered_quadratic_elements
224+
if (value in new_good_positions) == false
225+
226+
# Find relation to repalce this basis element by
227+
tuple_to_be_replaced = key
228+
index_of_element_to_be_replaced = value
229+
row_that_defines_relation = findfirst(k -> k == 1, new_mat[:,index_of_element_to_be_replaced])
230+
applicable_relation = new_mat[row_that_defines_relation, :]
231+
applicable_relation[index_of_element_to_be_replaced] = 0
232+
relation_to_be_applied = (-1) * applicable_relation
233+
relation_to_be_applied = [[relation_to_be_applied[ivalue], ikey] for (ikey, ivalue) in dict_of_filtered_quadratic_elements if relation_to_be_applied[ivalue] != 0]
234+
if length(relation_to_be_applied) == 0
235+
relation_to_be_applied = 0
236+
end
237+
238+
# Apply this relation throughout converter_dict, so that this tuple is never used in the values
239+
for (ikey, ivalue) in converter_dict
240+
241+
# If the entry maps to zero or is not yet specified, then nothing is to be done. Continue!
242+
if ivalue == 0 || ivalue === nothing
243+
continue
244+
end
245+
246+
# Is replacement needed?
247+
tuple_list = [k[2] for k in ivalue]
248+
position_of_key = findfirst(k -> k == key, tuple_list)
249+
if position_of_key !== nothing
250+
251+
# Prepare new lists for the tuples and coefficients
252+
new_tuple_list = copy(tuple_list)
253+
new_coeff_list = [k[1] for k in ivalue]
254+
255+
# Extract the coefficient of interest
256+
coeff_in_question = new_coeff_list[position_of_key]
257+
258+
# Remove the tuple to be replaced, and its corresponding coefficient
259+
deleteat!(new_tuple_list, position_of_key)
260+
deleteat!(new_coeff_list, position_of_key)
261+
262+
# Is the list empty after the removal? If so, we map to zero
263+
if length(new_tuple_list) == 0 && length(new_coeff_list) == 0
264+
converter_dict[ikey] = 0
265+
continue
266+
end
267+
268+
# Apply relation for element in question
269+
if relation_to_be_applied == 0
270+
converter_dict[ikey] = [[new_coeff_list[a], new_tuple_list[a]] for a in 1:length(new_tuple_list)]
271+
else
272+
for a in 1:length(relation_to_be_applied)
273+
if relation_to_be_applied[a][2] in new_tuple_list
274+
position_of_tuple = findfirst(k -> k == relation_to_be_applied[a][2], new_tuple_list)
275+
new_coeff_list[position_of_tuple] += relation_to_be_applied[a][1]
276+
else
277+
push!(new_tuple_list, relation_to_be_applied[a][2])
278+
push!(new_coeff_list, relation_to_be_applied[a][1])
279+
end
280+
end
281+
converter_dict[ikey] == [[new_coeff_list[a], new_tuple_list[a]] for a in 1:length(new_tuple_list)]
282+
end
283+
284+
end
285+
end
286+
287+
# Assign this value to the tuple to be replaced
288+
converter_dict[key] = relation_to_be_applied
289+
290+
end
291+
end
292+
end
293+
294+
# (11) Return the basis elements in terms of cohomology classes
142295
S = cohomology_ring(v, check = check)
143296
c_ds = [k.f for k in gens(S)]
144297
final_list_of_tuples = Tuple{Int64, Int64}[]
@@ -149,6 +302,27 @@ true
149302
end
150303
basis_of_h22 = [cohomology_class(v, MPolyQuoRingElem(c_ds[my_tuple[1]]*c_ds[my_tuple[2]], S)) for my_tuple in final_list_of_tuples]
151304
set_attribute!(v, :basis_of_h22_indices, final_list_of_tuples)
305+
306+
# (12) Consistency check
307+
l1 = sort(collect(keys(converter_dict))[findall(k -> converter_dict[k] === nothing, collect(keys(converter_dict)))])
308+
@req l1 == sort(final_list_of_tuples) "Inconsistency found"
309+
310+
# (13) Convert all entries in converter_dict to cohomology classes and save as attribute
311+
final_converter_dict = Dict{Tuple{Int, Int}, CohomologyClass}()
312+
for (key, value) in converter_dict
313+
if value == nothing
314+
final_converter_dict[key] = CohomologyClass(v, cohomology_ring(v)(crg[key[1]] *crg[key[2]]))
315+
elseif value == 0
316+
final_converter_dict[key] = CohomologyClass(v, zero(cohomology_ring(v, check = check)))
317+
else
318+
poly = sum(t[1] * crg[t[2][1]] * crg[t[2][2]] for t in value)
319+
image_as_cohomology_class = CohomologyClass(v, cohomology_ring(v)(poly))
320+
final_converter_dict[key] = image_as_cohomology_class
321+
end
322+
end
323+
set_attribute!(v, :converter_dict_h22, final_converter_dict)
324+
325+
# (14) Return the result - finally!
152326
return basis_of_h22
153327
end
154328

experimental/FTheoryTools/src/G4Fluxes/constructors.jl

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
################
44

55
@doc raw"""
6-
g4_flux(model::AbstractFTheoryModel, class::CohomologyClass)
6+
g4_flux(model::AbstractFTheoryModel, class::CohomologyClass; convert::Bool = false)
77
88
Construct a G4-flux candidate on an F-theory model. This functionality is
99
currently limited to
@@ -39,6 +39,9 @@ a long time. If the geometry in question is involved and you already know that t
3939
is simplicial and complete, then we recommend to trigger the computation of the cohomology
4040
ring with `check = false`. This will avoid this time consuming test.
4141
42+
Let us mention that you can also supply the option `convert = true`. This will turn the
43+
provided cohomology class into the basis chosen internally.
44+
4245
An example is in order.
4346
4447
# Examples
@@ -63,13 +66,51 @@ G4-flux candidate
6366
- Verticality checks: not executed
6467
- Non-abelian gauge group: breaking pattern not analyzed
6568
- Tadpole cancellation check: not executed
69+
70+
julia> cohomology_class(g4f2)
71+
Cohomology class on a normal toric variety given by 2*x5*e2 + 4*x5*u + 6*x5*e4 + 4*x5*e1 + 2*x5*w + 2*x6*e2 + 4*x6*u + 6*x6*e4 + 4*x6*e1 + 2*x6*w + 2*x7*x12 + 2*x7*e2 + 4*x7*u + 6*x7*e4 + 4*x7*e1 + 2*x7*w + 8*x8*x23 + 4*x10*x23 - 4*x15*x26 + 2*x15*e2 + 4*x15*u + 6*x15*e4 + 4*x15*e1 + 2*x15*w - 2*x16^2 + 2*x16*e2 + 4*x16*u + 6*x16*e4 + 4*x16*e1 + 2*x16*w - 22*x17*x24 + 4*x17*e2 + 8*x17*u + 12*x17*e4 + 8*x17*e1 + 4*x17*w - 10*x18^2 + 7//2*x18*x25 + 4*x18*e2 + 8*x18*u + 12*x18*e4 + 8*x18*e1 + 4*x18*w + 6*x19*e2 + 12*x19*u + 18*x19*e4 + 12*x19*e1 + 6*x19*w + 8*x20^2 + 88//3*x20*x21 - 7*x20*x25 + 4*x20*e2 + 8*x20*u + 12*x20*e4 + 8*x20*e1 + 4*x20*w + 11//3*x21^2 - 77//3*x21*x24 + 4*x21*e2 + 8*x21*u + 12*x21*e4 + 8*x21*e1 + 4*x21*w + 31//3*x22^2 + 5//3*x22*x23 + 97//6*x22*x25 + 4*x23^2 - 8*x24^2 - 17//3*x24*x27 + 2*x24*e2 + 4*x24*u + 6*x24*e4 + 4*x24*e1 + 2*x24*w + 7//2*x25^2 + 2*x25*e2 + 4*x25*u + 6*x25*e4 + 4*x25*e1 + 2*x25*w - 2//3*x26*x27 + 5//3*x27^2 + 2*x27*e2 + 4*x27*u + 6*x27*e4 + 4*x27*e1 + 2*x27*w + x28^2 - 7//3*x29^2 + 5*e1*w
72+
73+
julia> g4f3 = g4_flux(qsm_model, g4_class, check = false, convert = true)
74+
G4-flux candidate
75+
- Elementary quantization checks: not executed
76+
- Verticality checks: not executed
77+
- Non-abelian gauge group: breaking pattern not analyzed
78+
- Tadpole cancellation check: not executed
79+
80+
julia> cohomology_class(g4f3)
81+
Cohomology class on a normal toric variety given by 2*x5*e2 + 4*x5*u + 6*x5*e4 + 4*x5*e1 + 2*x5*w + 2*x6*e2 + 4*x6*u + 6*x6*e4 + 4*x6*e1 + 2*x6*w + 2*x7*x12 + 2*x7*e2 + 4*x7*u + 6*x7*e4 + 4*x7*e1 + 2*x7*w - 4*x15*x26 + 2*x15*e2 + 4*x15*u + 6*x15*e4 + 4*x15*e1 + 2*x15*w - 2*x16^2 + 2*x16*e2 + 4*x16*u + 6*x16*e4 + 4*x16*e1 + 2*x16*w - 6*x17*x24 + 4*x17*e2 + 8*x17*u + 12*x17*e4 + 8*x17*e1 + 4*x17*w - 10*x18^2 - 1//2*x18*x25 + 4*x18*e2 + 8*x18*u + 12*x18*e4 + 8*x18*e1 + 4*x18*w - 8*x19*x20 + 6*x19*e2 + 12*x19*u + 18*x19*e4 + 12*x19*e1 + 6*x19*w + 8*x20^2 + 56//3*x20*x21 + x20*x25 + 4*x20*e2 + 8*x20*u + 12*x20*e4 + 8*x20*e1 + 4*x20*w + 19//3*x21^2 - 13//3*x21*x24 + 4*x21*e2 + 8*x21*u + 12*x21*e4 + 8*x21*e1 + 4*x21*w - 1//3*x22^2 + 1//3*x22*x23 - 7//6*x22*x25 + 7//3*x24*x27 + 2*x24*e2 + 4*x24*u + 6*x24*e4 + 4*x24*e1 + 2*x24*w - 1//2*x25^2 + 2*x25*e2 + 4*x25*u + 6*x25*e4 + 4*x25*e1 + 2*x25*w - 2//3*x26*x27 + 5//3*x27^2 + 2*x27*e2 + 4*x27*u + 6*x27*e4 + 4*x27*e1 + 2*x27*w + x28^2 + 1//3*x29^2 + 5*e1*w
6682
```
6783
"""
68-
function g4_flux(m::AbstractFTheoryModel, g4_class::CohomologyClass; check::Bool = true)
84+
function g4_flux(m::AbstractFTheoryModel, g4_class::CohomologyClass; check::Bool = true, convert::Bool = false)
6985
@req (m isa WeierstrassModel || m isa GlobalTateModel || m isa HypersurfaceModel) "G4-fluxes only supported for Weierstrass, global Tate and hypersurface models"
7086
@req base_space(m) isa NormalToricVariety "G4-flux currently supported only for toric base"
7187
@req ambient_space(m) isa NormalToricVariety "G4-flux currently supported only for toric ambient space"
72-
g4_candidate = G4Flux(m, g4_class)
88+
89+
# If conversion to internally chosen basis desired, then modify the cohomology class
90+
if convert == true
91+
internal_basis = basis_of_h22(ambient_space(m), check = check)
92+
converter_dict = get_attribute(ambient_space(m), :converter_dict_h22)
93+
to_be_transformed_poly = lift(polynomial(g4_class))
94+
M = collect(exponents(lift(to_be_transformed_poly)))
95+
non_zero_exponents = Vector{Tuple{Int64, Int64}}()
96+
for my_row in M
97+
i1 = findfirst(x -> x != 0, my_row)
98+
my_row[i1] -= 1
99+
i2 = findfirst(x -> x != 0, my_row)
100+
push!(non_zero_exponents, (i1, i2))
101+
end
102+
coeffs = collect(coefficients(lift(to_be_transformed_poly)))
103+
@req length(coeffs) == length(non_zero_exponents) "Inconsistency encountered"
104+
converted_poly = cohomology_ring(ambient_space(m), check = check)(sum(coeffs[l] * lift(polynomial(converter_dict[non_zero_exponents[l]])) for l in 1:length(coeffs)))
105+
converted_class = CohomologyClass(ambient_space(m), converted_poly)
106+
else
107+
converted_class = g4_class
108+
end
109+
110+
# Build the G4-flux candidate
111+
g4_candidate = G4Flux(m, converted_class)
112+
113+
# Execute quantization checks if desired and return the created object
73114
if check && !is_well_quantized(g4_candidate)
74115
error("Given G4-flux candidate found to violate quantization condition")
75116
end

experimental/FTheoryTools/test/FTM-1511-03209.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,10 @@
1515
@test is_well_quantized(g1) == true
1616
@test is_vertical(g2) == true
1717
@test breaks_non_abelian_gauge_group(g3) == false
18+
@test size(matrix_integral(f1)) == (629, 502)
19+
@test size(matrix_rational(f1)) == (629, 127)
20+
@test size(matrix_integral(f2)) == (629, 224)
21+
@test size(matrix_rational(f2)) == (629, 127)
22+
@test size(matrix_integral(f3)) == (629, 1)
23+
@test size(matrix_rational(f3)) == (629, 127)
1824
end

0 commit comments

Comments
 (0)