@@ -327,6 +327,291 @@ true
327
327
end
328
328
329
329
330
+ @attr Vector{CohomologyClass} function converter_dict_h22 (v:: NormalToricVariety ; check:: Bool = true )
331
+
332
+ # (0) Some initial checks
333
+ if check
334
+ @req is_complete (v) " Computation of converter dict for H22 is currently only supported for complete toric varieties"
335
+ @req is_simplicial (v) " Computation of converter dict for H22 is currently only supported for simplicial toric varieties"
336
+ end
337
+ if dim (v) < 4
338
+ return Vector {CohomologyClass} ()
339
+ end
340
+
341
+ # (1) Prepare some data of the variety
342
+ mnf = Oscar. _minimal_nonfaces (v)
343
+ ignored_sets = Set ([Tuple (sort (Vector {Int} (Polymake. row (mnf, i)))) for i in 1 : Polymake. nrows (mnf)])
344
+
345
+ # (2) Prepare a dict that converts the "naive" generating set into our chosen basis
346
+ converter_dict = Dict {Tuple{Int, Int}, Any} ()
347
+ for k in 1 : n_rays (v)
348
+ for l in k: n_rays (v)
349
+ my_tuple = (k, l)
350
+ if (my_tuple in ignored_sets)
351
+ converter_dict[my_tuple] = 0
352
+ else
353
+ converter_dict[my_tuple] = nothing
354
+ end
355
+ end
356
+ end
357
+
358
+ # (3) Prepare the linear relations
359
+ N_lin_rel, my_mat = rref (transpose (matrix (QQ, rays (v))))
360
+ @req N_lin_rel == nrows (my_mat) " Cannot remove as many variables as there are linear relations - weird!"
361
+ bad_positions = [findfirst (! iszero, row) for row in eachrow (my_mat)]
362
+ lin_rels = Dict {Int, Vector{QQFieldElem}} ()
363
+ for k in 1 : nrows (my_mat)
364
+ my_relation = (- 1 ) * my_mat[k, :]
365
+ my_relation[bad_positions[k]] = 0
366
+ @req all (k -> k == 0 , my_relation[bad_positions]) " Inconsistency!"
367
+ lin_rels[bad_positions[k]] = my_relation
368
+ end
369
+
370
+ # (4) Apply linear relations to remaining entries in converter_dict
371
+ # (4) The code within the following for loop might need optimizing.
372
+ crg = gens (base_ring (cohomology_ring (v)))
373
+ for (key, value) in converter_dict
374
+ if value === nothing
375
+ image = Vector {Any} ()
376
+
377
+ # Only the first entry needs replacing by the linear relations
378
+ if (key[1 ] in keys (lin_rels)) && (key[2 ] in keys (lin_rels)) == false
379
+ my_relation = lin_rels[key[1 ]]
380
+ posi = findall (k -> k != 0 , my_relation)
381
+ coeffs = my_relation[posi]
382
+ for k in 1 : length (posi)
383
+ push! (image, [coeffs[k], (posi[k], key[2 ])])
384
+ end
385
+ end
386
+
387
+ # Only the second entry needs replacing by the linear relations
388
+ if (key[2 ] in keys (lin_rels)) && (key[1 ] in keys (lin_rels)) == false
389
+ my_relation = lin_rels[key[2 ]]
390
+ posi = findall (k -> k != 0 , my_relation)
391
+ coeffs = my_relation[posi]
392
+ for k in 1 : length (posi)
393
+ push! (image, [coeffs[k], (key[1 ], posi[k])])
394
+ end
395
+ end
396
+
397
+ # Both entry needs replacing by the linear relations
398
+ if (key[1 ] in keys (lin_rels)) && key[2 ] in keys (lin_rels)
399
+ my_relation = lin_rels[key[1 ]]
400
+ posi = findall (k -> k != 0 , my_relation)
401
+ coeffs = my_relation[posi]
402
+ for k in 1 : length (posi)
403
+ push! (image, [coeffs[k], (posi[k], key[2 ])])
404
+ end
405
+ my_relation = lin_rels[key[2 ]]
406
+ posi = findall (k -> k != 0 , my_relation)
407
+ coeffs = my_relation[posi]
408
+ old_image = copy (image)
409
+ image = Vector {Any} ()
410
+ for i in 1 : length (old_image)
411
+ for k in 1 : length (posi)
412
+ old_coeff = old_image[i][1 ]
413
+ push! (image, [old_coeff * coeffs[k], (old_image[i][2 ][1 ], posi[k])])
414
+ end
415
+ end
416
+ end
417
+
418
+ # If there was a replacement, update the key in the dict
419
+ if length (image) > 0
420
+ # image_as_cohomology_class = CohomologyClass(v, cohomology_ring(v)(sum(i[1] * crg[i[2][1]] * crg[i[2][2]] for i in image)))
421
+ # converter_dict[key] = image_as_cohomology_class
422
+ converter_dict[key] = image
423
+ end
424
+ end
425
+ end
426
+
427
+ # (5) Prepare a list of those variables that we keep, a.k.a. a basis of H^(1,1)
428
+ good_positions = setdiff (1 : n_rays (v), bad_positions)
429
+ n_good_positions = length (good_positions)
430
+
431
+ # (6) Make a list of all quadratic elements in the cohomology ring, which are not generators of the SR-ideal.
432
+ N_filtered_quadratic_elements = 0
433
+ dict_of_filtered_quadratic_elements = Dict {Tuple{Int64, Int64}, Int64} ()
434
+ for k in 1 : n_good_positions
435
+ for l in k: n_good_positions
436
+ my_tuple = (min (good_positions[k], good_positions[l]), max (good_positions[k], good_positions[l]))
437
+ if ! (my_tuple in ignored_sets)
438
+ N_filtered_quadratic_elements += 1
439
+ dict_of_filtered_quadratic_elements[my_tuple] = N_filtered_quadratic_elements
440
+ end
441
+ end
442
+ end
443
+
444
+ # (7) Consistency check
445
+ l1 = sort (collect (keys (converter_dict))[findall (k -> converter_dict[k] === nothing , collect (keys (converter_dict)))])
446
+ l2 = sort (collect (keys (dict_of_filtered_quadratic_elements)))
447
+ @req l1 == l2 " Inconsistency found"
448
+
449
+ # (8) We only care about the SR-ideal gens of degree 2. Above, we took care of all relations,
450
+ # (8) for which both variables are not replaced by one of the linear relations. So, let us identify
451
+ # (8) all remaining relations of the SR-ideal, and apply the linear relations to them.
452
+ remaining_relations = Vector {Vector{QQFieldElem}} ()
453
+ for my_tuple in ignored_sets
454
+
455
+ # The generator must have degree 2 and at least one variable is to be replaced
456
+ if length (my_tuple) == 2 && (my_tuple[1 ] in bad_positions || my_tuple[2 ] in bad_positions)
457
+
458
+ # Represent first variable by list of coefficients, after plugging in the linear relation
459
+ var1 = zeros (QQ, ncols (my_mat))
460
+ var1[my_tuple[1 ]] = 1
461
+ if my_tuple[1 ] in bad_positions
462
+ var1 = lin_rels[my_tuple[1 ]]
463
+ end
464
+
465
+ # Represent second variable by list of coefficients, after plugging in the linear relation
466
+ var2 = zeros (QQ, ncols (my_mat))
467
+ var2[my_tuple[2 ]] = 1
468
+ if my_tuple[2 ] in bad_positions
469
+ var2 = lin_rels[my_tuple[2 ]]
470
+ end
471
+
472
+ # Compute the product of the two variables, which represents the new relation
473
+ prod = zeros (QQ, N_filtered_quadratic_elements)
474
+ for k in 1 : length (var1)
475
+ if var1[k] != 0
476
+ for l in 1 : length (var2)
477
+ if var2[l] != 0
478
+ my_tuple = (min (k, l), max (k, l))
479
+ if haskey (dict_of_filtered_quadratic_elements, my_tuple)
480
+ prod[dict_of_filtered_quadratic_elements[my_tuple]] += var1[k] * var2[l]
481
+ end
482
+ end
483
+ end
484
+ end
485
+ end
486
+
487
+ # Remember the result
488
+ push! (remaining_relations, prod)
489
+
490
+ end
491
+
492
+ end
493
+
494
+ # (9) Identify variables that we can remove with the remaining relations
495
+ new_good_positions = 1 : N_filtered_quadratic_elements
496
+ if length (remaining_relations) != 0
497
+ remaining_relations_matrix = matrix (QQ, remaining_relations)
498
+ r, new_mat = rref (remaining_relations_matrix)
499
+ @req r == nrows (remaining_relations_matrix) " Cannot remove a variable via linear relations - weird!"
500
+ new_bad_positions = [findfirst (! iszero, row) for row in eachrow (new_mat)]
501
+ new_good_positions = setdiff (1 : N_filtered_quadratic_elements, new_bad_positions)
502
+ end
503
+
504
+ # (10) Some of the remaining variables are replaced by the final remaining variables
505
+ # (10) Above, we identified the remaining variables. Now we identify how the other variables
506
+ # (10) that appear in dict_of_filtered_quadratic_elements are replaced.
507
+ if length (remaining_relations) != 0
508
+ new_basis = collect (keys (dict_of_filtered_quadratic_elements))
509
+ for (key, value) in dict_of_filtered_quadratic_elements
510
+ if (value in new_good_positions) == false
511
+
512
+ # Find relation to repalce this basis element by
513
+ tuple_to_be_replaced = key
514
+ index_of_element_to_be_replaced = value
515
+ row_that_defines_relation = findfirst (k -> k == 1 , new_mat[:,index_of_element_to_be_replaced])
516
+ applicable_relation = new_mat[row_that_defines_relation, :]
517
+ applicable_relation[index_of_element_to_be_replaced] = 0
518
+ relation_to_be_applied = (- 1 ) * applicable_relation
519
+ 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 ]
520
+ if length (relation_to_be_applied) == 0
521
+ relation_to_be_applied = 0
522
+ end
523
+
524
+ # Apply this relation throughout converter_dict, so that this tuple is never used in the values
525
+ for (ikey, ivalue) in converter_dict
526
+
527
+ # If the entry maps to zero or is not yet specified, then nothing is to be done. Continue!
528
+ if ivalue == 0 || ivalue === nothing
529
+ continue
530
+ end
531
+
532
+ # Is replacement needed?
533
+ tuple_list = [k[2 ] for k in ivalue]
534
+ position_of_key = findfirst (k -> k == key, tuple_list)
535
+ if position_of_key != = nothing
536
+
537
+ # Prepare new lists for the tuples and coefficients
538
+ new_tuple_list = copy (tuple_list)
539
+ new_coeff_list = [k[1 ] for k in ivalue]
540
+
541
+ # Extract the coefficient of interest
542
+ coeff_in_question = new_coeff_list[position_of_key]
543
+
544
+ # Remove the tuple to be replaced, and its corresponding coefficient
545
+ deleteat! (new_tuple_list, position_of_key)
546
+ deleteat! (new_coeff_list, position_of_key)
547
+
548
+ # Is the list empty after the removal? If so, we map to zero
549
+ if length (new_tuple_list) == 0 && length (new_coeff_list) == 0
550
+ converter_dict[ikey] = 0
551
+ continue
552
+ end
553
+
554
+ # Apply relation for element in question
555
+ if relation_to_be_applied == 0
556
+ converter_dict[ikey] = [[new_coeff_list[a], new_tuple_list[a]] for a in 1 : length (new_tuple_list)]
557
+ else
558
+ for a in 1 : length (relation_to_be_applied)
559
+ if relation_to_be_applied[a][2 ] in new_tuple_list
560
+ position_of_tuple = findfirst (k -> k == relation_to_be_applied[a][2 ], new_tuple_list)
561
+ new_coeff_list[position_of_tuple] += relation_to_be_applied[a][1 ]
562
+ else
563
+ push! (new_tuple_list, relation_to_be_applied[a][2 ])
564
+ push! (new_coeff_list, relation_to_be_applied[a][1 ])
565
+ end
566
+ end
567
+ converter_dict[ikey] == [[new_coeff_list[a], new_tuple_list[a]] for a in 1 : length (new_tuple_list)]
568
+ end
569
+
570
+ end
571
+ end
572
+
573
+ # Assign this value to the tuple to be replaced
574
+ converter_dict[key] = relation_to_be_applied
575
+
576
+ end
577
+ end
578
+ end
579
+
580
+ # (11) Return the basis elements in terms of cohomology classes
581
+ S = cohomology_ring (v, check = check)
582
+ c_ds = [k. f for k in gens (S)]
583
+ final_list_of_tuples = Tuple{Int64, Int64}[]
584
+ for (key, value) in dict_of_filtered_quadratic_elements
585
+ if value in new_good_positions
586
+ push! (final_list_of_tuples, key)
587
+ end
588
+ end
589
+ 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]
590
+ set_attribute! (v, :basis_of_h22_indices , final_list_of_tuples)
591
+
592
+ # (12) Consistency check
593
+ l1 = sort (collect (keys (converter_dict))[findall (k -> converter_dict[k] === nothing , collect (keys (converter_dict)))])
594
+ @req l1 == sort (final_list_of_tuples) " Inconsistency found"
595
+
596
+ # (13) Convert all entries in converter_dict to cohomology classes and return the result
597
+ final_converter_dict = Dict {Tuple{Int, Int}, CohomologyClass} ()
598
+ for (key, value) in converter_dict
599
+ if value == nothing
600
+ final_converter_dict[key] = CohomologyClass (v, cohomology_ring (v)(crg[key[1 ]] * crg[key[2 ]]))
601
+ elseif value == 0
602
+ final_converter_dict[key] = CohomologyClass (v, zero (cohomology_ring (v, check = check)))
603
+ else
604
+ poly = sum (t[1 ] * crg[t[2 ][1 ]] * crg[t[2 ][2 ]] for t in value)
605
+ image_as_cohomology_class = CohomologyClass (v, cohomology_ring (v)(poly))
606
+ final_converter_dict[key] = image_as_cohomology_class
607
+ end
608
+ end
609
+ return converter_dict_h22
610
+
611
+ end
612
+
613
+
614
+
330
615
# The following is an internal function, that is being used to identify all well-quantized G4-fluxes.
331
616
# Let G4 in H^(2,2)(toric_ambient_space) a G4-flux ambient space candidate, i.e. the physically
332
617
# truly relevant quantity is the restriction of G4 to a hypersurface V(pt) in the toric_ambient_space.
0 commit comments