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"
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)]
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
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
153327end
154328
0 commit comments