Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ end


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


# (6) Work out the relevant intersection numbers to tell if a flux is vertical
Expand Down Expand Up @@ -622,7 +622,7 @@ end
# Compute against exceptional divisors
for j in 1:n_rays(base_space(m))
for k in 1:length(exceptional_divisor_positions)
my_tuple = Tuple(sort([ambient_space_flux_candidates_basis_indices[i]..., j, exceptional_divisor_positions[k]...]))
my_tuple = Tuple(sort([ambient_space_flux_candidates_basis_indices[i]..., [j, exceptional_divisor_positions[k]]...]))
push!(condition, sophisticated_intersection_product(ambient_space(m), my_tuple, hypersurface_equation(m), inter_dict, s_inter_dict, data))
end
end
Expand Down
190 changes: 182 additions & 8 deletions experimental/FTheoryTools/src/G4Fluxes/auxiliary.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ true
```
"""
@attr Vector{CohomologyClass} function basis_of_h22(v::NormalToricVariety; check::Bool = true)

# (0) Some initial checks
if check
@req is_complete(v) "Computation of basis of H22 is currently only supported for complete toric varieties"
Expand All @@ -50,11 +51,25 @@ true
if dim(v) < 4
return Vector{CohomologyClass}()
end

# (1) Prepare some data of the variety
mnf = Oscar._minimal_nonfaces(v)
ignored_sets = Set([Tuple(sort(Vector{Int}(Polymake.row(mnf, i)))) for i in 1:Polymake.nrows(mnf)])

# (2) Prepare the linear relations
# (2) Prepare a dict that converts the "naive" generating set into our chosen basis
converter_dict = Dict{Tuple{Int, Int}, Any}()
for k in 1:n_rays(v)
for l in k:n_rays(v)
my_tuple = (k, l)
if (my_tuple in ignored_sets)
converter_dict[my_tuple] = 0
else
converter_dict[my_tuple] = nothing
end
end
end

# (3) Prepare the linear relations
N_lin_rel, my_mat = rref(transpose(matrix(QQ, rays(v))))
@req N_lin_rel == nrows(my_mat) "Cannot remove as many variables as there are linear relations - weird!"
bad_positions = [findfirst(!iszero, row) for row in eachrow(my_mat)]
Expand All @@ -66,11 +81,68 @@ true
lin_rels[bad_positions[k]] = my_relation
end

# (3) Prepare a list of those variables that we keep, a.k.a. a basis of H^(1,1)
# (4) Apply linear relations to remaining entries in converter_dict
# (4) The code within the following for loop might need optimizing.
crg = gens(base_ring(cohomology_ring(v)))
for (key, value) in converter_dict
if value === nothing
image = Vector{Any}()

# Only the first entry needs replacing by the linear relations
if (key[1] in keys(lin_rels)) && (key[2] in keys(lin_rels)) == false
my_relation = lin_rels[key[1]]
posi = findall(k -> k != 0, my_relation)
coeffs = my_relation[posi]
for k in 1:length(posi)
push!(image, [coeffs[k], (posi[k], key[2])])
end
end

# Only the second entry needs replacing by the linear relations
if (key[2] in keys(lin_rels)) && (key[1] in keys(lin_rels)) == false
my_relation = lin_rels[key[2]]
posi = findall(k -> k != 0, my_relation)
coeffs = my_relation[posi]
for k in 1:length(posi)
push!(image, [coeffs[k], (key[1], posi[k])])
end
end

# Both entry needs replacing by the linear relations
if (key[1] in keys(lin_rels)) && key[2] in keys(lin_rels)
my_relation = lin_rels[key[1]]
posi = findall(k -> k != 0, my_relation)
coeffs = my_relation[posi]
for k in 1:length(posi)
push!(image, [coeffs[k], (posi[k], key[2])])
end
my_relation = lin_rels[key[2]]
posi = findall(k -> k != 0, my_relation)
coeffs = my_relation[posi]
old_image = copy(image)
image = Vector{Any}()
for i in 1:length(old_image)
for k in 1:length(posi)
old_coeff = old_image[i][1]
push!(image, [old_coeff * coeffs[k], (old_image[i][2][1], posi[k])])
end
end
end

# If there was a replacement, update the key in the dict
if length(image) > 0
#image_as_cohomology_class = CohomologyClass(v, cohomology_ring(v)(sum(i[1] * crg[i[2][1]] * crg[i[2][2]] for i in image)))
#converter_dict[key] = image_as_cohomology_class
converter_dict[key] = image
end
end
end

# (5) Prepare a list of those variables that we keep, a.k.a. a basis of H^(1,1)
good_positions = setdiff(1:n_rays(v), bad_positions)
n_good_positions = length(good_positions)

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

# (5) We only care about the SR-ideal gens of degree 2. Above, we took care of all relations,
# (5) for which both variables are not replaced by one of the linear relations. So, let us identify
# (5) all remaining relations of the SR-ideal, and apply the linear relations to them.
# (7) Consistency check
l1 = sort(collect(keys(converter_dict))[findall(k -> converter_dict[k] === nothing, collect(keys(converter_dict)))])
l2 = sort(collect(keys(dict_of_filtered_quadratic_elements)))
@req l1 == l2 "Inconsistency found"

# (8) We only care about the SR-ideal gens of degree 2. Above, we took care of all relations,
# (8) for which both variables are not replaced by one of the linear relations. So, let us identify
# (8) all remaining relations of the SR-ideal, and apply the linear relations to them.
remaining_relations = Vector{Vector{QQFieldElem}}()
for my_tuple in ignored_sets

Expand Down Expand Up @@ -137,8 +214,84 @@ true
new_bad_positions = [findfirst(!iszero, row) for row in eachrow(new_mat)]
new_good_positions = setdiff(1:N_filtered_quadratic_elements, new_bad_positions)
end

# (10) Return the basis elements in terms of cohomology classes

# (10) Some of the remaining variables are replaced by the final remaining variables
# (10) Above, we identified the remaining variables. Now we identify how the other variables
# (10) that appear in dict_of_filtered_quadratic_elements are replaced.
if length(remaining_relations) != 0
new_basis = collect(keys(dict_of_filtered_quadratic_elements))
for (key, value) in dict_of_filtered_quadratic_elements
if (value in new_good_positions) == false

# Find relation to repalce this basis element by
tuple_to_be_replaced = key
index_of_element_to_be_replaced = value
row_that_defines_relation = findfirst(k -> k == 1, new_mat[:,index_of_element_to_be_replaced])
applicable_relation = new_mat[row_that_defines_relation, :]
applicable_relation[index_of_element_to_be_replaced] = 0
relation_to_be_applied = (-1) * applicable_relation
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]
if length(relation_to_be_applied) == 0
relation_to_be_applied = 0
end

# Apply this relation throughout converter_dict, so that this tuple is never used in the values
for (ikey, ivalue) in converter_dict

# If the entry maps to zero or is not yet specified, then nothing is to be done. Continue!
if ivalue == 0 || ivalue === nothing
continue
end

# Is replacement needed?
tuple_list = [k[2] for k in ivalue]
position_of_key = findfirst(k -> k == key, tuple_list)
if position_of_key !== nothing

# Prepare new lists for the tuples and coefficients
new_tuple_list = copy(tuple_list)
new_coeff_list = [k[1] for k in ivalue]

# Extract the coefficient of interest
coeff_in_question = new_coeff_list[position_of_key]

# Remove the tuple to be replaced, and its corresponding coefficient
deleteat!(new_tuple_list, position_of_key)
deleteat!(new_coeff_list, position_of_key)

# Is the list empty after the removal? If so, we map to zero
if length(new_tuple_list) == 0 && length(new_coeff_list) == 0
converter_dict[ikey] = 0
continue
end

# Apply relation for element in question
if relation_to_be_applied == 0
converter_dict[ikey] = [[new_coeff_list[a], new_tuple_list[a]] for a in 1:length(new_tuple_list)]
else
for a in 1:length(relation_to_be_applied)
if relation_to_be_applied[a][2] in new_tuple_list
position_of_tuple = findfirst(k -> k == relation_to_be_applied[a][2], new_tuple_list)
new_coeff_list[position_of_tuple] += relation_to_be_applied[a][1]
else
push!(new_tuple_list, relation_to_be_applied[a][2])
push!(new_coeff_list, relation_to_be_applied[a][1])
end
end
converter_dict[ikey] == [[new_coeff_list[a], new_tuple_list[a]] for a in 1:length(new_tuple_list)]
end

end
end

# Assign this value to the tuple to be replaced
converter_dict[key] = relation_to_be_applied

end
end
end

# (11) Return the basis elements in terms of cohomology classes
S = cohomology_ring(v, check = check)
c_ds = [k.f for k in gens(S)]
final_list_of_tuples = Tuple{Int64, Int64}[]
Expand All @@ -149,6 +302,27 @@ true
end
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]
set_attribute!(v, :basis_of_h22_indices, final_list_of_tuples)

# (12) Consistency check
l1 = sort(collect(keys(converter_dict))[findall(k -> converter_dict[k] === nothing, collect(keys(converter_dict)))])
@req l1 == sort(final_list_of_tuples) "Inconsistency found"

# (13) Convert all entries in converter_dict to cohomology classes and save as attribute
final_converter_dict = Dict{Tuple{Int, Int}, CohomologyClass}()
for (key, value) in converter_dict
if value == nothing
final_converter_dict[key] = CohomologyClass(v, cohomology_ring(v)(crg[key[1]] *crg[key[2]]))
elseif value == 0
final_converter_dict[key] = CohomologyClass(v, zero(cohomology_ring(v, check = check)))
else
poly = sum(t[1] * crg[t[2][1]] * crg[t[2][2]] for t in value)
image_as_cohomology_class = CohomologyClass(v, cohomology_ring(v)(poly))
final_converter_dict[key] = image_as_cohomology_class
end
end
set_attribute!(v, :converter_dict_h22, final_converter_dict)

# (14) Return the result - finally!
return basis_of_h22
end

Expand Down
47 changes: 44 additions & 3 deletions experimental/FTheoryTools/src/G4Fluxes/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
################

@doc raw"""
g4_flux(model::AbstractFTheoryModel, class::CohomologyClass)
g4_flux(model::AbstractFTheoryModel, class::CohomologyClass; convert::Bool = false)

Construct a G4-flux candidate on an F-theory model. This functionality is
currently limited to
Expand Down Expand Up @@ -39,6 +39,9 @@ a long time. If the geometry in question is involved and you already know that t
is simplicial and complete, then we recommend to trigger the computation of the cohomology
ring with `check = false`. This will avoid this time consuming test.

Let us mention that you can also supply the option `convert = true`. This will turn the
provided cohomology class into the basis chosen internally.

An example is in order.

# Examples
Expand All @@ -63,13 +66,51 @@ G4-flux candidate
- Verticality checks: not executed
- Non-abelian gauge group: breaking pattern not analyzed
- Tadpole cancellation check: not executed

julia> cohomology_class(g4f2)
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

julia> g4f3 = g4_flux(qsm_model, g4_class, check = false, convert = true)
G4-flux candidate
- Elementary quantization checks: not executed
- Verticality checks: not executed
- Non-abelian gauge group: breaking pattern not analyzed
- Tadpole cancellation check: not executed

julia> cohomology_class(g4f3)
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
```
"""
function g4_flux(m::AbstractFTheoryModel, g4_class::CohomologyClass; check::Bool = true)
function g4_flux(m::AbstractFTheoryModel, g4_class::CohomologyClass; check::Bool = true, convert::Bool = false)
@req (m isa WeierstrassModel || m isa GlobalTateModel || m isa HypersurfaceModel) "G4-fluxes only supported for Weierstrass, global Tate and hypersurface models"
@req base_space(m) isa NormalToricVariety "G4-flux currently supported only for toric base"
@req ambient_space(m) isa NormalToricVariety "G4-flux currently supported only for toric ambient space"
g4_candidate = G4Flux(m, g4_class)

# If conversion to internally chosen basis desired, then modify the cohomology class
if convert == true
internal_basis = basis_of_h22(ambient_space(m), check = check)
converter_dict = get_attribute(ambient_space(m), :converter_dict_h22)
to_be_transformed_poly = lift(polynomial(g4_class))
M = collect(exponents(lift(to_be_transformed_poly)))
non_zero_exponents = Vector{Tuple{Int64, Int64}}()
for my_row in M
i1 = findfirst(x -> x != 0, my_row)
my_row[i1] -= 1
i2 = findfirst(x -> x != 0, my_row)
push!(non_zero_exponents, (i1, i2))
end
coeffs = collect(coefficients(lift(to_be_transformed_poly)))
@req length(coeffs) == length(non_zero_exponents) "Inconsistency encountered"
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)))
converted_class = CohomologyClass(ambient_space(m), converted_poly)
else
converted_class = g4_class
end

# Build the G4-flux candidate
g4_candidate = G4Flux(m, converted_class)

# Execute quantization checks if desired and return the created object
if check && !is_well_quantized(g4_candidate)
error("Given G4-flux candidate found to violate quantization condition")
end
Expand Down
6 changes: 6 additions & 0 deletions experimental/FTheoryTools/test/FTM-1511-03209.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@
@test is_well_quantized(g1) == true
@test is_vertical(g2) == true
@test breaks_non_abelian_gauge_group(g3) == false
@test size(matrix_integral(f1)) == (629, 502)
@test size(matrix_rational(f1)) == (629, 127)
@test size(matrix_integral(f2)) == (629, 224)
@test size(matrix_rational(f2)) == (629, 127)
@test size(matrix_integral(f3)) == (629, 1)
@test size(matrix_rational(f3)) == (629, 127)
end