passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_combinat/__init__.py +3 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
- passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
- passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
- passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
- sage/algebras/affine_nil_temperley_lieb.py +263 -0
- sage/algebras/all.py +24 -0
- sage/algebras/all__sagemath_combinat.py +35 -0
- sage/algebras/askey_wilson.py +935 -0
- sage/algebras/associated_graded.py +345 -0
- sage/algebras/cellular_basis.py +350 -0
- sage/algebras/cluster_algebra.py +2766 -0
- sage/algebras/down_up_algebra.py +860 -0
- sage/algebras/free_algebra.py +1698 -0
- sage/algebras/free_algebra_element.py +345 -0
- sage/algebras/free_algebra_quotient.py +405 -0
- sage/algebras/free_algebra_quotient_element.py +295 -0
- sage/algebras/free_zinbiel_algebra.py +885 -0
- sage/algebras/hall_algebra.py +783 -0
- sage/algebras/hecke_algebras/all.py +4 -0
- sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
- sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
- sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
- sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
- sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
- sage/algebras/iwahori_hecke_algebra.py +3095 -0
- sage/algebras/jordan_algebra.py +1773 -0
- sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
- sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
- sage/algebras/lie_conformal_algebras/all.py +18 -0
- sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
- sage/algebras/lie_conformal_algebras/examples.py +43 -0
- sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
- sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
- sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
- sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
- sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
- sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
- sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
- sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
- sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
- sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
- sage/algebras/nil_coxeter_algebra.py +191 -0
- sage/algebras/q_commuting_polynomials.py +673 -0
- sage/algebras/q_system.py +608 -0
- sage/algebras/quantum_clifford.py +959 -0
- sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
- sage/algebras/quantum_groups/all.py +9 -0
- sage/algebras/quantum_groups/fock_space.py +2219 -0
- sage/algebras/quantum_groups/q_numbers.py +207 -0
- sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
- sage/algebras/quantum_groups/representations.py +591 -0
- sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
- sage/algebras/quantum_oscillator.py +623 -0
- sage/algebras/quaternion_algebra.py +20 -0
- sage/algebras/quaternion_algebra_element.py +55 -0
- sage/algebras/rational_cherednik_algebra.py +525 -0
- sage/algebras/schur_algebra.py +670 -0
- sage/algebras/shuffle_algebra.py +1011 -0
- sage/algebras/splitting_algebra.py +779 -0
- sage/algebras/tensor_algebra.py +709 -0
- sage/algebras/yangian.py +1082 -0
- sage/algebras/yokonuma_hecke_algebra.py +1018 -0
- sage/all__sagemath_combinat.py +35 -0
- sage/combinat/SJT.py +255 -0
- sage/combinat/affine_permutation.py +2405 -0
- sage/combinat/algebraic_combinatorics.py +55 -0
- sage/combinat/all.py +53 -0
- sage/combinat/all__sagemath_combinat.py +195 -0
- sage/combinat/alternating_sign_matrix.py +2063 -0
- sage/combinat/baxter_permutations.py +346 -0
- sage/combinat/bijectionist.py +3220 -0
- sage/combinat/binary_recurrence_sequences.py +1180 -0
- sage/combinat/blob_algebra.py +685 -0
- sage/combinat/catalog_partitions.py +27 -0
- sage/combinat/chas/all.py +23 -0
- sage/combinat/chas/fsym.py +1180 -0
- sage/combinat/chas/wqsym.py +2601 -0
- sage/combinat/cluster_complex.py +326 -0
- sage/combinat/colored_permutations.py +2039 -0
- sage/combinat/colored_permutations_representations.py +964 -0
- sage/combinat/composition_signed.py +142 -0
- sage/combinat/composition_tableau.py +855 -0
- sage/combinat/constellation.py +1729 -0
- sage/combinat/core.py +751 -0
- sage/combinat/counting.py +12 -0
- sage/combinat/crystals/affine.py +742 -0
- sage/combinat/crystals/affine_factorization.py +518 -0
- sage/combinat/crystals/affinization.py +331 -0
- sage/combinat/crystals/alcove_path.py +2013 -0
- sage/combinat/crystals/all.py +22 -0
- sage/combinat/crystals/bkk_crystals.py +141 -0
- sage/combinat/crystals/catalog.py +115 -0
- sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
- sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
- sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
- sage/combinat/crystals/crystals.py +257 -0
- sage/combinat/crystals/direct_sum.py +260 -0
- sage/combinat/crystals/elementary_crystals.py +1251 -0
- sage/combinat/crystals/fast_crystals.py +441 -0
- sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
- sage/combinat/crystals/generalized_young_walls.py +1076 -0
- sage/combinat/crystals/highest_weight_crystals.py +436 -0
- sage/combinat/crystals/induced_structure.py +695 -0
- sage/combinat/crystals/infinity_crystals.py +730 -0
- sage/combinat/crystals/kac_modules.py +863 -0
- sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
- sage/combinat/crystals/kyoto_path_model.py +497 -0
- sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/letters.pxd +79 -0
- sage/combinat/crystals/letters.pyx +3056 -0
- sage/combinat/crystals/littelmann_path.py +1518 -0
- sage/combinat/crystals/monomial_crystals.py +1262 -0
- sage/combinat/crystals/multisegments.py +462 -0
- sage/combinat/crystals/mv_polytopes.py +467 -0
- sage/combinat/crystals/pbw_crystal.py +511 -0
- sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/pbw_datum.pxd +4 -0
- sage/combinat/crystals/pbw_datum.pyx +487 -0
- sage/combinat/crystals/polyhedral_realization.py +372 -0
- sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/spins.pxd +21 -0
- sage/combinat/crystals/spins.pyx +756 -0
- sage/combinat/crystals/star_crystal.py +290 -0
- sage/combinat/crystals/subcrystal.py +464 -0
- sage/combinat/crystals/tensor_product.py +1177 -0
- sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/tensor_product_element.pxd +35 -0
- sage/combinat/crystals/tensor_product_element.pyx +1870 -0
- sage/combinat/crystals/virtual_crystal.py +420 -0
- sage/combinat/cyclic_sieving_phenomenon.py +204 -0
- sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/degree_sequences.pyx +588 -0
- sage/combinat/derangements.py +527 -0
- sage/combinat/descent_algebra.py +1008 -0
- sage/combinat/diagram.py +1551 -0
- sage/combinat/diagram_algebras.py +5886 -0
- sage/combinat/dyck_word.py +4349 -0
- sage/combinat/e_one_star.py +1623 -0
- sage/combinat/enumerated_sets.py +123 -0
- sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/fast_vector_partitions.pyx +346 -0
- sage/combinat/fqsym.py +1977 -0
- sage/combinat/free_dendriform_algebra.py +954 -0
- sage/combinat/free_prelie_algebra.py +1141 -0
- sage/combinat/fully_commutative_elements.py +1077 -0
- sage/combinat/fully_packed_loop.py +1523 -0
- sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
- sage/combinat/gray_codes.py +311 -0
- sage/combinat/grossman_larson_algebras.py +667 -0
- sage/combinat/growth.py +4352 -0
- sage/combinat/hall_polynomial.py +188 -0
- sage/combinat/hillman_grassl.py +866 -0
- sage/combinat/integer_matrices.py +329 -0
- sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
- sage/combinat/k_tableau.py +4564 -0
- sage/combinat/kazhdan_lusztig.py +215 -0
- sage/combinat/key_polynomial.py +885 -0
- sage/combinat/knutson_tao_puzzles.py +2286 -0
- sage/combinat/lr_tableau.py +311 -0
- sage/combinat/matrices/all.py +24 -0
- sage/combinat/matrices/hadamard_matrix.py +3790 -0
- sage/combinat/matrices/latin.py +2912 -0
- sage/combinat/misc.py +401 -0
- sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
- sage/combinat/ncsf_qsym/all.py +21 -0
- sage/combinat/ncsf_qsym/combinatorics.py +317 -0
- sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
- sage/combinat/ncsf_qsym/ncsf.py +5637 -0
- sage/combinat/ncsf_qsym/qsym.py +4053 -0
- sage/combinat/ncsf_qsym/tutorial.py +447 -0
- sage/combinat/ncsym/all.py +21 -0
- sage/combinat/ncsym/bases.py +855 -0
- sage/combinat/ncsym/dual.py +593 -0
- sage/combinat/ncsym/ncsym.py +2076 -0
- sage/combinat/necklace.py +551 -0
- sage/combinat/non_decreasing_parking_function.py +634 -0
- sage/combinat/nu_dyck_word.py +1474 -0
- sage/combinat/output.py +861 -0
- sage/combinat/parallelogram_polyomino.py +4326 -0
- sage/combinat/parking_functions.py +1602 -0
- sage/combinat/partition_algebra.py +1998 -0
- sage/combinat/partition_kleshchev.py +1982 -0
- sage/combinat/partition_shifting_algebras.py +584 -0
- sage/combinat/partition_tuple.py +3114 -0
- sage/combinat/path_tableaux/all.py +13 -0
- sage/combinat/path_tableaux/catalog.py +29 -0
- sage/combinat/path_tableaux/dyck_path.py +380 -0
- sage/combinat/path_tableaux/frieze.py +476 -0
- sage/combinat/path_tableaux/path_tableau.py +728 -0
- sage/combinat/path_tableaux/semistandard.py +510 -0
- sage/combinat/perfect_matching.py +779 -0
- sage/combinat/plane_partition.py +3300 -0
- sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/q_bernoulli.pyx +128 -0
- sage/combinat/quickref.py +81 -0
- sage/combinat/recognizable_series.py +2051 -0
- sage/combinat/regular_sequence.py +4316 -0
- sage/combinat/regular_sequence_bounded.py +543 -0
- sage/combinat/restricted_growth.py +81 -0
- sage/combinat/ribbon.py +20 -0
- sage/combinat/ribbon_shaped_tableau.py +489 -0
- sage/combinat/ribbon_tableau.py +1180 -0
- sage/combinat/rigged_configurations/all.py +46 -0
- sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
- sage/combinat/rigged_configurations/bij_infinity.py +370 -0
- sage/combinat/rigged_configurations/bij_type_A.py +163 -0
- sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
- sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
- sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
- sage/combinat/rigged_configurations/bij_type_B.py +900 -0
- sage/combinat/rigged_configurations/bij_type_C.py +267 -0
- sage/combinat/rigged_configurations/bij_type_D.py +771 -0
- sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
- sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
- sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
- sage/combinat/rigged_configurations/bijection.py +143 -0
- sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
- sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
- sage/combinat/rigged_configurations/rc_crystal.py +461 -0
- sage/combinat/rigged_configurations/rc_infinity.py +540 -0
- sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
- sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
- sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
- sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
- sage/combinat/rsk.py +3438 -0
- sage/combinat/schubert_polynomial.py +508 -0
- sage/combinat/set_partition.py +3318 -0
- sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/set_partition_iterator.pyx +136 -0
- sage/combinat/set_partition_ordered.py +1590 -0
- sage/combinat/sf/abreu_nigro.py +346 -0
- sage/combinat/sf/all.py +52 -0
- sage/combinat/sf/character.py +576 -0
- sage/combinat/sf/classical.py +319 -0
- sage/combinat/sf/dual.py +996 -0
- sage/combinat/sf/elementary.py +549 -0
- sage/combinat/sf/hall_littlewood.py +1028 -0
- sage/combinat/sf/hecke.py +336 -0
- sage/combinat/sf/homogeneous.py +464 -0
- sage/combinat/sf/jack.py +1428 -0
- sage/combinat/sf/k_dual.py +1458 -0
- sage/combinat/sf/kfpoly.py +447 -0
- sage/combinat/sf/llt.py +789 -0
- sage/combinat/sf/macdonald.py +2019 -0
- sage/combinat/sf/monomial.py +525 -0
- sage/combinat/sf/multiplicative.py +113 -0
- sage/combinat/sf/new_kschur.py +1786 -0
- sage/combinat/sf/ns_macdonald.py +964 -0
- sage/combinat/sf/orthogonal.py +246 -0
- sage/combinat/sf/orthotriang.py +355 -0
- sage/combinat/sf/powersum.py +963 -0
- sage/combinat/sf/schur.py +880 -0
- sage/combinat/sf/sf.py +1653 -0
- sage/combinat/sf/sfa.py +7053 -0
- sage/combinat/sf/symplectic.py +253 -0
- sage/combinat/sf/witt.py +721 -0
- sage/combinat/shifted_primed_tableau.py +2735 -0
- sage/combinat/shuffle.py +830 -0
- sage/combinat/sidon_sets.py +146 -0
- sage/combinat/similarity_class_type.py +1721 -0
- sage/combinat/sine_gordon.py +618 -0
- sage/combinat/six_vertex_model.py +784 -0
- sage/combinat/skew_partition.py +2053 -0
- sage/combinat/skew_tableau.py +2989 -0
- sage/combinat/sloane_functions.py +8935 -0
- sage/combinat/specht_module.py +1403 -0
- sage/combinat/species/all.py +48 -0
- sage/combinat/species/characteristic_species.py +321 -0
- sage/combinat/species/composition_species.py +273 -0
- sage/combinat/species/cycle_species.py +284 -0
- sage/combinat/species/empty_species.py +155 -0
- sage/combinat/species/functorial_composition_species.py +148 -0
- sage/combinat/species/generating_series.py +673 -0
- sage/combinat/species/library.py +148 -0
- sage/combinat/species/linear_order_species.py +169 -0
- sage/combinat/species/misc.py +83 -0
- sage/combinat/species/partition_species.py +290 -0
- sage/combinat/species/permutation_species.py +268 -0
- sage/combinat/species/product_species.py +423 -0
- sage/combinat/species/recursive_species.py +476 -0
- sage/combinat/species/set_species.py +192 -0
- sage/combinat/species/species.py +820 -0
- sage/combinat/species/structure.py +539 -0
- sage/combinat/species/subset_species.py +243 -0
- sage/combinat/species/sum_species.py +225 -0
- sage/combinat/subword.py +564 -0
- sage/combinat/subword_complex.py +2122 -0
- sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/subword_complex_c.pyx +119 -0
- sage/combinat/super_tableau.py +821 -0
- sage/combinat/superpartition.py +1154 -0
- sage/combinat/symmetric_group_algebra.py +3774 -0
- sage/combinat/symmetric_group_representations.py +1830 -0
- sage/combinat/t_sequences.py +877 -0
- sage/combinat/tableau.py +9506 -0
- sage/combinat/tableau_residues.py +860 -0
- sage/combinat/tableau_tuple.py +5353 -0
- sage/combinat/tiling.py +2432 -0
- sage/combinat/triangles_FHM.py +777 -0
- sage/combinat/tutorial.py +1857 -0
- sage/combinat/vector_partition.py +337 -0
- sage/combinat/words/abstract_word.py +1722 -0
- sage/combinat/words/all.py +59 -0
- sage/combinat/words/alphabet.py +268 -0
- sage/combinat/words/finite_word.py +7201 -0
- sage/combinat/words/infinite_word.py +113 -0
- sage/combinat/words/lyndon_word.py +652 -0
- sage/combinat/words/morphic.py +351 -0
- sage/combinat/words/morphism.py +3878 -0
- sage/combinat/words/paths.py +2932 -0
- sage/combinat/words/shuffle_product.py +278 -0
- sage/combinat/words/suffix_trees.py +1873 -0
- sage/combinat/words/word.py +769 -0
- sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/words/word_datatypes.pxd +4 -0
- sage/combinat/words/word_datatypes.pyx +1067 -0
- sage/combinat/words/word_generators.py +2026 -0
- sage/combinat/words/word_infinite_datatypes.py +1218 -0
- sage/combinat/words/word_options.py +99 -0
- sage/combinat/words/words.py +2396 -0
- sage/data_structures/all__sagemath_combinat.py +1 -0
- sage/databases/all__sagemath_combinat.py +13 -0
- sage/databases/findstat.py +4897 -0
- sage/databases/oeis.py +2058 -0
- sage/databases/sloane.py +393 -0
- sage/dynamics/all__sagemath_combinat.py +14 -0
- sage/dynamics/cellular_automata/all.py +7 -0
- sage/dynamics/cellular_automata/catalog.py +34 -0
- sage/dynamics/cellular_automata/elementary.py +612 -0
- sage/dynamics/cellular_automata/glca.py +477 -0
- sage/dynamics/cellular_automata/solitons.py +1463 -0
- sage/dynamics/finite_dynamical_system.py +1249 -0
- sage/dynamics/finite_dynamical_system_catalog.py +382 -0
- sage/games/all.py +7 -0
- sage/games/hexad.py +704 -0
- sage/games/quantumino.py +591 -0
- sage/games/sudoku.py +889 -0
- sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
- sage/games/sudoku_backtrack.pyx +189 -0
- sage/groups/all__sagemath_combinat.py +1 -0
- sage/groups/indexed_free_group.py +489 -0
- sage/libs/all__sagemath_combinat.py +6 -0
- sage/libs/lrcalc/__init__.py +1 -0
- sage/libs/lrcalc/lrcalc.py +525 -0
- sage/libs/symmetrica/__init__.py +7 -0
- sage/libs/symmetrica/all.py +101 -0
- sage/libs/symmetrica/kostka.pxi +168 -0
- sage/libs/symmetrica/part.pxi +193 -0
- sage/libs/symmetrica/plet.pxi +42 -0
- sage/libs/symmetrica/sab.pxi +196 -0
- sage/libs/symmetrica/sb.pxi +332 -0
- sage/libs/symmetrica/sc.pxi +192 -0
- sage/libs/symmetrica/schur.pxi +956 -0
- sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/symmetrica/symmetrica.pxi +1172 -0
- sage/libs/symmetrica/symmetrica.pyx +39 -0
- sage/monoids/all.py +13 -0
- sage/monoids/automatic_semigroup.py +1054 -0
- sage/monoids/free_abelian_monoid.py +315 -0
- sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/monoids/free_abelian_monoid_element.pxd +16 -0
- sage/monoids/free_abelian_monoid_element.pyx +397 -0
- sage/monoids/free_monoid.py +335 -0
- sage/monoids/free_monoid_element.py +431 -0
- sage/monoids/hecke_monoid.py +65 -0
- sage/monoids/string_monoid.py +817 -0
- sage/monoids/string_monoid_element.py +547 -0
- sage/monoids/string_ops.py +143 -0
- sage/monoids/trace_monoid.py +972 -0
- sage/rings/all__sagemath_combinat.py +2 -0
- sage/sat/all.py +4 -0
- sage/sat/boolean_polynomials.py +405 -0
- sage/sat/converters/__init__.py +6 -0
- sage/sat/converters/anf2cnf.py +14 -0
- sage/sat/converters/polybori.py +611 -0
- sage/sat/solvers/__init__.py +5 -0
- sage/sat/solvers/cryptominisat.py +287 -0
- sage/sat/solvers/dimacs.py +783 -0
- sage/sat/solvers/picosat.py +228 -0
- sage/sat/solvers/sat_lp.py +156 -0
- sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
|
@@ -0,0 +1,2695 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: optional - gap_package_quagroup sage.combinat sage.libs.gap sage.modules
|
|
3
|
+
"""
|
|
4
|
+
Quantum Groups Using GAP's QuaGroup Package
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Travis Scrimshaw (03-2017): initial version
|
|
9
|
+
|
|
10
|
+
See the :gap_package:`documentation for GAP's QuaGroup package <quagroup/doc/chap0_mj.html>`,
|
|
11
|
+
originally authored by Willem Adriaan de Graaf.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# ****************************************************************************
|
|
15
|
+
# Copyright (C) 2017 Travis Scrimshaw <tcscrims at gmail.com>
|
|
16
|
+
#
|
|
17
|
+
# This program is free software: you can redistribute it and/or modify
|
|
18
|
+
# it under the terms of the GNU General Public License as published by
|
|
19
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
20
|
+
# (at your option) any later version.
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# ****************************************************************************
|
|
23
|
+
|
|
24
|
+
import re
|
|
25
|
+
|
|
26
|
+
from copy import copy
|
|
27
|
+
|
|
28
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
|
29
|
+
from sage.misc.lazy_import import lazy_import
|
|
30
|
+
from sage.misc.cachefunc import cached_method
|
|
31
|
+
from sage.structure.parent import Parent
|
|
32
|
+
from sage.structure.element import Element
|
|
33
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
34
|
+
from sage.structure.sage_object import SageObject
|
|
35
|
+
from sage.structure.richcmp import op_EQ, op_NE, richcmp
|
|
36
|
+
from sage.sets.non_negative_integers import NonNegativeIntegers
|
|
37
|
+
from sage.sets.family import Family
|
|
38
|
+
from sage.combinat.root_system.cartan_type import CartanType
|
|
39
|
+
from sage.libs.gap.libgap import libgap
|
|
40
|
+
from sage.features.gap import GapPackage
|
|
41
|
+
from sage.rings.rational_field import QQ
|
|
42
|
+
from sage.categories.algebras import Algebras
|
|
43
|
+
from sage.categories.cartesian_product import cartesian_product
|
|
44
|
+
from sage.categories.fields import Fields
|
|
45
|
+
from sage.categories.homset import HomsetWithBase, Hom
|
|
46
|
+
from sage.categories.hopf_algebras import HopfAlgebras
|
|
47
|
+
from sage.categories.modules import Modules
|
|
48
|
+
from sage.categories.morphism import Morphism
|
|
49
|
+
from sage.categories.rings import Rings
|
|
50
|
+
|
|
51
|
+
lazy_import('sage.graphs.digraph', 'DiGraph')
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class QuaGroupModuleElement(Element):
|
|
55
|
+
"""
|
|
56
|
+
Base class for elements created using QuaGroup.
|
|
57
|
+
"""
|
|
58
|
+
def __init__(self, parent, libgap_elt):
|
|
59
|
+
"""
|
|
60
|
+
Initialize ``self``.
|
|
61
|
+
|
|
62
|
+
EXAMPLES::
|
|
63
|
+
|
|
64
|
+
sage: Q = QuantumGroup(['G',2])
|
|
65
|
+
sage: TestSuite(Q.an_element()).run()
|
|
66
|
+
"""
|
|
67
|
+
self._libgap = libgap(libgap_elt)
|
|
68
|
+
Element.__init__(self, parent)
|
|
69
|
+
|
|
70
|
+
def _repr_(self):
|
|
71
|
+
"""
|
|
72
|
+
Return a string representation of ``self``.
|
|
73
|
+
|
|
74
|
+
EXAMPLES::
|
|
75
|
+
|
|
76
|
+
sage: Q = QuantumGroup(['G',2])
|
|
77
|
+
sage: Q.an_element()
|
|
78
|
+
1 + (q)*F[a1] + E[a1] + (q^2-1-q^-2 + q^-4)*[ K1 ; 2 ] + K1
|
|
79
|
+
+ (-q^-1 + q^-3)*K1[ K1 ; 1 ]
|
|
80
|
+
|
|
81
|
+
sage: Q = QuantumGroup(['D',4])
|
|
82
|
+
sage: Q.F_simple()
|
|
83
|
+
Finite family {1: F[a1], 2: F[a2], 3: F[a3], 4: F[a4]}
|
|
84
|
+
"""
|
|
85
|
+
# We add some space between the terms
|
|
86
|
+
# FIXME: This doesn't work to avoid within the () for the coeff's
|
|
87
|
+
c = re.compile(r"\+(?! [^(]* \))")
|
|
88
|
+
ret = re.sub(c, ' + ', repr(self._libgap))
|
|
89
|
+
# Replace Ei and Fi with the corresponding root in short form.
|
|
90
|
+
# Do the largest index first so, e.g., F12 gets replaced as 12
|
|
91
|
+
# instead of as 1.
|
|
92
|
+
for i, al in reversed(list(enumerate(self.parent()._pos_roots))):
|
|
93
|
+
short = '+'.join('%s*a%s' % (coeff, index)
|
|
94
|
+
if coeff != 1 else 'a%s' % index
|
|
95
|
+
for index, coeff in al)
|
|
96
|
+
ret = ret.replace('F%s' % (i + 1), 'F[%s]' % short)
|
|
97
|
+
ret = ret.replace('E%s' % (i + 1), 'E[%s]' % short)
|
|
98
|
+
return ret
|
|
99
|
+
|
|
100
|
+
def _latex_(self):
|
|
101
|
+
r"""
|
|
102
|
+
Return a latex representation of ``self``.
|
|
103
|
+
|
|
104
|
+
EXAMPLES::
|
|
105
|
+
|
|
106
|
+
sage: Q = QuantumGroup(['G',2])
|
|
107
|
+
sage: latex(Q.an_element())
|
|
108
|
+
1+{(q)} F_{\alpha_{1}}+E_{\alpha_{1}}+{(q^{2}-1-q^{-2}+q^{-4})}
|
|
109
|
+
[ K_{1} ; 2 ]+K_{1}+{(-q^{-1}+q^{-3})} K_{1}[ K_{1} ; 1 ]
|
|
110
|
+
|
|
111
|
+
sage: Q = QuantumGroup(['D',4])
|
|
112
|
+
sage: latex(list(Q.F_simple()))
|
|
113
|
+
\left[F_{\alpha_{1}}, F_{\alpha_{2}},
|
|
114
|
+
F_{\alpha_{3}}, F_{\alpha_{4}}\right]
|
|
115
|
+
"""
|
|
116
|
+
from sage.misc.latex import latex
|
|
117
|
+
ret = repr(self._libgap)
|
|
118
|
+
# Do the largest index first so, e.g., F12 gets replaced as 12
|
|
119
|
+
# instead of as 1.
|
|
120
|
+
for i, al in reversed(list(enumerate(self.parent()._pos_roots))):
|
|
121
|
+
ret = ret.replace('F%s' % (i + 1), 'F_{%s}' % latex(al))
|
|
122
|
+
ret = ret.replace('E%s' % (i + 1), 'E_{%s}' % latex(al))
|
|
123
|
+
for i, ii in reversed(list(enumerate(self.parent()._cartan_type.index_set()))):
|
|
124
|
+
ret = ret.replace('K%s' % (i + 1), 'K_{%s}' % ii)
|
|
125
|
+
# Fugly string parsing to get good looking latex
|
|
126
|
+
# TODO: Find a better way
|
|
127
|
+
ret = ret.replace('(', '{(')
|
|
128
|
+
ret = ret.replace(')', ')}')
|
|
129
|
+
ret = ret.replace('v0', 'v_0')
|
|
130
|
+
ret = ret.replace('*', ' ')
|
|
131
|
+
c = re.compile(r"q\^-?[0-9]*")
|
|
132
|
+
for m in reversed(list(c.finditer(ret))):
|
|
133
|
+
ret = ret[:m.start() + 2] + '{' + ret[m.start() + 2:m.end()] + '}' + ret[m.end():]
|
|
134
|
+
return ret
|
|
135
|
+
|
|
136
|
+
def __reduce__(self):
|
|
137
|
+
"""
|
|
138
|
+
Used in pickling.
|
|
139
|
+
|
|
140
|
+
EXAMPLES::
|
|
141
|
+
|
|
142
|
+
sage: Q = QuantumGroup(['G',2])
|
|
143
|
+
sage: x = Q.an_element()
|
|
144
|
+
sage: loads(dumps(x)) == x
|
|
145
|
+
True
|
|
146
|
+
"""
|
|
147
|
+
data = self._libgap.ExtRepOfObj()
|
|
148
|
+
R = self.base_ring()
|
|
149
|
+
ret = []
|
|
150
|
+
for i in range(len(data) // 2):
|
|
151
|
+
ret.append(data[2 * i].sage())
|
|
152
|
+
ret.append(R(str(data[2 * i + 1])))
|
|
153
|
+
return (_unpickle_generic_element, (self.parent(), ret))
|
|
154
|
+
|
|
155
|
+
def __hash__(self):
|
|
156
|
+
r"""
|
|
157
|
+
Return the hash of ``self``.
|
|
158
|
+
|
|
159
|
+
EXAMPLES::
|
|
160
|
+
|
|
161
|
+
sage: Q = QuantumGroup(['B',3])
|
|
162
|
+
sage: x = Q.an_element()
|
|
163
|
+
sage: hash(x) == hash(x.gap())
|
|
164
|
+
True
|
|
165
|
+
"""
|
|
166
|
+
return hash(self._libgap)
|
|
167
|
+
|
|
168
|
+
def _richcmp_(self, other, op):
|
|
169
|
+
"""
|
|
170
|
+
Rich comparison of ``self`` and ``other`` by ``op``.
|
|
171
|
+
|
|
172
|
+
EXAMPLES::
|
|
173
|
+
|
|
174
|
+
sage: Q = QuantumGroup(['A',2])
|
|
175
|
+
sage: x = Q.an_element()
|
|
176
|
+
sage: F1, F12, F2 = Q.F()
|
|
177
|
+
sage: q = Q.q()
|
|
178
|
+
sage: x == F1
|
|
179
|
+
False
|
|
180
|
+
sage: x != F1
|
|
181
|
+
True
|
|
182
|
+
sage: F2 * F1
|
|
183
|
+
(q)*F[a1]*F[a2] + F[a1+a2]
|
|
184
|
+
sage: F2 * F1 == q * F1 * F2 + F12
|
|
185
|
+
True
|
|
186
|
+
"""
|
|
187
|
+
return richcmp(self._libgap, other._libgap, op)
|
|
188
|
+
|
|
189
|
+
def gap(self):
|
|
190
|
+
r"""
|
|
191
|
+
Return the gap representation of ``self``.
|
|
192
|
+
|
|
193
|
+
EXAMPLES::
|
|
194
|
+
|
|
195
|
+
sage: Q = QuantumGroup(['B',3])
|
|
196
|
+
sage: x = Q.an_element()
|
|
197
|
+
sage: x.gap()
|
|
198
|
+
1+(q)*F1+E1+(q^4-1-q^-4+q^-8)*[ K1 ; 2 ]+K1+(-q^-2+q^-6)*K1[ K1 ; 1 ]
|
|
199
|
+
"""
|
|
200
|
+
return self._libgap
|
|
201
|
+
|
|
202
|
+
_libgap_ = _gap_ = gap
|
|
203
|
+
|
|
204
|
+
def _add_(self, other):
|
|
205
|
+
r"""
|
|
206
|
+
Add ``self`` and ``other``.
|
|
207
|
+
|
|
208
|
+
EXAMPLES::
|
|
209
|
+
|
|
210
|
+
sage: Q = QuantumGroup(['G',2])
|
|
211
|
+
sage: F1, F2 = Q.F_simple()
|
|
212
|
+
sage: F1 * F2 + F2 * F1
|
|
213
|
+
(q^3 + 1)*F[a1]*F[a2] + F[a1+a2]
|
|
214
|
+
"""
|
|
215
|
+
return self.__class__(self.parent(), self._libgap + other._libgap)
|
|
216
|
+
|
|
217
|
+
def _sub_(self, other):
|
|
218
|
+
r"""
|
|
219
|
+
Subtract ``self`` and ``other``.
|
|
220
|
+
|
|
221
|
+
EXAMPLES::
|
|
222
|
+
|
|
223
|
+
sage: Q = QuantumGroup(['G',2])
|
|
224
|
+
sage: F1, F2 = Q.F_simple()
|
|
225
|
+
sage: F1 * F2 - F2 * F1
|
|
226
|
+
(-q^3 + 1)*F[a1]*F[a2] + (-1)*F[a1+a2]
|
|
227
|
+
"""
|
|
228
|
+
return self.__class__(self.parent(), self._libgap - other._libgap)
|
|
229
|
+
|
|
230
|
+
def _acted_upon_(self, scalar, self_on_left=True):
|
|
231
|
+
r"""
|
|
232
|
+
Return the action of ``scalar`` on ``self``.
|
|
233
|
+
|
|
234
|
+
EXAMPLES::
|
|
235
|
+
|
|
236
|
+
sage: Q = QuantumGroup(['B',2])
|
|
237
|
+
sage: q = Q.q()
|
|
238
|
+
sage: x = Q.one().f_tilde([1,2,1,1,2,2]); x
|
|
239
|
+
F[a1+a2]^(3)
|
|
240
|
+
sage: 3 * x
|
|
241
|
+
(3)*F[a1+a2]^(3)
|
|
242
|
+
sage: x * (5/3)
|
|
243
|
+
(5/3)*F[a1+a2]^(3)
|
|
244
|
+
sage: q^-10 * x
|
|
245
|
+
(q^-10)*F[a1+a2]^(3)
|
|
246
|
+
sage: (1 + q^2 - q^-1) * x
|
|
247
|
+
(q^2 + 1-q^-1)*F[a1+a2]^(3)
|
|
248
|
+
"""
|
|
249
|
+
try:
|
|
250
|
+
scalar = self.parent().base_ring()(scalar)
|
|
251
|
+
scalar = scalar.subs(q=self.parent()._libgap_q)
|
|
252
|
+
except (TypeError, ValueError):
|
|
253
|
+
return None
|
|
254
|
+
return self.__class__(self.parent(), self._libgap * libgap(scalar))
|
|
255
|
+
|
|
256
|
+
def e_tilde(self, i):
|
|
257
|
+
r"""
|
|
258
|
+
Return the action of the Kashiwara operator
|
|
259
|
+
`\widetilde{e}_i` on ``self``.
|
|
260
|
+
|
|
261
|
+
INPUT:
|
|
262
|
+
|
|
263
|
+
- ``i`` -- an element of the index set or a list to
|
|
264
|
+
perform a string of operators
|
|
265
|
+
|
|
266
|
+
EXAMPLES::
|
|
267
|
+
|
|
268
|
+
sage: Q = QuantumGroup(['B',2])
|
|
269
|
+
sage: x = Q.one().f_tilde([1,2,1,1,2,2])
|
|
270
|
+
sage: x.e_tilde([2,2,1,2])
|
|
271
|
+
F[a1]^(2)
|
|
272
|
+
"""
|
|
273
|
+
# Do not override this method, instead implement _et
|
|
274
|
+
if isinstance(i, (list, tuple)):
|
|
275
|
+
ret = self
|
|
276
|
+
for j in i:
|
|
277
|
+
if not ret: # ret == 0
|
|
278
|
+
return ret
|
|
279
|
+
ret = ret._et(j)
|
|
280
|
+
return ret
|
|
281
|
+
return self._et(i)
|
|
282
|
+
|
|
283
|
+
def f_tilde(self, i):
|
|
284
|
+
r"""
|
|
285
|
+
Return the action of the Kashiwara operator
|
|
286
|
+
`\widetilde{f}_i` on ``self``.
|
|
287
|
+
|
|
288
|
+
INPUT:
|
|
289
|
+
|
|
290
|
+
- ``i`` -- an element of the index set or a list to
|
|
291
|
+
perform a string of operators
|
|
292
|
+
|
|
293
|
+
EXAMPLES::
|
|
294
|
+
|
|
295
|
+
sage: Q = QuantumGroup(['B',2])
|
|
296
|
+
sage: Q.one().f_tilde(1)
|
|
297
|
+
F[a1]
|
|
298
|
+
sage: Q.one().f_tilde(2)
|
|
299
|
+
F[a2]
|
|
300
|
+
sage: Q.one().f_tilde([1,2,1,1,2])
|
|
301
|
+
F[a1]*F[a1+a2]^(2)
|
|
302
|
+
"""
|
|
303
|
+
# Do not override this method, instead implement _ft
|
|
304
|
+
if isinstance(i, (list, tuple)):
|
|
305
|
+
ret = self
|
|
306
|
+
for j in i:
|
|
307
|
+
if not ret: # ret == 0
|
|
308
|
+
return ret
|
|
309
|
+
ret = ret._ft(j)
|
|
310
|
+
return ret
|
|
311
|
+
return self._ft(i)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
class QuantumGroup(UniqueRepresentation, Parent):
|
|
315
|
+
r"""
|
|
316
|
+
A Drinfel'd-Jimbo quantum group (implemented using the optional GAP
|
|
317
|
+
package ``QuaGroup``).
|
|
318
|
+
|
|
319
|
+
EXAMPLES:
|
|
320
|
+
|
|
321
|
+
We check the quantum Serre relations. We first we import the
|
|
322
|
+
`q`-binomial using the `q`-int for quantum groups::
|
|
323
|
+
|
|
324
|
+
sage: from sage.algebras.quantum_groups.q_numbers import q_binomial
|
|
325
|
+
|
|
326
|
+
We verify the Serre relations for type `A_2`::
|
|
327
|
+
|
|
328
|
+
sage: Q = algebras.QuantumGroup(['A',2])
|
|
329
|
+
sage: F1,F12,F2 = Q.F()
|
|
330
|
+
sage: q = Q.q()
|
|
331
|
+
sage: F1^2*F2 - q_binomial(2,1,q) * F1*F2*F1 + F2*F1^2
|
|
332
|
+
0
|
|
333
|
+
|
|
334
|
+
We verify the Serre relations for type `B_2`::
|
|
335
|
+
|
|
336
|
+
sage: Q = algebras.QuantumGroup(['B',2])
|
|
337
|
+
sage: F1, F12, F122, F2 = Q.F()
|
|
338
|
+
sage: F1^2*F2 - q_binomial(2,1,q^2) * F1*F2*F1 + F2*F1^2
|
|
339
|
+
0
|
|
340
|
+
sage: (F2^3*F1 - q_binomial(3,1,q) * F2^2*F1*F2
|
|
341
|
+
....: + q_binomial(3,2,q) * F2*F1*F2^2 - F1*F2^3)
|
|
342
|
+
0
|
|
343
|
+
|
|
344
|
+
REFERENCES:
|
|
345
|
+
|
|
346
|
+
- :wikipedia:`Quantum_group`
|
|
347
|
+
"""
|
|
348
|
+
@staticmethod
|
|
349
|
+
def __classcall_private__(cls, cartan_type, q=None):
|
|
350
|
+
"""
|
|
351
|
+
Initialize ``self``.
|
|
352
|
+
|
|
353
|
+
TESTS::
|
|
354
|
+
|
|
355
|
+
sage: Q = QuantumGroup(['A',2])
|
|
356
|
+
sage: Q is QuantumGroup('A2', None)
|
|
357
|
+
True
|
|
358
|
+
"""
|
|
359
|
+
cartan_type = CartanType(cartan_type)
|
|
360
|
+
return super().__classcall__(cls, cartan_type, q)
|
|
361
|
+
|
|
362
|
+
def __init__(self, cartan_type, q):
|
|
363
|
+
"""
|
|
364
|
+
Initialize ``self``.
|
|
365
|
+
|
|
366
|
+
TESTS::
|
|
367
|
+
|
|
368
|
+
sage: Q = QuantumGroup(['A',2])
|
|
369
|
+
sage: TestSuite(Q).run() # long time
|
|
370
|
+
|
|
371
|
+
sage: Q = QuantumGroup(['G',2])
|
|
372
|
+
sage: TestSuite(Q).run() # long time
|
|
373
|
+
"""
|
|
374
|
+
self._cartan_type = cartan_type
|
|
375
|
+
GapPackage("QuaGroup", spkg='gap_package_quagroup').require()
|
|
376
|
+
libgap.LoadPackage('QuaGroup')
|
|
377
|
+
R = libgap.eval('RootSystem("%s",%s)' % (cartan_type.type(), cartan_type.rank()))
|
|
378
|
+
Q = self._cartan_type.root_system().root_lattice()
|
|
379
|
+
I = cartan_type.index_set()
|
|
380
|
+
self._pos_roots = [Q.sum_of_terms([(ii, root[i])
|
|
381
|
+
for i, ii in enumerate(I)
|
|
382
|
+
if root[i] != 0])
|
|
383
|
+
for root in R.PositiveRootsInConvexOrder().sage()]
|
|
384
|
+
if q is None:
|
|
385
|
+
self._libgap = R.QuantizedUEA()
|
|
386
|
+
self._libgap_q = libgap.eval('_q')
|
|
387
|
+
self._libgap_base = libgap.eval('QuantumField')
|
|
388
|
+
base_field = QQ['q'].fraction_field()
|
|
389
|
+
q = base_field.gen()
|
|
390
|
+
else:
|
|
391
|
+
base_field = q.parent()
|
|
392
|
+
self._libgap = R.QuantizedUEA(base_field, q)
|
|
393
|
+
self._libgap_base = libgap(base_field)
|
|
394
|
+
self._libgap_q = libgap(q)
|
|
395
|
+
self._q = q
|
|
396
|
+
Parent.__init__(self, base=base_field, category=HopfAlgebras(Fields()))
|
|
397
|
+
|
|
398
|
+
def _repr_(self):
|
|
399
|
+
"""
|
|
400
|
+
Return a string representation of ``self``.
|
|
401
|
+
|
|
402
|
+
EXAMPLES::
|
|
403
|
+
|
|
404
|
+
sage: QuantumGroup(['A',2])
|
|
405
|
+
Quantum Group of type ['A', 2] with q=q
|
|
406
|
+
"""
|
|
407
|
+
return "Quantum Group of type {} with q={}".format(self._cartan_type, self._q)
|
|
408
|
+
|
|
409
|
+
def _latex_(self):
|
|
410
|
+
r"""
|
|
411
|
+
Return a latex representation of ``self``.
|
|
412
|
+
|
|
413
|
+
EXAMPLES::
|
|
414
|
+
|
|
415
|
+
sage: latex(QuantumGroup(['A',3]))
|
|
416
|
+
U_{q}(A_{3})
|
|
417
|
+
sage: zeta3 = CyclotomicField(3).gen()
|
|
418
|
+
sage: latex(QuantumGroup(['G',2], q=zeta3))
|
|
419
|
+
U_{\zeta_{3}}(G_2)
|
|
420
|
+
"""
|
|
421
|
+
from sage.misc.latex import latex
|
|
422
|
+
return "U_{%s}(%s)" % (latex(self._q), latex(self._cartan_type))
|
|
423
|
+
|
|
424
|
+
def gap(self):
|
|
425
|
+
"""
|
|
426
|
+
Return the gap representation of ``self``.
|
|
427
|
+
|
|
428
|
+
EXAMPLES::
|
|
429
|
+
|
|
430
|
+
sage: Q = QuantumGroup(['A',2])
|
|
431
|
+
sage: Q.gap()
|
|
432
|
+
QuantumUEA( <root system of type A2>, Qpar = q )
|
|
433
|
+
"""
|
|
434
|
+
return self._libgap
|
|
435
|
+
|
|
436
|
+
_libgap_ = _gap_ = gap
|
|
437
|
+
|
|
438
|
+
def cartan_type(self):
|
|
439
|
+
"""
|
|
440
|
+
Return the Cartan type of ``self``.
|
|
441
|
+
|
|
442
|
+
EXAMPLES::
|
|
443
|
+
|
|
444
|
+
sage: Q = QuantumGroup(['A',2])
|
|
445
|
+
sage: Q.cartan_type()
|
|
446
|
+
['A', 2]
|
|
447
|
+
"""
|
|
448
|
+
return self._cartan_type
|
|
449
|
+
|
|
450
|
+
def _element_constructor_(self, elt):
|
|
451
|
+
"""
|
|
452
|
+
Construct an element of ``self`` from ``elt``.
|
|
453
|
+
|
|
454
|
+
EXAMPLES::
|
|
455
|
+
|
|
456
|
+
sage: Q = QuantumGroup(['A',2])
|
|
457
|
+
sage: Q(0)
|
|
458
|
+
0
|
|
459
|
+
sage: Q(4)
|
|
460
|
+
(4)*1
|
|
461
|
+
sage: Q(4).parent() is Q
|
|
462
|
+
True
|
|
463
|
+
sage: Q(Q.q()).parent() is Q
|
|
464
|
+
True
|
|
465
|
+
sage: Q(Q.an_element()) == Q.an_element()
|
|
466
|
+
True
|
|
467
|
+
"""
|
|
468
|
+
if not elt:
|
|
469
|
+
return self.zero()
|
|
470
|
+
if elt in self.base_ring():
|
|
471
|
+
return elt * self.one()
|
|
472
|
+
return self.element_class(self, elt)
|
|
473
|
+
|
|
474
|
+
# Special elements
|
|
475
|
+
# ----------------
|
|
476
|
+
|
|
477
|
+
@cached_method
|
|
478
|
+
def one(self):
|
|
479
|
+
"""
|
|
480
|
+
Return the multiplicative identity of ``self``.
|
|
481
|
+
|
|
482
|
+
EXAMPLES::
|
|
483
|
+
|
|
484
|
+
sage: Q = QuantumGroup(['A',2])
|
|
485
|
+
sage: Q.one()
|
|
486
|
+
1
|
|
487
|
+
"""
|
|
488
|
+
return self.element_class(self, self._libgap.One())
|
|
489
|
+
|
|
490
|
+
@cached_method
|
|
491
|
+
def zero(self):
|
|
492
|
+
"""
|
|
493
|
+
Return the multiplicative identity of ``self``.
|
|
494
|
+
|
|
495
|
+
EXAMPLES::
|
|
496
|
+
|
|
497
|
+
sage: Q = QuantumGroup(['A',2])
|
|
498
|
+
sage: Q.zero()
|
|
499
|
+
0
|
|
500
|
+
"""
|
|
501
|
+
return self.element_class(self, self._libgap.ZeroImmutable())
|
|
502
|
+
|
|
503
|
+
@cached_method
|
|
504
|
+
def gens(self) -> tuple:
|
|
505
|
+
"""
|
|
506
|
+
Return the generators of ``self``.
|
|
507
|
+
|
|
508
|
+
EXAMPLES::
|
|
509
|
+
|
|
510
|
+
sage: Q = QuantumGroup(['A',2])
|
|
511
|
+
sage: Q.gens()
|
|
512
|
+
(F[a1], F[a1+a2], F[a2],
|
|
513
|
+
K1, (-q + q^-1)*[ K1 ; 1 ] + K1,
|
|
514
|
+
K2, (-q + q^-1)*[ K2 ; 1 ] + K2,
|
|
515
|
+
E[a1], E[a1+a2], E[a2])
|
|
516
|
+
"""
|
|
517
|
+
return tuple([self.element_class(self, gen)
|
|
518
|
+
for gen in self._libgap.GeneratorsOfAlgebra()])
|
|
519
|
+
|
|
520
|
+
def E(self):
|
|
521
|
+
r"""
|
|
522
|
+
Return the family of generators `\{E_{\alpha}\}_{\alpha \in \Phi}`,
|
|
523
|
+
where `\Phi` is the root system of ``self``.
|
|
524
|
+
|
|
525
|
+
EXAMPLES::
|
|
526
|
+
|
|
527
|
+
sage: Q = QuantumGroup(['B',2])
|
|
528
|
+
sage: list(Q.E())
|
|
529
|
+
[E[a1], E[a1+a2], E[a1+2*a2], E[a2]]
|
|
530
|
+
"""
|
|
531
|
+
N = len(self._pos_roots) + len(self._cartan_type.index_set()) * 2
|
|
532
|
+
d = {al: self.gens()[N + i] for i, al in enumerate(self._pos_roots)}
|
|
533
|
+
return Family(self._pos_roots, d.__getitem__)
|
|
534
|
+
|
|
535
|
+
def E_simple(self):
|
|
536
|
+
r"""
|
|
537
|
+
Return the family of generators `\{E_i := E_{\alpha_i}\}_{i \in I}`.
|
|
538
|
+
|
|
539
|
+
EXAMPLES::
|
|
540
|
+
|
|
541
|
+
sage: Q = QuantumGroup(['B',2])
|
|
542
|
+
sage: Q.E_simple()
|
|
543
|
+
Finite family {1: E[a1], 2: E[a2]}
|
|
544
|
+
"""
|
|
545
|
+
I = self._cartan_type.index_set()
|
|
546
|
+
gens = self.algebra_generators()
|
|
547
|
+
d = {i: gens['E%s' % i] for i in I}
|
|
548
|
+
return Family(I, d.__getitem__)
|
|
549
|
+
|
|
550
|
+
def F(self):
|
|
551
|
+
r"""
|
|
552
|
+
Return the family of generators `\{F_{\alpha}\}_{\alpha \in \Phi}`,
|
|
553
|
+
where `\Phi` is the root system of ``self``.
|
|
554
|
+
|
|
555
|
+
EXAMPLES::
|
|
556
|
+
|
|
557
|
+
sage: Q = QuantumGroup(['G',2])
|
|
558
|
+
sage: list(Q.F())
|
|
559
|
+
[F[a1], F[3*a1+a2], F[2*a1+a2], F[3*a1+2*a2], F[a1+a2], F[a2]]
|
|
560
|
+
"""
|
|
561
|
+
d = {al: self.gens()[i] for i, al in enumerate(self._pos_roots)}
|
|
562
|
+
return Family(self._pos_roots, d.__getitem__)
|
|
563
|
+
|
|
564
|
+
def F_simple(self):
|
|
565
|
+
r"""
|
|
566
|
+
Return the family of generators `\{F_i := F_{\alpha_i}\}_{i \in I}`.
|
|
567
|
+
|
|
568
|
+
EXAMPLES::
|
|
569
|
+
|
|
570
|
+
sage: Q = QuantumGroup(['G',2])
|
|
571
|
+
sage: Q.F_simple()
|
|
572
|
+
Finite family {1: F[a1], 2: F[a2]}
|
|
573
|
+
"""
|
|
574
|
+
I = self._cartan_type.index_set()
|
|
575
|
+
gens = self.algebra_generators()
|
|
576
|
+
d = {i: gens['F%s' % i] for i in I}
|
|
577
|
+
return Family(I, d.__getitem__)
|
|
578
|
+
|
|
579
|
+
def K(self):
|
|
580
|
+
r"""
|
|
581
|
+
Return the family of generators `\{K_i\}_{i \in I}`.
|
|
582
|
+
|
|
583
|
+
EXAMPLES::
|
|
584
|
+
|
|
585
|
+
sage: Q = QuantumGroup(['A',3])
|
|
586
|
+
sage: Q.K()
|
|
587
|
+
Finite family {1: K1, 2: K2, 3: K3}
|
|
588
|
+
sage: Q.K_inverse()
|
|
589
|
+
Finite family {1: (-q + q^-1)*[ K1 ; 1 ] + K1,
|
|
590
|
+
2: (-q + q^-1)*[ K2 ; 1 ] + K2,
|
|
591
|
+
3: (-q + q^-1)*[ K3 ; 1 ] + K3}
|
|
592
|
+
"""
|
|
593
|
+
N = len(self._pos_roots)
|
|
594
|
+
I = self._cartan_type.index_set()
|
|
595
|
+
d = {ii: self.gens()[N + 2 * i] for i, ii in enumerate(I)}
|
|
596
|
+
return Family(I, d.__getitem__)
|
|
597
|
+
|
|
598
|
+
def K_inverse(self):
|
|
599
|
+
r"""
|
|
600
|
+
Return the family of generators `\{K_i^{-1}\}_{i \in I}`.
|
|
601
|
+
|
|
602
|
+
EXAMPLES::
|
|
603
|
+
|
|
604
|
+
sage: Q = QuantumGroup(['A',3])
|
|
605
|
+
sage: Q.K_inverse()
|
|
606
|
+
Finite family {1: (-q + q^-1)*[ K1 ; 1 ] + K1,
|
|
607
|
+
2: (-q + q^-1)*[ K2 ; 1 ] + K2,
|
|
608
|
+
3: (-q + q^-1)*[ K3 ; 1 ] + K3}
|
|
609
|
+
"""
|
|
610
|
+
N = len(self._pos_roots)
|
|
611
|
+
I = self._cartan_type.index_set()
|
|
612
|
+
d = {ii: self.gens()[N + 2 * i + 1] for i, ii in enumerate(I)}
|
|
613
|
+
return Family(I, d.__getitem__)
|
|
614
|
+
|
|
615
|
+
@cached_method
|
|
616
|
+
def algebra_generators(self):
|
|
617
|
+
"""
|
|
618
|
+
Return the algebra generators of ``self``.
|
|
619
|
+
|
|
620
|
+
EXAMPLES::
|
|
621
|
+
|
|
622
|
+
sage: Q = QuantumGroup(['A',2])
|
|
623
|
+
sage: list(Q.algebra_generators())
|
|
624
|
+
[F[a1], F[a2],
|
|
625
|
+
K1, K2,
|
|
626
|
+
(-q + q^-1)*[ K1 ; 1 ] + K1, (-q + q^-1)*[ K2 ; 1 ] + K2,
|
|
627
|
+
E[a1], E[a2]]
|
|
628
|
+
"""
|
|
629
|
+
I = self._cartan_type.index_set()
|
|
630
|
+
simples = self._cartan_type.root_system().root_lattice().simple_roots()
|
|
631
|
+
ret = {}
|
|
632
|
+
for i, al in enumerate(simples):
|
|
633
|
+
ii = I[i]
|
|
634
|
+
ret['F%s' % ii] = self.F()[al]
|
|
635
|
+
ret['K%s' % ii] = self.K()[ii]
|
|
636
|
+
ret['Ki%s' % ii] = self.K_inverse()[ii]
|
|
637
|
+
ret['E%s' % ii] = self.E()[al]
|
|
638
|
+
keys = (['F%s' % i for i in I] + ['K%s' % i for i in I]
|
|
639
|
+
+ ['Ki%s' % i for i in I] + ['E%s' % i for i in I])
|
|
640
|
+
return Family(keys, ret.__getitem__)
|
|
641
|
+
|
|
642
|
+
def _an_element_(self):
|
|
643
|
+
"""
|
|
644
|
+
Return an element of ``self``.
|
|
645
|
+
|
|
646
|
+
EXAMPLES::
|
|
647
|
+
|
|
648
|
+
sage: Q = QuantumGroup(['A',2])
|
|
649
|
+
sage: Q.an_element()
|
|
650
|
+
1 + (q)*F[a1] + E[a1] + (q^2-1-q^-2 + q^-4)*[ K1 ; 2 ]
|
|
651
|
+
+ K1 + (-q^-1 + q^-3)*K1[ K1 ; 1 ]
|
|
652
|
+
"""
|
|
653
|
+
i = self._cartan_type.index_set()[0]
|
|
654
|
+
al = self._cartan_type.root_system().root_lattice().simple_root(i)
|
|
655
|
+
return self.E()[al] + self.K()[i] + self.K_inverse()[i]**2 + self.q()*self.F()[al]
|
|
656
|
+
|
|
657
|
+
def some_elements(self):
|
|
658
|
+
"""
|
|
659
|
+
Return some elements of ``self``.
|
|
660
|
+
|
|
661
|
+
EXAMPLES::
|
|
662
|
+
|
|
663
|
+
sage: Q = QuantumGroup(['A',1])
|
|
664
|
+
sage: Q.some_elements()
|
|
665
|
+
[1 + (q)*F[a1] + E[a1] + (q^2-1-q^-2 + q^-4)*[ K1 ; 2 ]
|
|
666
|
+
+ K1 + (-q^-1 + q^-3)*K1[ K1 ; 1 ],
|
|
667
|
+
K1, F[a1], E[a1]]
|
|
668
|
+
"""
|
|
669
|
+
return ([self.an_element()] + list(self.K())
|
|
670
|
+
+ list(self.F_simple()) + list(self.E_simple()))
|
|
671
|
+
|
|
672
|
+
def q(self):
|
|
673
|
+
"""
|
|
674
|
+
Return the parameter `q`.
|
|
675
|
+
|
|
676
|
+
EXAMPLES::
|
|
677
|
+
|
|
678
|
+
sage: Q = QuantumGroup(['A',3])
|
|
679
|
+
sage: Q.q()
|
|
680
|
+
q
|
|
681
|
+
sage: zeta3 = CyclotomicField(3).gen()
|
|
682
|
+
sage: Q = QuantumGroup(['B',2], q=zeta3)
|
|
683
|
+
sage: Q.q()
|
|
684
|
+
zeta3
|
|
685
|
+
"""
|
|
686
|
+
return self._q
|
|
687
|
+
|
|
688
|
+
# Misc
|
|
689
|
+
# ----
|
|
690
|
+
|
|
691
|
+
def _Hom_(self, Y, category):
|
|
692
|
+
"""
|
|
693
|
+
Return the highest weight module of weight ``weight`` of ``self``.
|
|
694
|
+
|
|
695
|
+
EXAMPLES::
|
|
696
|
+
|
|
697
|
+
sage: Q = QuantumGroup(['A',2])
|
|
698
|
+
sage: B = Q.lower_half()
|
|
699
|
+
sage: H = Hom(Q, B); H
|
|
700
|
+
Set of Morphisms from Quantum Group of type ['A', 2] with q=q to
|
|
701
|
+
Lower Half of Quantum Group of type ['A', 2] with q=q in Category of rings
|
|
702
|
+
sage: type(H)
|
|
703
|
+
<class '...QuantumGroupHomset_with_category_with_equality_by_id'>
|
|
704
|
+
"""
|
|
705
|
+
if category is not None and not category.is_subcategory(Rings()):
|
|
706
|
+
raise TypeError("%s is not a subcategory of Rings()" % category)
|
|
707
|
+
if Y not in Rings():
|
|
708
|
+
raise TypeError("%s is not a ring" % Y)
|
|
709
|
+
return QuantumGroupHomset(self, Y, category=category)
|
|
710
|
+
|
|
711
|
+
def highest_weight_module(self, weight):
|
|
712
|
+
"""
|
|
713
|
+
Return the highest weight module of weight ``weight`` of ``self``.
|
|
714
|
+
|
|
715
|
+
EXAMPLES::
|
|
716
|
+
|
|
717
|
+
sage: Q = QuantumGroup(['A',2])
|
|
718
|
+
sage: Q.highest_weight_module([1,3])
|
|
719
|
+
Highest weight module of weight Lambda[1] + 3*Lambda[2] of
|
|
720
|
+
Quantum Group of type ['A', 2] with q=q
|
|
721
|
+
"""
|
|
722
|
+
return HighestWeightModule(self, weight)
|
|
723
|
+
|
|
724
|
+
def lower_half(self):
|
|
725
|
+
"""
|
|
726
|
+
Return the lower half of the quantum group ``self``.
|
|
727
|
+
|
|
728
|
+
EXAMPLES::
|
|
729
|
+
|
|
730
|
+
sage: Q = QuantumGroup(['A',2])
|
|
731
|
+
sage: Q.lower_half()
|
|
732
|
+
Lower Half of Quantum Group of type ['A', 2] with q=q
|
|
733
|
+
"""
|
|
734
|
+
return LowerHalfQuantumGroup(self)
|
|
735
|
+
|
|
736
|
+
# Hopf structure
|
|
737
|
+
# --------------
|
|
738
|
+
|
|
739
|
+
def coproduct(self, elt, n=1):
|
|
740
|
+
r"""
|
|
741
|
+
Return the coproduct of ``elt`` (iterated ``n`` times).
|
|
742
|
+
|
|
743
|
+
The comultiplication `\Delta \colon U_q(\mathfrak{g}) \to
|
|
744
|
+
U_q(\mathfrak{g}) \otimes U_q(\mathfrak{g})` is defined by
|
|
745
|
+
|
|
746
|
+
.. MATH::
|
|
747
|
+
|
|
748
|
+
\begin{aligned}
|
|
749
|
+
\Delta(E_i) &= E_i \otimes 1 + K_i \otimes E_i, \\
|
|
750
|
+
\Delta(F_i) &= F_i \otimes K_i^{-1} + 1 \otimes F_i, \\
|
|
751
|
+
\Delta(K_i) &= K_i \otimes K_i.
|
|
752
|
+
\end{aligned}
|
|
753
|
+
|
|
754
|
+
EXAMPLES::
|
|
755
|
+
|
|
756
|
+
sage: Q = QuantumGroup(['B',2])
|
|
757
|
+
sage: [Q.coproduct(e) for e in Q.E()]
|
|
758
|
+
[1*(E[a1]<x>1) + 1*(K1<x>E[a1]),
|
|
759
|
+
1*(E[a1+a2]<x>1) + 1*(K1*K2<x>E[a1+a2]) + q^2-q^-2*(K2*E[a1]<x>E[a2]),
|
|
760
|
+
q^4-q^2-1 + q^-2*(E[a1]<x>E[a2]^(2)) + 1*(E[a1+2*a2]<x>1)
|
|
761
|
+
+ 1*(K1<x>E[a1+2*a2]) + q-q^-1*(K1*K2[ K2 ; 1 ]<x>E[a1+2*a2])
|
|
762
|
+
+ q-q^-1*(K2*E[a1+a2]<x>E[a2]) + q^5-2*q^3
|
|
763
|
+
+ 2*q^-1-q^-3*(K2[ K2 ; 1 ]*E[a1]<x>E[a2]^(2)),
|
|
764
|
+
1*(E[a2]<x>1) + 1*(K2<x>E[a2])]
|
|
765
|
+
sage: [Q.coproduct(f, 2) for f in Q.F_simple()]
|
|
766
|
+
[1*(1<x>1<x>F[a1]) + -q^2 + q^-2*(1<x>F[a1]<x>[ K1 ; 1 ])
|
|
767
|
+
+ 1*(1<x>F[a1]<x>K1) + q^4-2 + q^-4*(F[a1]<x>[ K1 ; 1 ]<x>[ K1 ; 1 ])
|
|
768
|
+
+ -q^2 + q^-2*(F[a1]<x>[ K1 ; 1 ]<x>K1) + -q^2
|
|
769
|
+
+ q^-2*(F[a1]<x>K1<x>[ K1 ; 1 ]) + 1*(F[a1]<x>K1<x>K1),
|
|
770
|
+
1*(1<x>1<x>F[a2]) + -q + q^-1*(1<x>F[a2]<x>[ K2 ; 1 ])
|
|
771
|
+
+ 1*(1<x>F[a2]<x>K2) + q^2-2 + q^-2*(F[a2]<x>[ K2 ; 1 ]<x>[ K2 ; 1 ])
|
|
772
|
+
+ -q + q^-1*(F[a2]<x>[ K2 ; 1 ]<x>K2) + -q
|
|
773
|
+
+ q^-1*(F[a2]<x>K2<x>[ K2 ; 1 ]) + 1*(F[a2]<x>K2<x>K2)]
|
|
774
|
+
"""
|
|
775
|
+
D = self._libgap.ComultiplicationMap(n+1)
|
|
776
|
+
# TODO: This is not the correct parent. Need to create it.
|
|
777
|
+
return self.element_class(self, libgap.Image(D, elt._libgap))
|
|
778
|
+
|
|
779
|
+
def antipode(self, elt):
|
|
780
|
+
r"""
|
|
781
|
+
Return the antipode of ``elt``.
|
|
782
|
+
|
|
783
|
+
The antipode `S \colon U_q(\mathfrak{g}) \to U_q(\mathfrak{g})`
|
|
784
|
+
is the anti-automorphism defined by
|
|
785
|
+
|
|
786
|
+
.. MATH::
|
|
787
|
+
|
|
788
|
+
S(E_i) = -K_i^{-1}E_i, \qquad
|
|
789
|
+
S(F_i) = -F_iK_i, \qquad
|
|
790
|
+
S(K_i) = K_i^{-1}.
|
|
791
|
+
|
|
792
|
+
EXAMPLES::
|
|
793
|
+
|
|
794
|
+
sage: Q = QuantumGroup(['B',2])
|
|
795
|
+
sage: [Q.antipode(f) for f in Q.F()]
|
|
796
|
+
[(-1)*F[a1]*K1,
|
|
797
|
+
(-q^6 + q^2)*F[a1]*F[a2]*K1*K2 + (-q^4)*F[a1+a2]*K1*K2,
|
|
798
|
+
(-q^8 + q^6 + q^4-q^2)*F[a1]*F[a2]^(2)*K1
|
|
799
|
+
+ (-q^9 + 2*q^7-2*q^3 + q)*F[a1]*F[a2]^(2)*K1*K2[ K2 ; 1 ]
|
|
800
|
+
+ (-q^5 + q^3)*F[a1+a2]*F[a2]*K1
|
|
801
|
+
+ (-q^6 + 2*q^4-q^2)*F[a1+a2]*F[a2]*K1*K2[ K2 ; 1 ]
|
|
802
|
+
+ (-q^4)*F[a1+2*a2]*K1 + (-q^5 + q^3)*F[a1+2*a2]*K1*K2[ K2 ; 1 ],
|
|
803
|
+
(-1)*F[a2]*K2]
|
|
804
|
+
"""
|
|
805
|
+
S = self._libgap.AntipodeMap()
|
|
806
|
+
return self.element_class(self, libgap.Image(S, elt._libgap))
|
|
807
|
+
|
|
808
|
+
def counit(self, elt):
|
|
809
|
+
r"""
|
|
810
|
+
Return the counit of ``elt``.
|
|
811
|
+
|
|
812
|
+
The counit `\varepsilon \colon U_q(\mathfrak{g}) \to \QQ(q)` is
|
|
813
|
+
defined by
|
|
814
|
+
|
|
815
|
+
.. MATH::
|
|
816
|
+
|
|
817
|
+
\varepsilon(E_i) = \varepsilon(F_i) = 0, \qquad
|
|
818
|
+
\varepsilon(K_i) = 1.
|
|
819
|
+
|
|
820
|
+
EXAMPLES::
|
|
821
|
+
|
|
822
|
+
sage: Q = QuantumGroup(['B',2])
|
|
823
|
+
sage: x = Q.an_element()^2
|
|
824
|
+
sage: Q.counit(x)
|
|
825
|
+
4
|
|
826
|
+
sage: Q.counit(Q.one())
|
|
827
|
+
1
|
|
828
|
+
sage: Q.counit(Q.zero())
|
|
829
|
+
0
|
|
830
|
+
"""
|
|
831
|
+
# We need to extract the constant coefficient because the
|
|
832
|
+
# counit in QuaGroup doesn't support it
|
|
833
|
+
R = self.base_ring()
|
|
834
|
+
ext_rep = list(elt._libgap.ExtRepOfObj())
|
|
835
|
+
constant = R.zero()
|
|
836
|
+
for i in range(len(ext_rep) // 2):
|
|
837
|
+
if ext_rep[2 * i].Length() == 0:
|
|
838
|
+
ext_rep.pop(2 * i) # Pop the key
|
|
839
|
+
constant = R(str(ext_rep.pop(2 * i))) # Pop the coefficient
|
|
840
|
+
break
|
|
841
|
+
# To reconstruct, we need the following
|
|
842
|
+
F = self._libgap.FamilyObj().ElementsFamily()
|
|
843
|
+
elt = F.ObjByExtRep(ext_rep)
|
|
844
|
+
co = self._libgap.CounitMap()
|
|
845
|
+
return R(str(co(elt))) + constant
|
|
846
|
+
|
|
847
|
+
class Element(QuaGroupModuleElement):
|
|
848
|
+
def _mul_(self, other):
|
|
849
|
+
r"""
|
|
850
|
+
Multiply ``self`` and ``other``.
|
|
851
|
+
|
|
852
|
+
EXAMPLES::
|
|
853
|
+
|
|
854
|
+
sage: Q = QuantumGroup(['G',2])
|
|
855
|
+
sage: F1, F2 = Q.F_simple()
|
|
856
|
+
sage: F1 * F2 * F1 * F2
|
|
857
|
+
F[a1]*F[a1+a2]*F[a2] + (q^7 + q^5 + q + q^-1)*F[a1]^(2)*F[a2]^(2)
|
|
858
|
+
sage: E1, E2 = Q.E_simple()
|
|
859
|
+
sage: F1 * E1
|
|
860
|
+
F[a1]*E[a1]
|
|
861
|
+
sage: E1 * F1
|
|
862
|
+
F[a1]*E[a1] + [ K1 ; 1 ]
|
|
863
|
+
"""
|
|
864
|
+
return self.__class__(self.parent(), self._libgap * other._libgap)
|
|
865
|
+
|
|
866
|
+
def bar(self):
|
|
867
|
+
r"""
|
|
868
|
+
Return the bar involution on ``self``.
|
|
869
|
+
|
|
870
|
+
The bar involution is defined by
|
|
871
|
+
|
|
872
|
+
.. MATH::
|
|
873
|
+
|
|
874
|
+
\overline{E_i} = E_i, \qquad\qquad
|
|
875
|
+
\overline{F_i} = F_i, \qquad\qquad
|
|
876
|
+
\overline{K_i} = K_i^{-1}.
|
|
877
|
+
|
|
878
|
+
EXAMPLES::
|
|
879
|
+
|
|
880
|
+
sage: Q = QuantumGroup(['A',2])
|
|
881
|
+
sage: [gen.bar() for gen in Q.gens()]
|
|
882
|
+
[F[a1],
|
|
883
|
+
(q-q^-1)*F[a1]*F[a2] + F[a1+a2],
|
|
884
|
+
F[a2],
|
|
885
|
+
(-q + q^-1)*[ K1 ; 1 ] + K1, K1,
|
|
886
|
+
(-q + q^-1)*[ K2 ; 1 ] + K2, K2,
|
|
887
|
+
E[a1],
|
|
888
|
+
(-q^2 + 1)*E[a1]*E[a2] + (q^2)*E[a1+a2],
|
|
889
|
+
E[a2]]
|
|
890
|
+
"""
|
|
891
|
+
bar = self.parent()._libgap.BarAutomorphism()
|
|
892
|
+
return self.__class__(self.parent(), libgap.Image(bar, self._libgap))
|
|
893
|
+
|
|
894
|
+
def omega(self):
|
|
895
|
+
r"""
|
|
896
|
+
Return the action of the `\omega` automorphism on ``self``.
|
|
897
|
+
|
|
898
|
+
The `\omega` automorphism is defined by
|
|
899
|
+
|
|
900
|
+
.. MATH::
|
|
901
|
+
|
|
902
|
+
\omega(E_i) = F_i, \qquad\qquad
|
|
903
|
+
\omega(F_i) = E_i, \qquad\qquad
|
|
904
|
+
\omega(K_i) = K_i^{-1}.
|
|
905
|
+
|
|
906
|
+
EXAMPLES::
|
|
907
|
+
|
|
908
|
+
sage: Q = QuantumGroup(['A',2])
|
|
909
|
+
sage: [gen.omega() for gen in Q.gens()]
|
|
910
|
+
[E[a1],
|
|
911
|
+
(-q)*E[a1+a2],
|
|
912
|
+
E[a2],
|
|
913
|
+
(-q + q^-1)*[ K1 ; 1 ] + K1,
|
|
914
|
+
K1,
|
|
915
|
+
(-q + q^-1)*[ K2 ; 1 ] + K2,
|
|
916
|
+
K2,
|
|
917
|
+
F[a1],
|
|
918
|
+
(-q^-1)*F[a1+a2],
|
|
919
|
+
F[a2]]
|
|
920
|
+
"""
|
|
921
|
+
omega = self.parent()._libgap.AutomorphismOmega()
|
|
922
|
+
return self.__class__(self.parent(), libgap.Image(omega, self._libgap))
|
|
923
|
+
|
|
924
|
+
def tau(self):
|
|
925
|
+
r"""
|
|
926
|
+
Return the action of the `\tau` anti-automorphism on ``self``.
|
|
927
|
+
|
|
928
|
+
The `\tau` anti-automorphism is defined by
|
|
929
|
+
|
|
930
|
+
.. MATH::
|
|
931
|
+
|
|
932
|
+
\tau(E_i) = E_i, \qquad\qquad
|
|
933
|
+
\tau(F_i) = F_i, \qquad\qquad
|
|
934
|
+
\tau(K_i) = K_i^{-1}.
|
|
935
|
+
|
|
936
|
+
EXAMPLES::
|
|
937
|
+
|
|
938
|
+
sage: Q = QuantumGroup(['A',2])
|
|
939
|
+
sage: [gen.tau() for gen in Q.gens()]
|
|
940
|
+
[F[a1],
|
|
941
|
+
(-q^2 + 1)*F[a1]*F[a2] + (-q)*F[a1+a2],
|
|
942
|
+
F[a2],
|
|
943
|
+
(-q + q^-1)*[ K1 ; 1 ] + K1,
|
|
944
|
+
K1,
|
|
945
|
+
(-q + q^-1)*[ K2 ; 1 ] + K2,
|
|
946
|
+
K2,
|
|
947
|
+
E[a1],
|
|
948
|
+
(q-q^-1)*E[a1]*E[a2] + (-q)*E[a1+a2],
|
|
949
|
+
E[a2]]
|
|
950
|
+
"""
|
|
951
|
+
tau = self.parent()._libgap.AntiAutomorphismTau()
|
|
952
|
+
return self.__class__(self.parent(), libgap.Image(tau, self._libgap))
|
|
953
|
+
|
|
954
|
+
def braid_group_action(self, braid):
|
|
955
|
+
r"""
|
|
956
|
+
Return the action of the braid group element ``braid``.
|
|
957
|
+
|
|
958
|
+
The braid group operator `T_i \colon U_q(\mathfrak{g}) \to
|
|
959
|
+
U_q(\mathfrak{g})` is defined by
|
|
960
|
+
|
|
961
|
+
.. MATH::
|
|
962
|
+
|
|
963
|
+
\begin{aligned}
|
|
964
|
+
T_i(E_i) &= -F_iK_i, \\
|
|
965
|
+
T_i(E_j) &= \sum_{k=0}^{-a_{ij}} (-1)^k q_i^{-k} E_i^{(-a_{ij}-k)} E_j E_i^{(k)} \text{ if } i \neq j,\\
|
|
966
|
+
T_i(K_j) &= K_jK_i^{a_{ij}}, \\
|
|
967
|
+
T_i(F_i) &= -K_i^{-1}E_i, \\
|
|
968
|
+
T_i(F_j) &= \sum_{k=0}^{-a_{ij}} (-1)^k q_i^{-k} F_i^{(k)} F_j F_i^{(-a_{ij}-k)} \text{ if } i \neq j,
|
|
969
|
+
\end{aligned}
|
|
970
|
+
|
|
971
|
+
where `a_{ij} = \langle \alpha_j, \alpha_i^\vee \rangle` is the
|
|
972
|
+
`(i,j)`-entry of the Cartan matrix associated to `\mathfrak{g}`.
|
|
973
|
+
|
|
974
|
+
INPUT:
|
|
975
|
+
|
|
976
|
+
- ``braid`` -- a reduced word of a braid group element
|
|
977
|
+
|
|
978
|
+
EXAMPLES::
|
|
979
|
+
|
|
980
|
+
sage: Q = QuantumGroup(['A',2])
|
|
981
|
+
sage: F1 = Q.F_simple()[1]
|
|
982
|
+
sage: F1.braid_group_action([1])
|
|
983
|
+
(q-q^-1)*[ K1 ; 1 ]*E[a1] + (-1)*K1*E[a1]
|
|
984
|
+
sage: F1.braid_group_action([1,2])
|
|
985
|
+
F[a2]
|
|
986
|
+
sage: F1.braid_group_action([2,1])
|
|
987
|
+
(-q^3 + 3*q-3*q^-1 + q^-3)*[ K1 ; 1 ]*[ K2 ; 1 ]*E[a1]*E[a2]
|
|
988
|
+
+ (q^3-2*q + q^-1)*[ K1 ; 1 ]*[ K2 ; 1 ]*E[a1+a2]
|
|
989
|
+
+ (q^2-2 + q^-2)*[ K1 ; 1 ]*K2*E[a1]*E[a2]
|
|
990
|
+
+ (-q^2 + 1)*[ K1 ; 1 ]*K2*E[a1+a2]
|
|
991
|
+
+ (q^2-2 + q^-2)*K1*[ K2 ; 1 ]*E[a1]*E[a2]
|
|
992
|
+
+ (-q^2 + 1)*K1*[ K2 ; 1 ]*E[a1+a2]
|
|
993
|
+
+ (-q + q^-1)*K1*K2*E[a1]*E[a2] + (q)*K1*K2*E[a1+a2]
|
|
994
|
+
sage: F1.braid_group_action([1,2,1]) == F1.braid_group_action([2,1,2])
|
|
995
|
+
True
|
|
996
|
+
sage: F1.braid_group_action([]) == F1
|
|
997
|
+
True
|
|
998
|
+
"""
|
|
999
|
+
if not braid:
|
|
1000
|
+
return self
|
|
1001
|
+
QU = self.parent()._libgap
|
|
1002
|
+
tau = QU.AntiAutomorphismTau()
|
|
1003
|
+
ret = QU.IdentityMapping()
|
|
1004
|
+
for i in braid:
|
|
1005
|
+
if i < 0:
|
|
1006
|
+
i = -i
|
|
1007
|
+
T = QU.AutomorphismTalpha(i)
|
|
1008
|
+
ret *= tau * T * tau
|
|
1009
|
+
else:
|
|
1010
|
+
ret *= QU.AutomorphismTalpha(i)
|
|
1011
|
+
return self.__class__(self.parent(), libgap.Image(ret, self._libgap))
|
|
1012
|
+
|
|
1013
|
+
def _et(self, i):
|
|
1014
|
+
r"""
|
|
1015
|
+
Return the action of the Kashiwara operator `\widetilde{e}_i`
|
|
1016
|
+
on ``self``.
|
|
1017
|
+
|
|
1018
|
+
EXAMPLES::
|
|
1019
|
+
|
|
1020
|
+
sage: Q = QuantumGroup(['G',2])
|
|
1021
|
+
sage: [(g.e_tilde(1), g.e_tilde(2)) for g in Q.F()]
|
|
1022
|
+
[(1, 0), (0, F[a1]^(3)), (0, F[a1]^(2)),
|
|
1023
|
+
(0, F[3*a1+a2]), (0, F[a1]), (0, 1)]
|
|
1024
|
+
|
|
1025
|
+
TESTS::
|
|
1026
|
+
|
|
1027
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1028
|
+
sage: Q.one()._et(1)
|
|
1029
|
+
0
|
|
1030
|
+
sage: Q.zero().e_tilde(1)
|
|
1031
|
+
0
|
|
1032
|
+
"""
|
|
1033
|
+
if not self: # self == 0
|
|
1034
|
+
return self
|
|
1035
|
+
ret = self._libgap.Ealpha(i)
|
|
1036
|
+
if not ret:
|
|
1037
|
+
return self.parent().zero()
|
|
1038
|
+
return self.__class__(self.parent(), ret)
|
|
1039
|
+
|
|
1040
|
+
def _ft(self, i):
|
|
1041
|
+
r"""
|
|
1042
|
+
Return the action of the Kashiwara operator `\widetilde{f}_i`
|
|
1043
|
+
on ``self``.
|
|
1044
|
+
|
|
1045
|
+
EXAMPLES::
|
|
1046
|
+
|
|
1047
|
+
sage: Q = QuantumGroup(['G',2])
|
|
1048
|
+
sage: [(g._ft(1), g._ft(2)) for g in Q.F()]
|
|
1049
|
+
[(F[a1]^(2), F[a1+a2]),
|
|
1050
|
+
(F[a1]*F[3*a1+a2], F[3*a1+2*a2]),
|
|
1051
|
+
(F[a1]*F[2*a1+a2], F[a1+a2]^(2)),
|
|
1052
|
+
(F[a1]*F[3*a1+2*a2], F[a1+a2]^(3)),
|
|
1053
|
+
(F[a1]*F[a1+a2], F[a1+a2]*F[a2]),
|
|
1054
|
+
(F[a1]*F[a2], F[a2]^(2))]
|
|
1055
|
+
sage: Q.one().f_tilde([1,2,1,1,2,2])
|
|
1056
|
+
F[2*a1+a2]*F[a1+a2]*F[a2]
|
|
1057
|
+
|
|
1058
|
+
TESTS::
|
|
1059
|
+
|
|
1060
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1061
|
+
sage: Q.zero().f_tilde(1)
|
|
1062
|
+
0
|
|
1063
|
+
"""
|
|
1064
|
+
if not self: # self == 0
|
|
1065
|
+
return self
|
|
1066
|
+
ret = self._libgap.Falpha(i)
|
|
1067
|
+
if not ret:
|
|
1068
|
+
return self.parent().zero()
|
|
1069
|
+
return self.__class__(self.parent(), ret)
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
#####################################################################
|
|
1073
|
+
# Morphisms
|
|
1074
|
+
|
|
1075
|
+
class QuantumGroupMorphism(Morphism):
|
|
1076
|
+
r"""
|
|
1077
|
+
A morphism whose domain is a quantum group.
|
|
1078
|
+
"""
|
|
1079
|
+
def __init__(self, parent, im_gens, check=True):
|
|
1080
|
+
r"""
|
|
1081
|
+
Initialize ``self``.
|
|
1082
|
+
|
|
1083
|
+
EXAMPLES::
|
|
1084
|
+
|
|
1085
|
+
sage: Q = QuantumGroup(['A',1])
|
|
1086
|
+
sage: F, K, Ki, E = Q.gens()
|
|
1087
|
+
sage: phi = Q.hom([E, Ki, K, F])
|
|
1088
|
+
sage: TestSuite(phi).run(skip='_test_category')
|
|
1089
|
+
"""
|
|
1090
|
+
self._repr_type_str = "Quantum group homomorphism"
|
|
1091
|
+
Morphism.__init__(self, parent)
|
|
1092
|
+
Q = parent.domain()
|
|
1093
|
+
self._im_gens = tuple(im_gens)
|
|
1094
|
+
if check and len(im_gens) != len(Q.algebra_generators()):
|
|
1095
|
+
raise ValueError("number of images must equal the number of generators")
|
|
1096
|
+
self._libgap = Q._libgap.QEAHomomorphism(parent.codomain(), im_gens)
|
|
1097
|
+
|
|
1098
|
+
def __reduce__(self):
|
|
1099
|
+
r"""
|
|
1100
|
+
For pickling.
|
|
1101
|
+
|
|
1102
|
+
EXAMPLES::
|
|
1103
|
+
|
|
1104
|
+
sage: Q = QuantumGroup(['A',1])
|
|
1105
|
+
sage: F, K, Ki, E = Q.gens()
|
|
1106
|
+
sage: phi = Q.hom([E, Ki, K, F])
|
|
1107
|
+
sage: loads(dumps(phi)) == phi
|
|
1108
|
+
True
|
|
1109
|
+
"""
|
|
1110
|
+
return (self.parent(), (self._im_gens,))
|
|
1111
|
+
|
|
1112
|
+
def _call_(self, val):
|
|
1113
|
+
r"""
|
|
1114
|
+
Return the image of ``val`` under ``self``.
|
|
1115
|
+
|
|
1116
|
+
EXAMPLES::
|
|
1117
|
+
|
|
1118
|
+
sage: Q = QuantumGroup(['A',1])
|
|
1119
|
+
sage: F, K, Ki, E = Q.gens()
|
|
1120
|
+
sage: phi = Q.hom([E, Ki, K, F])
|
|
1121
|
+
sage: phi(F)
|
|
1122
|
+
E[a1]
|
|
1123
|
+
sage: phi(E*F)
|
|
1124
|
+
F[a1]*E[a1]
|
|
1125
|
+
sage: phi(F*E)
|
|
1126
|
+
F[a1]*E[a1] + [ K1 ; 1 ]
|
|
1127
|
+
sage: phi(E*K)
|
|
1128
|
+
(-q + q^-1)*F[a1]*[ K1 ; 1 ] + F[a1]*K1
|
|
1129
|
+
sage: phi(F*E) == phi(F) * phi(E)
|
|
1130
|
+
True
|
|
1131
|
+
"""
|
|
1132
|
+
try:
|
|
1133
|
+
return self.codomain()(self._libgap.ImageElm(val))
|
|
1134
|
+
except TypeError:
|
|
1135
|
+
return self.codomain()(str(self._libgap.ImageElm(val)))
|
|
1136
|
+
|
|
1137
|
+
def __richcmp__(self, other, op):
|
|
1138
|
+
r"""
|
|
1139
|
+
Rich comparison of ``self`` and ``other`` by ``op``.
|
|
1140
|
+
|
|
1141
|
+
EXAMPLES::
|
|
1142
|
+
|
|
1143
|
+
sage: Q = QuantumGroup(['A',1])
|
|
1144
|
+
sage: F, K, Ki, E = Q.gens()
|
|
1145
|
+
sage: phi = Q.hom([E, Ki, K, F])
|
|
1146
|
+
sage: psi = Q.hom([F, K, Ki, E])
|
|
1147
|
+
sage: phi == Q.hom([E, Ki, K, F])
|
|
1148
|
+
True
|
|
1149
|
+
sage: phi == psi
|
|
1150
|
+
False
|
|
1151
|
+
sage: psi != Q.hom([F, K, Ki, E])
|
|
1152
|
+
False
|
|
1153
|
+
sage: phi != psi
|
|
1154
|
+
True
|
|
1155
|
+
|
|
1156
|
+
sage: QB = QuantumGroup(['B',3])
|
|
1157
|
+
sage: QC = QuantumGroup(['C',3])
|
|
1158
|
+
sage: x = ZZ.one()
|
|
1159
|
+
sage: phi = QB.hom([x]*len(QB.algebra_generators()))
|
|
1160
|
+
sage: psi = QC.hom([x]*len(QC.algebra_generators()))
|
|
1161
|
+
sage: phi.im_gens() == psi.im_gens()
|
|
1162
|
+
True
|
|
1163
|
+
sage: phi == psi
|
|
1164
|
+
False
|
|
1165
|
+
"""
|
|
1166
|
+
if op == op_EQ:
|
|
1167
|
+
return (type(self) is type(other)
|
|
1168
|
+
and self.domain() is other.domain()
|
|
1169
|
+
and self._im_gens == other._im_gens)
|
|
1170
|
+
if op == op_NE:
|
|
1171
|
+
return not (self == other)
|
|
1172
|
+
return NotImplemented
|
|
1173
|
+
|
|
1174
|
+
def im_gens(self):
|
|
1175
|
+
r"""
|
|
1176
|
+
Return the image of the generators under ``self``.
|
|
1177
|
+
|
|
1178
|
+
EXAMPLES::
|
|
1179
|
+
|
|
1180
|
+
sage: Q = QuantumGroup(['A',1])
|
|
1181
|
+
sage: F, K, Ki, E = Q.gens()
|
|
1182
|
+
sage: phi = Q.hom([E, Ki, K, F])
|
|
1183
|
+
sage: phi.im_gens()
|
|
1184
|
+
(E[a1], (-q + q^-1)*[ K1 ; 1 ] + K1, K1, F[a1])
|
|
1185
|
+
"""
|
|
1186
|
+
return self._im_gens
|
|
1187
|
+
|
|
1188
|
+
def _repr_defn(self):
|
|
1189
|
+
r"""
|
|
1190
|
+
Used in constructing the string representation of ``self``.
|
|
1191
|
+
|
|
1192
|
+
EXAMPLES::
|
|
1193
|
+
|
|
1194
|
+
sage: Q = QuantumGroup(['A',1])
|
|
1195
|
+
sage: F, K, Ki, E = Q.gens()
|
|
1196
|
+
sage: phi = Q.hom([E, Ki, K, F])
|
|
1197
|
+
sage: print(phi._repr_defn())
|
|
1198
|
+
F[a1] |--> E[a1]
|
|
1199
|
+
K1 |--> (-q + q^-1)*[ K1 ; 1 ] + K1
|
|
1200
|
+
(-q + q^-1)*[ K1 ; 1 ] + K1 |--> K1
|
|
1201
|
+
E[a1] |--> F[a1]
|
|
1202
|
+
"""
|
|
1203
|
+
return '\n'.join('%s |--> %s' % (gen, self._im_gens[i])
|
|
1204
|
+
for i, gen in enumerate(self.domain().algebra_generators()))
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
class QuantumGroupHomset(HomsetWithBase):
|
|
1208
|
+
r"""
|
|
1209
|
+
The homset whose domain is a quantum group.
|
|
1210
|
+
"""
|
|
1211
|
+
def __call__(self, im_gens, check=True):
|
|
1212
|
+
r"""
|
|
1213
|
+
Construct an element of ``self``.
|
|
1214
|
+
|
|
1215
|
+
EXAMPLES::
|
|
1216
|
+
|
|
1217
|
+
sage: Q = QuantumGroup(['A',1])
|
|
1218
|
+
sage: H = Hom(Q, Q)
|
|
1219
|
+
sage: F, K, Ki, E = Q.gens()
|
|
1220
|
+
sage: phi = H([E, Ki, K, F]); phi
|
|
1221
|
+
Quantum group homomorphism endomorphism of Quantum Group of type ['A', 1] with q=q
|
|
1222
|
+
Defn: F[a1] |--> E[a1]
|
|
1223
|
+
K1 |--> (-q + q^-1)*[ K1 ; 1 ] + K1
|
|
1224
|
+
(-q + q^-1)*[ K1 ; 1 ] + K1 |--> K1
|
|
1225
|
+
E[a1] |--> F[a1]
|
|
1226
|
+
sage: H(phi) == phi
|
|
1227
|
+
True
|
|
1228
|
+
sage: H2 = Hom(Q, Q, Modules(Fields()))
|
|
1229
|
+
sage: H == H2
|
|
1230
|
+
False
|
|
1231
|
+
sage: H2(phi)
|
|
1232
|
+
Quantum group homomorphism endomorphism of Quantum Group of type ['A', 1] with q=q
|
|
1233
|
+
Defn: F[a1] |--> E[a1]
|
|
1234
|
+
K1 |--> (-q + q^-1)*[ K1 ; 1 ] + K1
|
|
1235
|
+
(-q + q^-1)*[ K1 ; 1 ] + K1 |--> K1
|
|
1236
|
+
E[a1] |--> F[a1]
|
|
1237
|
+
"""
|
|
1238
|
+
if isinstance(im_gens, QuantumGroupMorphism):
|
|
1239
|
+
if im_gens.parent() is self:
|
|
1240
|
+
return im_gens
|
|
1241
|
+
if im_gens.parent() != self:
|
|
1242
|
+
return QuantumGroupMorphism(self, im_gens.im_gens())
|
|
1243
|
+
raise TypeError("unable to coerce {}".format(im_gens))
|
|
1244
|
+
return QuantumGroupMorphism(self, im_gens)
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
def projection_lower_half(Q):
|
|
1248
|
+
r"""
|
|
1249
|
+
Return the projection onto the lower half of the quantum group.
|
|
1250
|
+
|
|
1251
|
+
EXAMPLES::
|
|
1252
|
+
|
|
1253
|
+
sage: from sage.algebras.quantum_groups.quantum_group_gap import projection_lower_half
|
|
1254
|
+
sage: Q = QuantumGroup(['G',2])
|
|
1255
|
+
sage: phi = projection_lower_half(Q); phi
|
|
1256
|
+
Quantum group homomorphism endomorphism of Quantum Group of type ['G', 2] with q=q
|
|
1257
|
+
Defn: F[a1] |--> F[a1]
|
|
1258
|
+
F[a2] |--> F[a2]
|
|
1259
|
+
K1 |--> 0
|
|
1260
|
+
K2 |--> 0
|
|
1261
|
+
(-q + q^-1)*[ K1 ; 1 ] + K1 |--> 0
|
|
1262
|
+
(-q^3 + q^-3)*[ K2 ; 1 ] + K2 |--> 0
|
|
1263
|
+
E[a1] |--> 0
|
|
1264
|
+
E[a2] |--> 0
|
|
1265
|
+
sage: all(phi(f) == f for f in Q.F())
|
|
1266
|
+
True
|
|
1267
|
+
sage: all(phi(e) == Q.zero() for e in Q.E())
|
|
1268
|
+
True
|
|
1269
|
+
sage: all(phi(K) == Q.zero() for K in Q.K())
|
|
1270
|
+
True
|
|
1271
|
+
"""
|
|
1272
|
+
I = Q._cartan_type.index_set()
|
|
1273
|
+
return Hom(Q, Q)(list(Q.F_simple()) + [Q.zero()] * (len(I) * 3))
|
|
1274
|
+
|
|
1275
|
+
|
|
1276
|
+
#####################################################################
|
|
1277
|
+
# Representations
|
|
1278
|
+
|
|
1279
|
+
class QuaGroupRepresentationElement(QuaGroupModuleElement):
|
|
1280
|
+
"""
|
|
1281
|
+
Element of a quantum group representation.
|
|
1282
|
+
"""
|
|
1283
|
+
def __reduce__(self):
|
|
1284
|
+
"""
|
|
1285
|
+
Used in pickling.
|
|
1286
|
+
|
|
1287
|
+
EXAMPLES::
|
|
1288
|
+
|
|
1289
|
+
sage: Q = QuantumGroup(['B',2])
|
|
1290
|
+
sage: F1, F2 = Q.F_simple()
|
|
1291
|
+
sage: q = Q.q()
|
|
1292
|
+
sage: V = Q.highest_weight_module([2,1])
|
|
1293
|
+
sage: v = V.highest_weight_vector()
|
|
1294
|
+
sage: x = (2 - q) * v + F1*v + q*F2*F1*v
|
|
1295
|
+
sage: loads(dumps(x)) == x
|
|
1296
|
+
True
|
|
1297
|
+
"""
|
|
1298
|
+
return (self.parent(), (self.monomial_coefficients(),))
|
|
1299
|
+
|
|
1300
|
+
def _acted_upon_(self, scalar, self_on_left=False):
|
|
1301
|
+
r"""
|
|
1302
|
+
Return the action of ``scalar`` on ``self``.
|
|
1303
|
+
|
|
1304
|
+
EXAMPLES::
|
|
1305
|
+
|
|
1306
|
+
sage: Q = QuantumGroup(['B',2])
|
|
1307
|
+
sage: F1, F2 = Q.F_simple()
|
|
1308
|
+
sage: q = Q.q()
|
|
1309
|
+
sage: V = Q.highest_weight_module([2,1])
|
|
1310
|
+
sage: v = V.highest_weight_vector()
|
|
1311
|
+
sage: F1 * v
|
|
1312
|
+
F[a1]*v0
|
|
1313
|
+
sage: F2 * v
|
|
1314
|
+
F[a2]*v0
|
|
1315
|
+
sage: F1^2 * v
|
|
1316
|
+
(q^2 + q^-2)*F[a1]^(2)*v0
|
|
1317
|
+
sage: F2^2 * v
|
|
1318
|
+
0*v0
|
|
1319
|
+
sage: (F1 * F2) * v
|
|
1320
|
+
F[a1]*F[a2]*v0
|
|
1321
|
+
sage: F1 * (F2 * v)
|
|
1322
|
+
F[a1]*F[a2]*v0
|
|
1323
|
+
sage: (2 - q) * v + F1*v + q*F2*F1*v
|
|
1324
|
+
(-q + 2)*1*v0 + F[a1]*v0 + (q^3)*F[a1]*F[a2]*v0 + (q)*F[a1+a2]*v0
|
|
1325
|
+
"""
|
|
1326
|
+
try:
|
|
1327
|
+
if scalar.parent() is self.parent()._Q:
|
|
1328
|
+
if self_on_left: # Only act: scalar * v
|
|
1329
|
+
return None
|
|
1330
|
+
return self.__class__(self.parent(), scalar._libgap ** self._libgap)
|
|
1331
|
+
except AttributeError:
|
|
1332
|
+
pass
|
|
1333
|
+
return QuaGroupModuleElement._acted_upon_(self, scalar, self_on_left)
|
|
1334
|
+
|
|
1335
|
+
_lmul_ = _acted_upon_
|
|
1336
|
+
|
|
1337
|
+
def _et(self, i):
|
|
1338
|
+
r"""
|
|
1339
|
+
Return the action of `\widetilde{e}_i` on ``self``.
|
|
1340
|
+
|
|
1341
|
+
EXAMPLES::
|
|
1342
|
+
|
|
1343
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1344
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1345
|
+
sage: v = V.highest_weight_vector()
|
|
1346
|
+
sage: v._et(1)
|
|
1347
|
+
0*v0
|
|
1348
|
+
sage: V.zero().e_tilde(1)
|
|
1349
|
+
0*v0
|
|
1350
|
+
"""
|
|
1351
|
+
if not self: # self == 0
|
|
1352
|
+
return self
|
|
1353
|
+
V = self.parent()
|
|
1354
|
+
ret = V._libgap.Ealpha(self._libgap, i)
|
|
1355
|
+
return self.__class__(V, ret)
|
|
1356
|
+
|
|
1357
|
+
def _ft(self, i):
|
|
1358
|
+
r"""
|
|
1359
|
+
Return the action of `\widetilde{e}_i` on ``self``.
|
|
1360
|
+
|
|
1361
|
+
EXAMPLES::
|
|
1362
|
+
|
|
1363
|
+
sage: Q = QuantumGroup(['C',2])
|
|
1364
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1365
|
+
sage: v = V.highest_weight_vector()
|
|
1366
|
+
sage: v._ft(1)
|
|
1367
|
+
F[a1]*v0
|
|
1368
|
+
sage: v._ft(2)
|
|
1369
|
+
F[a2]*v0
|
|
1370
|
+
sage: v.f_tilde([1,1])
|
|
1371
|
+
0*v0
|
|
1372
|
+
sage: v.f_tilde([2,2])
|
|
1373
|
+
0*v0
|
|
1374
|
+
sage: v.f_tilde([2,1,1])
|
|
1375
|
+
(-q^-3)*F[a1]*F[a1+a2]*v0 + (-q^-4)*F[2*a1+a2]*v0
|
|
1376
|
+
sage: v.f_tilde([1,2,2])
|
|
1377
|
+
F[a1+a2]*F[a2]*v0
|
|
1378
|
+
sage: V.zero().f_tilde(1)
|
|
1379
|
+
0*v0
|
|
1380
|
+
"""
|
|
1381
|
+
if not self: # self == 0
|
|
1382
|
+
return self
|
|
1383
|
+
V = self.parent()
|
|
1384
|
+
ret = V._libgap.Falpha(self._libgap, i)
|
|
1385
|
+
return self.__class__(V, ret)
|
|
1386
|
+
|
|
1387
|
+
def monomial_coefficients(self, copy=True):
|
|
1388
|
+
r"""
|
|
1389
|
+
Return the dictionary of ``self`` whose keys are the basis indices
|
|
1390
|
+
and the values are coefficients.
|
|
1391
|
+
|
|
1392
|
+
EXAMPLES::
|
|
1393
|
+
|
|
1394
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1395
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1396
|
+
sage: v = V.highest_weight_vector()
|
|
1397
|
+
sage: F1, F2 = Q.F_simple()
|
|
1398
|
+
sage: q = Q.q()
|
|
1399
|
+
sage: x = v + F1*v + q*F2*F1*v; x
|
|
1400
|
+
1*v0 + F[a1]*v0 + (q^2)*F[a1]*F[a2]*v0 + (q)*F[a1+a2]*v0
|
|
1401
|
+
sage: sorted(x.monomial_coefficients().items(), key=str)
|
|
1402
|
+
[(0, 1), (1, 1), (3, q^2), (4, q)]
|
|
1403
|
+
"""
|
|
1404
|
+
R = self.parent()._Q.base_ring()
|
|
1405
|
+
B = self.parent()._libgap.Basis()
|
|
1406
|
+
data = [R(str(c)) for c in libgap.Coefficients(B, self._libgap)]
|
|
1407
|
+
return {i: c for i, c in enumerate(data) if c != 0}
|
|
1408
|
+
|
|
1409
|
+
def _vector_(self, R=None, order=None, sparse=False):
|
|
1410
|
+
"""
|
|
1411
|
+
Return ``self`` as a vector.
|
|
1412
|
+
|
|
1413
|
+
EXAMPLES::
|
|
1414
|
+
|
|
1415
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1416
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1417
|
+
sage: v = V.highest_weight_vector()
|
|
1418
|
+
sage: vector(v)
|
|
1419
|
+
(1, 0, 0, 0, 0, 0, 0, 0)
|
|
1420
|
+
sage: F1, F2 = Q.F_simple()
|
|
1421
|
+
sage: q = Q.q()
|
|
1422
|
+
sage: x = v + F1*v + q*F2*F1*v; x
|
|
1423
|
+
1*v0 + F[a1]*v0 + (q^2)*F[a1]*F[a2]*v0 + (q)*F[a1+a2]*v0
|
|
1424
|
+
sage: vector(x)
|
|
1425
|
+
(1, 1, 0, q^2, q, 0, 0, 0)
|
|
1426
|
+
|
|
1427
|
+
sage: v._vector_(sparse=True)
|
|
1428
|
+
(1, 0, 0, 0, 0, 0, 0, 0)
|
|
1429
|
+
sage: x._vector_(sparse=True)
|
|
1430
|
+
(1, 1, 0, q^2, q, 0, 0, 0)
|
|
1431
|
+
|
|
1432
|
+
sage: M = V.submodule([V.an_element()])
|
|
1433
|
+
sage: M
|
|
1434
|
+
Free module generated by {0} over Fraction Field of Univariate Polynomial Ring in q over Rational Field
|
|
1435
|
+
"""
|
|
1436
|
+
V = self.parent()._dense_free_module(R)
|
|
1437
|
+
if sparse:
|
|
1438
|
+
V = V.sparse_module()
|
|
1439
|
+
if order is None:
|
|
1440
|
+
return V(self.monomial_coefficients())
|
|
1441
|
+
|
|
1442
|
+
v = copy(V.zero())
|
|
1443
|
+
if order is None:
|
|
1444
|
+
for i, c in self.monomial_coefficients().items():
|
|
1445
|
+
v[i] = c
|
|
1446
|
+
else:
|
|
1447
|
+
for i, c in self.monomial_coefficients().items():
|
|
1448
|
+
v[order[i]] = c
|
|
1449
|
+
return v
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
class CrystalGraphVertex(SageObject):
|
|
1453
|
+
r"""
|
|
1454
|
+
Helper class used as the vertices of a crystal graph.
|
|
1455
|
+
"""
|
|
1456
|
+
def __init__(self, V, s):
|
|
1457
|
+
"""
|
|
1458
|
+
Initialize ``self``.
|
|
1459
|
+
|
|
1460
|
+
EXAMPLES::
|
|
1461
|
+
|
|
1462
|
+
sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
|
|
1463
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1464
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1465
|
+
sage: v = CrystalGraphVertex(V, '<F2*v0>')
|
|
1466
|
+
sage: TestSuite(v).run()
|
|
1467
|
+
"""
|
|
1468
|
+
self.V = V
|
|
1469
|
+
self.s = s
|
|
1470
|
+
|
|
1471
|
+
def __hash__(self):
|
|
1472
|
+
"""
|
|
1473
|
+
Return the hash of ``self``.
|
|
1474
|
+
|
|
1475
|
+
EXAMPLES::
|
|
1476
|
+
|
|
1477
|
+
sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
|
|
1478
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1479
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1480
|
+
sage: v = CrystalGraphVertex(V, '<F2*v0>')
|
|
1481
|
+
sage: hash(v) == hash('<F2*v0>')
|
|
1482
|
+
True
|
|
1483
|
+
"""
|
|
1484
|
+
return hash(self.s)
|
|
1485
|
+
|
|
1486
|
+
def __eq__(self, other):
|
|
1487
|
+
"""
|
|
1488
|
+
Check equality of ``self`` and ``other``.
|
|
1489
|
+
|
|
1490
|
+
EXAMPLES::
|
|
1491
|
+
|
|
1492
|
+
sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
|
|
1493
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1494
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1495
|
+
sage: v = CrystalGraphVertex(V, '<F2*v0>')
|
|
1496
|
+
sage: vp = CrystalGraphVertex(V, '<F2*v0>')
|
|
1497
|
+
sage: v == vp
|
|
1498
|
+
True
|
|
1499
|
+
sage: vpp = CrystalGraphVertex(V, '<1*v0>')
|
|
1500
|
+
sage: v == vpp
|
|
1501
|
+
False
|
|
1502
|
+
"""
|
|
1503
|
+
return isinstance(other, CrystalGraphVertex) and self.s == other.s
|
|
1504
|
+
|
|
1505
|
+
def _repr_(self):
|
|
1506
|
+
"""
|
|
1507
|
+
Return a string representation of ``self``.
|
|
1508
|
+
|
|
1509
|
+
EXAMPLES::
|
|
1510
|
+
|
|
1511
|
+
sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
|
|
1512
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1513
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1514
|
+
sage: CrystalGraphVertex(V, '<F2*v0>')
|
|
1515
|
+
<F2*v0>
|
|
1516
|
+
"""
|
|
1517
|
+
return self.s
|
|
1518
|
+
|
|
1519
|
+
def _latex_(self):
|
|
1520
|
+
r"""
|
|
1521
|
+
Return a latex representation of ``self``.
|
|
1522
|
+
|
|
1523
|
+
EXAMPLES::
|
|
1524
|
+
|
|
1525
|
+
sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
|
|
1526
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1527
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1528
|
+
sage: v = CrystalGraphVertex(V, '<F2*v0>')
|
|
1529
|
+
sage: latex(v)
|
|
1530
|
+
\langle F_{\alpha_{1} + \alpha_{2}} v_0 \rangle
|
|
1531
|
+
"""
|
|
1532
|
+
# Essentially same as QuaGroupModuleElement._latex_
|
|
1533
|
+
from sage.misc.latex import latex
|
|
1534
|
+
ret = self.s[1:-1] # Strip leading '<' and trailing '>'
|
|
1535
|
+
for i, al in enumerate(self.V._pos_roots):
|
|
1536
|
+
ret = ret.replace('F%s' % (i + 1), 'F_{%s}' % latex(al))
|
|
1537
|
+
ret = ret.replace('E%s' % (i + 1), 'E_{%s}' % latex(al))
|
|
1538
|
+
for i, ii in enumerate(self.V._cartan_type.index_set()):
|
|
1539
|
+
ret = ret.replace('K%s' % (i + 1), 'K_{%s}' % ii)
|
|
1540
|
+
# Fugly string parsing to get good looking latex
|
|
1541
|
+
# TODO: Find a better way
|
|
1542
|
+
ret = ret.replace('(', '{(')
|
|
1543
|
+
ret = ret.replace(')', ')}')
|
|
1544
|
+
ret = ret.replace('v0', 'v_0')
|
|
1545
|
+
ret = ret.replace('*', ' ')
|
|
1546
|
+
ret = ret.replace('<x>', ' \\otimes ')
|
|
1547
|
+
c = re.compile(r"q\^-?[0-9]*")
|
|
1548
|
+
for m in reversed(list(c.finditer(ret))):
|
|
1549
|
+
ret = ret[:m.start()+2]+'{'+ret[m.start()+2:m.end()]+'}'+ret[m.end():]
|
|
1550
|
+
return '\\langle {} \\rangle'.format(ret)
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
class QuantumGroupModule(Parent, UniqueRepresentation):
|
|
1554
|
+
r"""
|
|
1555
|
+
Abstract base class for quantum group representations.
|
|
1556
|
+
"""
|
|
1557
|
+
def __init__(self, Q, category):
|
|
1558
|
+
r"""
|
|
1559
|
+
Initialize ``self``.
|
|
1560
|
+
|
|
1561
|
+
EXAMPLES::
|
|
1562
|
+
|
|
1563
|
+
sage: Q = QuantumGroup(['G',2])
|
|
1564
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1565
|
+
sage: TestSuite(V).run()
|
|
1566
|
+
"""
|
|
1567
|
+
self._Q = Q
|
|
1568
|
+
self._libgap_q = Q._libgap_q
|
|
1569
|
+
self._libgap_base = Q._libgap_base
|
|
1570
|
+
self._cartan_type = Q._cartan_type
|
|
1571
|
+
self._pos_roots = Q._pos_roots
|
|
1572
|
+
Parent.__init__(self, base=Q.base_ring(), category=category)
|
|
1573
|
+
|
|
1574
|
+
def _latex_(self):
|
|
1575
|
+
r"""
|
|
1576
|
+
Return a latex representation of ``self``.
|
|
1577
|
+
|
|
1578
|
+
EXAMPLES::
|
|
1579
|
+
|
|
1580
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1581
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1582
|
+
sage: T = tensor([V,V])
|
|
1583
|
+
sage: S = T.highest_weight_decomposition()[0]
|
|
1584
|
+
sage: latex(S)
|
|
1585
|
+
\begin{tikzpicture}...
|
|
1586
|
+
...
|
|
1587
|
+
\end{tikzpicture}
|
|
1588
|
+
"""
|
|
1589
|
+
from sage.misc.latex import latex
|
|
1590
|
+
return latex(self.crystal_graph())
|
|
1591
|
+
|
|
1592
|
+
def gap(self):
|
|
1593
|
+
r"""
|
|
1594
|
+
Return the gap representation of ``self``.
|
|
1595
|
+
|
|
1596
|
+
EXAMPLES::
|
|
1597
|
+
|
|
1598
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1599
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1600
|
+
sage: V.gap()
|
|
1601
|
+
<8-dimensional left-module over QuantumUEA( <root system of type A2>,
|
|
1602
|
+
Qpar = q )>
|
|
1603
|
+
"""
|
|
1604
|
+
return self._libgap
|
|
1605
|
+
|
|
1606
|
+
_libgap_ = _gap_ = gap
|
|
1607
|
+
|
|
1608
|
+
def _element_constructor_(self, elt):
|
|
1609
|
+
"""
|
|
1610
|
+
Construct an element of ``self``.
|
|
1611
|
+
|
|
1612
|
+
EXAMPLES::
|
|
1613
|
+
|
|
1614
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1615
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1616
|
+
sage: q = Q.q()
|
|
1617
|
+
sage: V(0)
|
|
1618
|
+
0*v0
|
|
1619
|
+
sage: V({1: q^2 - q^-2, 3: 2})
|
|
1620
|
+
(q^2-q^-2)*F[a1]*v0 + (2)*F[a1]*F[a2]*v0
|
|
1621
|
+
"""
|
|
1622
|
+
if not elt:
|
|
1623
|
+
return self.zero()
|
|
1624
|
+
if isinstance(elt, dict):
|
|
1625
|
+
return self._from_dict(elt)
|
|
1626
|
+
return self.element_class(self, elt)
|
|
1627
|
+
|
|
1628
|
+
@cached_method
|
|
1629
|
+
def basis(self):
|
|
1630
|
+
r"""
|
|
1631
|
+
Return a basis of ``self``.
|
|
1632
|
+
|
|
1633
|
+
EXAMPLES::
|
|
1634
|
+
|
|
1635
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1636
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1637
|
+
sage: V.basis()
|
|
1638
|
+
Family (1*v0, F[a1]*v0, F[a2]*v0, F[a1]*F[a2]*v0, F[a1+a2]*v0,
|
|
1639
|
+
F[a1]*F[a1+a2]*v0, F[a1+a2]*F[a2]*v0, F[a1+a2]^(2)*v0)
|
|
1640
|
+
"""
|
|
1641
|
+
return Family([self.element_class(self, b) for b in self._libgap.Basis()])
|
|
1642
|
+
|
|
1643
|
+
@cached_method
|
|
1644
|
+
def crystal_basis(self):
|
|
1645
|
+
r"""
|
|
1646
|
+
Return the crystal basis of ``self``.
|
|
1647
|
+
|
|
1648
|
+
EXAMPLES::
|
|
1649
|
+
|
|
1650
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1651
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1652
|
+
sage: V.crystal_basis()
|
|
1653
|
+
Family (1*v0, F[a1]*v0, F[a2]*v0, F[a1]*F[a2]*v0,
|
|
1654
|
+
(q)*F[a1]*F[a2]*v0 + F[a1+a2]*v0, F[a1+a2]*F[a2]*v0,
|
|
1655
|
+
(-q^-2)*F[a1]*F[a1+a2]*v0, (-q^-1)*F[a1+a2]^(2)*v0)
|
|
1656
|
+
"""
|
|
1657
|
+
return Family([self.element_class(self, b) for b in self._libgap.CrystalBasis()])
|
|
1658
|
+
|
|
1659
|
+
@cached_method
|
|
1660
|
+
def R_matrix(self):
|
|
1661
|
+
"""
|
|
1662
|
+
Return the `R`-matrix of ``self``.
|
|
1663
|
+
|
|
1664
|
+
EXAMPLES::
|
|
1665
|
+
|
|
1666
|
+
sage: Q = QuantumGroup(['A',1])
|
|
1667
|
+
sage: V = Q.highest_weight_module([1])
|
|
1668
|
+
sage: V.R_matrix()
|
|
1669
|
+
[ 1 0 0 0]
|
|
1670
|
+
[ 0 q -q^2 + 1 0]
|
|
1671
|
+
[ 0 0 q 0]
|
|
1672
|
+
[ 0 0 0 1]
|
|
1673
|
+
"""
|
|
1674
|
+
R = self._libgap.RMatrix()
|
|
1675
|
+
F = self._Q.base_ring()
|
|
1676
|
+
from sage.matrix.constructor import matrix
|
|
1677
|
+
M = matrix(F, [[F(str(elt)) for elt in row] for row in R])
|
|
1678
|
+
M.set_immutable()
|
|
1679
|
+
return M
|
|
1680
|
+
|
|
1681
|
+
def crystal_graph(self):
|
|
1682
|
+
r"""
|
|
1683
|
+
Return the crystal graph of ``self``.
|
|
1684
|
+
|
|
1685
|
+
EXAMPLES::
|
|
1686
|
+
|
|
1687
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1688
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1689
|
+
sage: G = V.crystal_graph(); G
|
|
1690
|
+
Digraph on 8 vertices
|
|
1691
|
+
|
|
1692
|
+
sage: B = crystals.Tableaux(['A',2], shape=[2,1])
|
|
1693
|
+
sage: G.is_isomorphic(B.digraph(), edge_labels=True)
|
|
1694
|
+
True
|
|
1695
|
+
"""
|
|
1696
|
+
G = self._libgap.CrystalGraph()
|
|
1697
|
+
vertices = [CrystalGraphVertex(self, repr(p)) for p in G['points']]
|
|
1698
|
+
edges = [[vertices[e[0][0]-1], vertices[e[0][1]-1], e[1]]
|
|
1699
|
+
for e in G['edges'].sage()]
|
|
1700
|
+
G = DiGraph([vertices, edges], format='vertices_and_edges')
|
|
1701
|
+
from sage.graphs.dot2tex_utils import have_dot2tex
|
|
1702
|
+
if have_dot2tex():
|
|
1703
|
+
G.set_latex_options(format='dot2tex',
|
|
1704
|
+
edge_labels=True,
|
|
1705
|
+
color_by_label=self._cartan_type._index_set_coloring)
|
|
1706
|
+
return G
|
|
1707
|
+
|
|
1708
|
+
@cached_method
|
|
1709
|
+
def zero(self):
|
|
1710
|
+
r"""
|
|
1711
|
+
Return the zero element of ``self``.
|
|
1712
|
+
|
|
1713
|
+
EXAMPLES::
|
|
1714
|
+
|
|
1715
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1716
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1717
|
+
sage: V.zero()
|
|
1718
|
+
0*v0
|
|
1719
|
+
"""
|
|
1720
|
+
return self.element_class(self, self._libgap.ZeroImmutable())
|
|
1721
|
+
|
|
1722
|
+
|
|
1723
|
+
class HighestWeightModule(QuantumGroupModule):
|
|
1724
|
+
"""
|
|
1725
|
+
A highest weight module of a quantum group.
|
|
1726
|
+
"""
|
|
1727
|
+
@staticmethod
|
|
1728
|
+
def __classcall_private__(cls, Q, weight):
|
|
1729
|
+
"""
|
|
1730
|
+
Normalize input to ensure a unique representation.
|
|
1731
|
+
|
|
1732
|
+
EXAMPLES::
|
|
1733
|
+
|
|
1734
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1735
|
+
sage: La = Q.cartan_type().root_system().weight_lattice().fundamental_weights()
|
|
1736
|
+
sage: V = Q.highest_weight_module([1,3])
|
|
1737
|
+
sage: V is Q.highest_weight_module(La[1]+3*La[2])
|
|
1738
|
+
True
|
|
1739
|
+
"""
|
|
1740
|
+
P = Q._cartan_type.root_system().weight_lattice()
|
|
1741
|
+
if isinstance(weight, (list, tuple)):
|
|
1742
|
+
La = P.fundamental_weights()
|
|
1743
|
+
weight = P.sum(la * weight[i] for i, la in enumerate(La))
|
|
1744
|
+
else:
|
|
1745
|
+
weight = P(weight)
|
|
1746
|
+
return super().__classcall__(cls, Q, weight)
|
|
1747
|
+
|
|
1748
|
+
def __init__(self, Q, weight):
|
|
1749
|
+
"""
|
|
1750
|
+
Initialize ``self``.
|
|
1751
|
+
|
|
1752
|
+
EXAMPLES::
|
|
1753
|
+
|
|
1754
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1755
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1756
|
+
sage: TestSuite(V).run()
|
|
1757
|
+
"""
|
|
1758
|
+
self._libgap = Q._libgap.HighestWeightModule(list(weight.to_vector()))
|
|
1759
|
+
self._weight = weight
|
|
1760
|
+
cat = Modules(Q.base_ring()).FiniteDimensional().WithBasis()
|
|
1761
|
+
QuantumGroupModule.__init__(self, Q, cat)
|
|
1762
|
+
|
|
1763
|
+
def _repr_(self):
|
|
1764
|
+
"""
|
|
1765
|
+
Return a string representation of ``self``.
|
|
1766
|
+
|
|
1767
|
+
EXAMPLES::
|
|
1768
|
+
|
|
1769
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1770
|
+
sage: Q.highest_weight_module([1,1])
|
|
1771
|
+
Highest weight module of weight Lambda[1] + Lambda[2] of
|
|
1772
|
+
Quantum Group of type ['A', 2] with q=q
|
|
1773
|
+
"""
|
|
1774
|
+
return "Highest weight module of weight {} of {}".format(self._weight, self._Q)
|
|
1775
|
+
|
|
1776
|
+
def _latex_(self):
|
|
1777
|
+
r"""
|
|
1778
|
+
Return a latex representation of ``self``.
|
|
1779
|
+
|
|
1780
|
+
EXAMPLES::
|
|
1781
|
+
|
|
1782
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1783
|
+
sage: V = Q.highest_weight_module([1,2])
|
|
1784
|
+
sage: latex(V)
|
|
1785
|
+
V(\Lambda_{1} + 2 \Lambda_{2})
|
|
1786
|
+
"""
|
|
1787
|
+
from sage.misc.latex import latex
|
|
1788
|
+
return "V({})".format(latex(self._weight))
|
|
1789
|
+
|
|
1790
|
+
@cached_method
|
|
1791
|
+
def highest_weight_vector(self):
|
|
1792
|
+
"""
|
|
1793
|
+
Return the highest weight vector of ``self``.
|
|
1794
|
+
|
|
1795
|
+
EXAMPLES::
|
|
1796
|
+
|
|
1797
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1798
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1799
|
+
sage: V.highest_weight_vector()
|
|
1800
|
+
1*v0
|
|
1801
|
+
"""
|
|
1802
|
+
return self.element_class(self, self._libgap.HighestWeightsAndVectors()[1][0][0])
|
|
1803
|
+
|
|
1804
|
+
an_element = highest_weight_vector
|
|
1805
|
+
|
|
1806
|
+
def tensor(self, *V, **options):
|
|
1807
|
+
"""
|
|
1808
|
+
Return the tensor product of ``self`` with ``V``.
|
|
1809
|
+
|
|
1810
|
+
EXAMPLES::
|
|
1811
|
+
|
|
1812
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1813
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1814
|
+
sage: Vp = Q.highest_weight_module([1,0])
|
|
1815
|
+
sage: Vp.tensor(V)
|
|
1816
|
+
Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q
|
|
1817
|
+
# Highest weight module of weight Lambda[1] + Lambda[2] of Quantum Group of type ['A', 2] with q=q
|
|
1818
|
+
"""
|
|
1819
|
+
return TensorProductOfHighestWeightModules(self, *V, **options)
|
|
1820
|
+
|
|
1821
|
+
Element = QuaGroupRepresentationElement
|
|
1822
|
+
|
|
1823
|
+
|
|
1824
|
+
class TensorProductOfHighestWeightModules(QuantumGroupModule):
|
|
1825
|
+
def __init__(self, *modules, **options):
|
|
1826
|
+
"""
|
|
1827
|
+
Initialize ``self``.
|
|
1828
|
+
|
|
1829
|
+
EXAMPLES::
|
|
1830
|
+
|
|
1831
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1832
|
+
sage: V = Q.highest_weight_module([1,1])
|
|
1833
|
+
sage: T = tensor([V,V])
|
|
1834
|
+
sage: TestSuite(T).run()
|
|
1835
|
+
"""
|
|
1836
|
+
Q = modules[0]._Q
|
|
1837
|
+
self._modules = tuple(modules)
|
|
1838
|
+
self._libgap = libgap.TensorProductOfAlgebraModules([m._libgap for m in modules])
|
|
1839
|
+
cat = Modules(Q.base_ring()).TensorProducts().FiniteDimensional().WithBasis()
|
|
1840
|
+
QuantumGroupModule.__init__(self, Q, category=cat)
|
|
1841
|
+
|
|
1842
|
+
def _repr_(self):
|
|
1843
|
+
"""
|
|
1844
|
+
Return a string representation of ``self``.
|
|
1845
|
+
|
|
1846
|
+
EXAMPLES::
|
|
1847
|
+
|
|
1848
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1849
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1850
|
+
sage: T = tensor([V,V])
|
|
1851
|
+
sage: T
|
|
1852
|
+
Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q
|
|
1853
|
+
# Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q
|
|
1854
|
+
"""
|
|
1855
|
+
return " # ".join(repr(M) for M in self._modules)
|
|
1856
|
+
|
|
1857
|
+
def _latex_(self):
|
|
1858
|
+
r"""
|
|
1859
|
+
Return a string representation of ``self``.
|
|
1860
|
+
|
|
1861
|
+
EXAMPLES::
|
|
1862
|
+
|
|
1863
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1864
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1865
|
+
sage: T = tensor([V,V])
|
|
1866
|
+
sage: latex(T)
|
|
1867
|
+
V(\Lambda_{1}) \otimes V(\Lambda_{1})
|
|
1868
|
+
"""
|
|
1869
|
+
from sage.misc.latex import latex
|
|
1870
|
+
return " \\otimes ".join(latex(M) for M in self._modules)
|
|
1871
|
+
|
|
1872
|
+
@lazy_attribute
|
|
1873
|
+
def _highest_weights_and_vectors(self):
|
|
1874
|
+
"""
|
|
1875
|
+
Return the highest weights and the corresponding vectors.
|
|
1876
|
+
|
|
1877
|
+
.. NOTE::
|
|
1878
|
+
|
|
1879
|
+
The resulting objects are GAP objects.
|
|
1880
|
+
|
|
1881
|
+
EXAMPLES::
|
|
1882
|
+
|
|
1883
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1884
|
+
sage: V = Q.highest_weight_module([0,1])
|
|
1885
|
+
sage: T = tensor([V,V])
|
|
1886
|
+
sage: T._highest_weights_and_vectors
|
|
1887
|
+
[ [ [ 0, 2 ], [ 1, 0 ] ],
|
|
1888
|
+
[ [ 1*(1*v0<x>1*v0) ], [ -q^-1*(1*v0<x>F3*v0)+1*(F3*v0<x>1*v0) ] ] ]
|
|
1889
|
+
"""
|
|
1890
|
+
return self._libgap.HighestWeightsAndVectors()
|
|
1891
|
+
|
|
1892
|
+
def highest_weight_vectors(self):
|
|
1893
|
+
r"""
|
|
1894
|
+
Return the highest weight vectors of ``self``.
|
|
1895
|
+
|
|
1896
|
+
EXAMPLES::
|
|
1897
|
+
|
|
1898
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1899
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1900
|
+
sage: T = tensor([V,V])
|
|
1901
|
+
sage: T.highest_weight_vectors()
|
|
1902
|
+
[1*(1*v0<x>1*v0), -q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)]
|
|
1903
|
+
"""
|
|
1904
|
+
return [self.element_class(self, v)
|
|
1905
|
+
for vecs in self._highest_weights_and_vectors[1]
|
|
1906
|
+
for v in vecs]
|
|
1907
|
+
|
|
1908
|
+
some_elements = highest_weight_vectors
|
|
1909
|
+
|
|
1910
|
+
def _an_element_(self):
|
|
1911
|
+
"""
|
|
1912
|
+
Return an element of ``self``.
|
|
1913
|
+
|
|
1914
|
+
EXAMPLES::
|
|
1915
|
+
|
|
1916
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1917
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1918
|
+
sage: T = tensor([V,V])
|
|
1919
|
+
sage: T.an_element()
|
|
1920
|
+
1*(1*v0<x>1*v0)
|
|
1921
|
+
"""
|
|
1922
|
+
return self.highest_weight_vectors()[0]
|
|
1923
|
+
|
|
1924
|
+
@cached_method
|
|
1925
|
+
def highest_weight_decomposition(self):
|
|
1926
|
+
"""
|
|
1927
|
+
Return the highest weight decomposition of ``self``.
|
|
1928
|
+
|
|
1929
|
+
EXAMPLES::
|
|
1930
|
+
|
|
1931
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1932
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1933
|
+
sage: T = tensor([V,V])
|
|
1934
|
+
sage: T.highest_weight_decomposition()
|
|
1935
|
+
[Highest weight submodule with weight 2*Lambda[1] generated by 1*(1*v0<x>1*v0),
|
|
1936
|
+
Highest weight submodule with weight Lambda[2] generated by -q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)]
|
|
1937
|
+
"""
|
|
1938
|
+
return [HighestWeightSubmodule(self, self.element_class(self, v), tuple(wt.sage()))
|
|
1939
|
+
for wt, vecs in zip(*self._highest_weights_and_vectors)
|
|
1940
|
+
for v in vecs]
|
|
1941
|
+
|
|
1942
|
+
def tensor_factors(self):
|
|
1943
|
+
r"""
|
|
1944
|
+
Return the factors of ``self``.
|
|
1945
|
+
|
|
1946
|
+
EXAMPLES::
|
|
1947
|
+
|
|
1948
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1949
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1950
|
+
sage: T = tensor([V,V])
|
|
1951
|
+
sage: T.tensor_factors()
|
|
1952
|
+
(Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q,
|
|
1953
|
+
Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q)
|
|
1954
|
+
"""
|
|
1955
|
+
return self._modules
|
|
1956
|
+
|
|
1957
|
+
Element = QuaGroupRepresentationElement
|
|
1958
|
+
|
|
1959
|
+
|
|
1960
|
+
class HighestWeightSubmodule(QuantumGroupModule):
|
|
1961
|
+
def __init__(self, ambient, gen, weight):
|
|
1962
|
+
"""
|
|
1963
|
+
Initialize ``self``.
|
|
1964
|
+
|
|
1965
|
+
EXAMPLES::
|
|
1966
|
+
|
|
1967
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1968
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1969
|
+
sage: T = tensor([V,V])
|
|
1970
|
+
sage: S = T.highest_weight_decomposition()[0]
|
|
1971
|
+
sage: TestSuite(S).run()
|
|
1972
|
+
"""
|
|
1973
|
+
self._ambient = ambient
|
|
1974
|
+
# We do not use the generic ambient category since submodules of tensor
|
|
1975
|
+
# products are considered to be tensor products.
|
|
1976
|
+
# This should be reverted after this has changed.
|
|
1977
|
+
#cat = ambient.category()
|
|
1978
|
+
cat = Modules(ambient.base_ring()).FiniteDimensional().WithBasis()
|
|
1979
|
+
QuantumGroupModule.__init__(self, ambient._Q, cat.Subobjects())
|
|
1980
|
+
|
|
1981
|
+
self._gen = gen
|
|
1982
|
+
|
|
1983
|
+
self._libgap = self._ambient._libgap.HWModuleByGenerator(gen, weight)
|
|
1984
|
+
|
|
1985
|
+
# Convert the weight to an element of the weight lattice
|
|
1986
|
+
P = self._Q._cartan_type.root_system().weight_lattice()
|
|
1987
|
+
La = P.fundamental_weights()
|
|
1988
|
+
self._weight = P.sum(la * weight[i] for i, la in enumerate(La))
|
|
1989
|
+
|
|
1990
|
+
def _repr_(self):
|
|
1991
|
+
"""
|
|
1992
|
+
Return a string representation of ``self``.
|
|
1993
|
+
|
|
1994
|
+
EXAMPLES::
|
|
1995
|
+
|
|
1996
|
+
sage: Q = QuantumGroup(['A',2])
|
|
1997
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
1998
|
+
sage: T = tensor([V,V])
|
|
1999
|
+
sage: T.highest_weight_decomposition()
|
|
2000
|
+
[Highest weight submodule with weight 2*Lambda[1]
|
|
2001
|
+
generated by 1*(1*v0<x>1*v0),
|
|
2002
|
+
Highest weight submodule with weight Lambda[2]
|
|
2003
|
+
generated by -q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)]
|
|
2004
|
+
"""
|
|
2005
|
+
return "Highest weight submodule with weight {} generated by {}".format(self._weight, self._gen)
|
|
2006
|
+
|
|
2007
|
+
@lazy_attribute
|
|
2008
|
+
def _ambient_basis_map(self):
|
|
2009
|
+
"""
|
|
2010
|
+
A dict that maps the basis of ``self`` to the ambient module.
|
|
2011
|
+
|
|
2012
|
+
EXAMPLES::
|
|
2013
|
+
|
|
2014
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2015
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
2016
|
+
sage: T = tensor([V,V])
|
|
2017
|
+
sage: S = T.highest_weight_decomposition()[0]
|
|
2018
|
+
sage: S._ambient_basis_map
|
|
2019
|
+
{0: 1*(1*v0<x>1*v0),
|
|
2020
|
+
1: 1*(1*v0<x>F[a1]*v0) + q^-1*(F[a1]*v0<x>1*v0),
|
|
2021
|
+
2: 1*(F[a1]*v0<x>F[a1]*v0),
|
|
2022
|
+
3: 1*(1*v0<x>F[a1+a2]*v0) + q^-1*(F[a1+a2]*v0<x>1*v0),
|
|
2023
|
+
4: 1*(F[a1]*v0<x>F[a1+a2]*v0) + q^-1*(F[a1+a2]*v0<x>F[a1]*v0),
|
|
2024
|
+
5: 1*(F[a1+a2]*v0<x>F[a1+a2]*v0)}
|
|
2025
|
+
"""
|
|
2026
|
+
B = list(self.basis())
|
|
2027
|
+
d = {self.highest_weight_vector(): self._gen}
|
|
2028
|
+
todo = {self.highest_weight_vector()}
|
|
2029
|
+
I = self._cartan_type.index_set()
|
|
2030
|
+
while todo:
|
|
2031
|
+
x = todo.pop()
|
|
2032
|
+
for i in I:
|
|
2033
|
+
y = x.f_tilde(i)
|
|
2034
|
+
if y and y not in d:
|
|
2035
|
+
d[y] = d[x].f_tilde(i)
|
|
2036
|
+
todo.add(y)
|
|
2037
|
+
return {B.index(k): d[k] for k in d}
|
|
2038
|
+
|
|
2039
|
+
def ambient(self):
|
|
2040
|
+
"""
|
|
2041
|
+
Return the ambient module of ``self``.
|
|
2042
|
+
|
|
2043
|
+
EXAMPLES::
|
|
2044
|
+
|
|
2045
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2046
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
2047
|
+
sage: T = tensor([V,V])
|
|
2048
|
+
sage: S = T.highest_weight_decomposition()[0]
|
|
2049
|
+
sage: S.ambient() is T
|
|
2050
|
+
True
|
|
2051
|
+
"""
|
|
2052
|
+
return self._ambient
|
|
2053
|
+
|
|
2054
|
+
@lazy_attribute
|
|
2055
|
+
def lift(self):
|
|
2056
|
+
"""
|
|
2057
|
+
The lift morphism from ``self`` to the ambient space.
|
|
2058
|
+
|
|
2059
|
+
EXAMPLES::
|
|
2060
|
+
|
|
2061
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2062
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
2063
|
+
sage: T = tensor([V,V])
|
|
2064
|
+
sage: S = T.highest_weight_decomposition()[0]
|
|
2065
|
+
sage: S.lift
|
|
2066
|
+
Generic morphism:
|
|
2067
|
+
From: Highest weight submodule with weight 2*Lambda[1] generated by 1*(1*v0<x>1*v0)
|
|
2068
|
+
To: Highest weight module ... # Highest weight module ...
|
|
2069
|
+
sage: x = sum(S.basis())
|
|
2070
|
+
sage: x.lift()
|
|
2071
|
+
1*(1*v0<x>1*v0) + 1*(1*v0<x>F[a1]*v0) + 1*(1*v0<x>F[a1+a2]*v0)
|
|
2072
|
+
+ q^-1*(F[a1]*v0<x>1*v0) + 1*(F[a1]*v0<x>F[a1]*v0)
|
|
2073
|
+
+ 1*(F[a1]*v0<x>F[a1+a2]*v0) + q^-1*(F[a1+a2]*v0<x>1*v0)
|
|
2074
|
+
+ q^-1*(F[a1+a2]*v0<x>F[a1]*v0) + 1*(F[a1+a2]*v0<x>F[a1+a2]*v0)
|
|
2075
|
+
"""
|
|
2076
|
+
return self.module_morphism(self._ambient_basis_map.__getitem__,
|
|
2077
|
+
codomain=self._ambient, unitriangular='lower')
|
|
2078
|
+
|
|
2079
|
+
def retract(self, elt):
|
|
2080
|
+
"""
|
|
2081
|
+
The retract map from the ambient space to ``self``.
|
|
2082
|
+
|
|
2083
|
+
EXAMPLES::
|
|
2084
|
+
|
|
2085
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2086
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
2087
|
+
sage: T = tensor([V,V])
|
|
2088
|
+
sage: all(S.retract(S.lift(x)) == x
|
|
2089
|
+
....: for S in T.highest_weight_decomposition()
|
|
2090
|
+
....: for x in S.basis())
|
|
2091
|
+
True
|
|
2092
|
+
"""
|
|
2093
|
+
c = self.lift.matrix().solve_right(elt._vector_())
|
|
2094
|
+
return self._from_dict(c.dict(), coerce=False, remove_zeros=False)
|
|
2095
|
+
|
|
2096
|
+
def highest_weight_vector(self):
|
|
2097
|
+
"""
|
|
2098
|
+
Return the highest weight vector of ``self``.
|
|
2099
|
+
|
|
2100
|
+
EXAMPLES::
|
|
2101
|
+
|
|
2102
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2103
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
2104
|
+
sage: T = tensor([V,V])
|
|
2105
|
+
sage: S = T.highest_weight_decomposition()[1]
|
|
2106
|
+
sage: u = S.highest_weight_vector(); u
|
|
2107
|
+
(1)*e.1
|
|
2108
|
+
sage: u.lift()
|
|
2109
|
+
-q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)
|
|
2110
|
+
"""
|
|
2111
|
+
I = self._cartan_type.index_set()
|
|
2112
|
+
zero = self._libgap.ZeroImmutable()
|
|
2113
|
+
for v in self.basis():
|
|
2114
|
+
if all(self._libgap.Ealpha(v._libgap, i) == zero for i in I):
|
|
2115
|
+
return v
|
|
2116
|
+
return self.zero()
|
|
2117
|
+
|
|
2118
|
+
an_element = highest_weight_vector
|
|
2119
|
+
|
|
2120
|
+
def crystal_graph(self, use_ambient=True):
|
|
2121
|
+
"""
|
|
2122
|
+
Return the crystal graph of ``self``.
|
|
2123
|
+
|
|
2124
|
+
INPUT:
|
|
2125
|
+
|
|
2126
|
+
- ``use_ambient`` -- boolean (default: ``True``); if ``True``,
|
|
2127
|
+
the vertices are given in terms of the ambient module
|
|
2128
|
+
|
|
2129
|
+
EXAMPLES::
|
|
2130
|
+
|
|
2131
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2132
|
+
sage: V = Q.highest_weight_module([1,0])
|
|
2133
|
+
sage: T = tensor([V,V])
|
|
2134
|
+
sage: S = T.highest_weight_decomposition()[1]
|
|
2135
|
+
sage: G = S.crystal_graph()
|
|
2136
|
+
sage: sorted(G.vertices(sort=False), key=str)
|
|
2137
|
+
[<-q^-1*(1*v0<x>F[a1+a2]*v0) + 1*(F[a1+a2]*v0<x>1*v0)>,
|
|
2138
|
+
<-q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)>,
|
|
2139
|
+
<-q^-1*(F[a1]*v0<x>F[a1+a2]*v0) + 1*(F[a1+a2]*v0<x>F[a1]*v0)>]
|
|
2140
|
+
sage: sorted(S.crystal_graph(False).vertices(sort=False), key=str)
|
|
2141
|
+
[<(1)*e.1>, <(1)*e.2>, <(1)*e.3>]
|
|
2142
|
+
"""
|
|
2143
|
+
G = self._libgap.CrystalGraph()
|
|
2144
|
+
if not use_ambient:
|
|
2145
|
+
return QuantumGroupModule.crystal_graph(self)
|
|
2146
|
+
# Mostly a copy; there is likely a better way with a helper function
|
|
2147
|
+
B = self.basis()
|
|
2148
|
+
d = {repr(B[k]._libgap): '<{!r}>'.format(self._ambient_basis_map[k])
|
|
2149
|
+
for k in self._ambient_basis_map}
|
|
2150
|
+
vertices = [CrystalGraphVertex(self, d[repr(p)[1:-1]])
|
|
2151
|
+
for p in G['points']]
|
|
2152
|
+
edges = [[vertices[e[0][0]-1], vertices[e[0][1]-1], e[1]]
|
|
2153
|
+
for e in G['edges'].sage()]
|
|
2154
|
+
G = DiGraph([vertices, edges], format='vertices_and_edges')
|
|
2155
|
+
from sage.graphs.dot2tex_utils import have_dot2tex
|
|
2156
|
+
if have_dot2tex():
|
|
2157
|
+
G.set_latex_options(format='dot2tex',
|
|
2158
|
+
edge_labels=True,
|
|
2159
|
+
color_by_label=self._cartan_type._index_set_coloring)
|
|
2160
|
+
return G
|
|
2161
|
+
|
|
2162
|
+
Element = QuaGroupRepresentationElement
|
|
2163
|
+
|
|
2164
|
+
|
|
2165
|
+
# TODO: Generalized this to Verma modules
|
|
2166
|
+
class LowerHalfQuantumGroup(Parent, UniqueRepresentation):
|
|
2167
|
+
"""
|
|
2168
|
+
The lower half of the quantum group.
|
|
2169
|
+
"""
|
|
2170
|
+
@staticmethod
|
|
2171
|
+
def __classcall_private__(cls, Q):
|
|
2172
|
+
"""
|
|
2173
|
+
Initialize ``self``.
|
|
2174
|
+
|
|
2175
|
+
EXAMPLES::
|
|
2176
|
+
|
|
2177
|
+
sage: from sage.algebras.quantum_groups.quantum_group_gap import LowerHalfQuantumGroup
|
|
2178
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2179
|
+
sage: Q.lower_half() is LowerHalfQuantumGroup(Q)
|
|
2180
|
+
True
|
|
2181
|
+
"""
|
|
2182
|
+
from sage.combinat.root_system.cartan_type import CartanType_abstract
|
|
2183
|
+
if isinstance(Q, CartanType_abstract):
|
|
2184
|
+
Q = QuantumGroup(Q)
|
|
2185
|
+
return super().__classcall__(cls, Q)
|
|
2186
|
+
|
|
2187
|
+
def __init__(self, Q):
|
|
2188
|
+
"""
|
|
2189
|
+
Initialize ``self``.
|
|
2190
|
+
|
|
2191
|
+
EXAMPLES::
|
|
2192
|
+
|
|
2193
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2194
|
+
sage: B = Q.lower_half()
|
|
2195
|
+
sage: TestSuite(B).run()
|
|
2196
|
+
"""
|
|
2197
|
+
self._Q = Q
|
|
2198
|
+
self._libgap = Q._libgap
|
|
2199
|
+
self._libgap_q = Q._libgap_q
|
|
2200
|
+
self._libgap_base = Q._libgap_base
|
|
2201
|
+
self._cartan_type = Q._cartan_type
|
|
2202
|
+
self._pos_roots = Q._pos_roots
|
|
2203
|
+
self._proj = projection_lower_half(Q)
|
|
2204
|
+
B = Q.base_ring()
|
|
2205
|
+
Parent.__init__(self, base=B, category=Algebras(B).WithBasis().Subobjects())
|
|
2206
|
+
|
|
2207
|
+
def _repr_(self):
|
|
2208
|
+
r"""
|
|
2209
|
+
Return a string representation of ``self``.
|
|
2210
|
+
|
|
2211
|
+
EXAMPLES::
|
|
2212
|
+
|
|
2213
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2214
|
+
sage: Q.lower_half()
|
|
2215
|
+
Lower Half of Quantum Group of type ['A', 2] with q=q
|
|
2216
|
+
"""
|
|
2217
|
+
return "Lower Half of {}".format(self._Q)
|
|
2218
|
+
|
|
2219
|
+
def _latex_(self):
|
|
2220
|
+
r"""
|
|
2221
|
+
Return a latex representation of ``self``.
|
|
2222
|
+
|
|
2223
|
+
EXAMPLES::
|
|
2224
|
+
|
|
2225
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2226
|
+
sage: latex(Q.lower_half())
|
|
2227
|
+
U^-_{q}(A_{2})
|
|
2228
|
+
"""
|
|
2229
|
+
from sage.misc.latex import latex
|
|
2230
|
+
return "U^-_{%s}(%s)" % (latex(self._Q._q), latex(self._cartan_type))
|
|
2231
|
+
|
|
2232
|
+
def _element_constructor_(self, elt):
|
|
2233
|
+
r"""
|
|
2234
|
+
Construct an element of ``self``.
|
|
2235
|
+
|
|
2236
|
+
EXAMPLES::
|
|
2237
|
+
|
|
2238
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2239
|
+
sage: B = Q.lower_half()
|
|
2240
|
+
sage: q = Q.q()
|
|
2241
|
+
sage: B(0)
|
|
2242
|
+
0
|
|
2243
|
+
sage: B(1 + q^2)
|
|
2244
|
+
(q^2 + 1)*1
|
|
2245
|
+
sage: B({(1,2,0): q, (0,0,2): q^2 - 2})
|
|
2246
|
+
(q)*F[a1]*F[a1+a2]^(2) + (q^2-2)*F[a2]^(2)
|
|
2247
|
+
"""
|
|
2248
|
+
if not elt:
|
|
2249
|
+
return self.zero()
|
|
2250
|
+
if isinstance(elt, dict):
|
|
2251
|
+
return self._from_dict(elt)
|
|
2252
|
+
if elt in self.base_ring():
|
|
2253
|
+
return elt * self.one()
|
|
2254
|
+
if elt.parent() is self._Q:
|
|
2255
|
+
return self.element_class(self, self._proj(elt)._libgap)
|
|
2256
|
+
return self.element_class(self, elt)
|
|
2257
|
+
|
|
2258
|
+
def ambient(self):
|
|
2259
|
+
r"""
|
|
2260
|
+
Return the ambient quantum group of ``self``.
|
|
2261
|
+
|
|
2262
|
+
EXAMPLES::
|
|
2263
|
+
|
|
2264
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2265
|
+
sage: B = Q.lower_half()
|
|
2266
|
+
sage: B.ambient() is Q
|
|
2267
|
+
True
|
|
2268
|
+
"""
|
|
2269
|
+
return self._Q
|
|
2270
|
+
|
|
2271
|
+
@cached_method
|
|
2272
|
+
def highest_weight_vector(self):
|
|
2273
|
+
"""
|
|
2274
|
+
Return the highest weight vector of ``self``.
|
|
2275
|
+
|
|
2276
|
+
EXAMPLES::
|
|
2277
|
+
|
|
2278
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2279
|
+
sage: B = Q.lower_half()
|
|
2280
|
+
sage: B.highest_weight_vector()
|
|
2281
|
+
1
|
|
2282
|
+
"""
|
|
2283
|
+
return self.element_class(self, self._Q.one()._libgap)
|
|
2284
|
+
|
|
2285
|
+
one = highest_weight_vector
|
|
2286
|
+
an_element = highest_weight_vector
|
|
2287
|
+
|
|
2288
|
+
@cached_method
|
|
2289
|
+
def zero(self):
|
|
2290
|
+
"""
|
|
2291
|
+
Return the zero element of ``self``.
|
|
2292
|
+
|
|
2293
|
+
EXAMPLES::
|
|
2294
|
+
|
|
2295
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2296
|
+
sage: B = Q.lower_half()
|
|
2297
|
+
sage: B.zero()
|
|
2298
|
+
0
|
|
2299
|
+
"""
|
|
2300
|
+
return self.element_class(self, self._Q._libgap.ZeroImmutable())
|
|
2301
|
+
|
|
2302
|
+
@cached_method
|
|
2303
|
+
def algebra_generators(self):
|
|
2304
|
+
r"""
|
|
2305
|
+
Return the algebra generators of ``self``.
|
|
2306
|
+
|
|
2307
|
+
EXAMPLES::
|
|
2308
|
+
|
|
2309
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2310
|
+
sage: B = Q.lower_half()
|
|
2311
|
+
sage: B.algebra_generators()
|
|
2312
|
+
Finite family {1: F[a1], 2: F[a2]}
|
|
2313
|
+
"""
|
|
2314
|
+
F = self._Q.F_simple()
|
|
2315
|
+
keys = F.keys()
|
|
2316
|
+
d = {i: self.element_class(self, F[i]._libgap) for i in keys}
|
|
2317
|
+
return Family(keys, d.__getitem__)
|
|
2318
|
+
|
|
2319
|
+
gens = algebra_generators
|
|
2320
|
+
|
|
2321
|
+
def _construct_monomial(self, k):
|
|
2322
|
+
"""
|
|
2323
|
+
Construct a monomial of ``self`` indexed by ``k``.
|
|
2324
|
+
|
|
2325
|
+
EXAMPLES::
|
|
2326
|
+
|
|
2327
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2328
|
+
sage: B = Q.lower_half()
|
|
2329
|
+
sage: B._construct_monomial((1,2,1))
|
|
2330
|
+
F[a1]*F[a1+a2]^(2)*F[a2]
|
|
2331
|
+
sage: B._construct_monomial((3,0,1))
|
|
2332
|
+
F[a1]^(3)*F[a2]
|
|
2333
|
+
"""
|
|
2334
|
+
F = self._libgap.FamilyObj().ElementsFamily()
|
|
2335
|
+
one = self._libgap_base.One()
|
|
2336
|
+
data = []
|
|
2337
|
+
for i, val in enumerate(k):
|
|
2338
|
+
if val == 0:
|
|
2339
|
+
continue
|
|
2340
|
+
data.append(i + 1)
|
|
2341
|
+
data.append(val)
|
|
2342
|
+
return self.element_class(self, F.ObjByExtRep([data, one]))
|
|
2343
|
+
|
|
2344
|
+
@cached_method
|
|
2345
|
+
def basis(self):
|
|
2346
|
+
r"""
|
|
2347
|
+
Return the basis of ``self``.
|
|
2348
|
+
|
|
2349
|
+
This returns the PBW basis of ``self``, which is given by
|
|
2350
|
+
monomials in `\{F_{\alpha}\}`, where `\alpha` runs over all
|
|
2351
|
+
positive roots.
|
|
2352
|
+
|
|
2353
|
+
EXAMPLES::
|
|
2354
|
+
|
|
2355
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2356
|
+
sage: B = Q.lower_half()
|
|
2357
|
+
sage: basis = B.basis(); basis
|
|
2358
|
+
Lazy family (monomial(i))_{i in The Cartesian product of
|
|
2359
|
+
(Non negative integers, Non negative integers, Non negative integers)}
|
|
2360
|
+
sage: basis[1,2,1]
|
|
2361
|
+
F[a1]*F[a1+a2]^(2)*F[a2]
|
|
2362
|
+
sage: basis[1,2,4]
|
|
2363
|
+
F[a1]*F[a1+a2]^(2)*F[a2]^(4)
|
|
2364
|
+
sage: basis[1,0,4]
|
|
2365
|
+
F[a1]*F[a2]^(4)
|
|
2366
|
+
"""
|
|
2367
|
+
I = cartesian_product([NonNegativeIntegers()]*len(self._pos_roots))
|
|
2368
|
+
return Family(I, self._construct_monomial, name='monomial')
|
|
2369
|
+
|
|
2370
|
+
def _construct_canonical_basis_elts(self, k):
|
|
2371
|
+
r"""
|
|
2372
|
+
Construct the monomial elements of ``self`` indexed by ``k``.
|
|
2373
|
+
|
|
2374
|
+
EXAMPLES::
|
|
2375
|
+
|
|
2376
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2377
|
+
sage: B = Q.lower_half()
|
|
2378
|
+
sage: B._construct_canonical_basis_elts((1,2))
|
|
2379
|
+
[F[a1]*F[a2]^(2), (q^2)*F[a1]*F[a2]^(2) + F[a1+a2]*F[a2]]
|
|
2380
|
+
"""
|
|
2381
|
+
B = self._libgap.CanonicalBasis()
|
|
2382
|
+
return [self.element_class(self, v) for v in B.PBWElements(k)]
|
|
2383
|
+
|
|
2384
|
+
@cached_method
|
|
2385
|
+
def canonical_basis_elements(self):
|
|
2386
|
+
r"""
|
|
2387
|
+
Construct the monomial elements of ``self`` indexed by ``k``.
|
|
2388
|
+
|
|
2389
|
+
EXAMPLES::
|
|
2390
|
+
|
|
2391
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2392
|
+
sage: B = Q.lower_half()
|
|
2393
|
+
sage: C = B.canonical_basis_elements(); C
|
|
2394
|
+
Lazy family (Canonical basis(i))_{i in The Cartesian product of
|
|
2395
|
+
(Non negative integers, Non negative integers)}
|
|
2396
|
+
sage: C[2,1]
|
|
2397
|
+
[F[a1]^(2)*F[a2], F[a1]*F[a1+a2] + (q^2)*F[a1]^(2)*F[a2]]
|
|
2398
|
+
sage: C[1,2]
|
|
2399
|
+
[F[a1]*F[a2]^(2), (q^2)*F[a1]*F[a2]^(2) + F[a1+a2]*F[a2]]
|
|
2400
|
+
"""
|
|
2401
|
+
I = cartesian_product([NonNegativeIntegers()]*len(self._cartan_type.index_set()))
|
|
2402
|
+
return Family(I, self._construct_canonical_basis_elts, name='Canonical basis')
|
|
2403
|
+
|
|
2404
|
+
def lift(self, elt):
|
|
2405
|
+
r"""
|
|
2406
|
+
Lift ``elt`` to the ambient quantum group of ``self``.
|
|
2407
|
+
|
|
2408
|
+
EXAMPLES::
|
|
2409
|
+
|
|
2410
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2411
|
+
sage: B = Q.lower_half()
|
|
2412
|
+
sage: x = B.lift(B.an_element()); x
|
|
2413
|
+
1
|
|
2414
|
+
sage: x.parent() is Q
|
|
2415
|
+
True
|
|
2416
|
+
"""
|
|
2417
|
+
return self._Q.element_class(self._Q, elt._libgap)
|
|
2418
|
+
|
|
2419
|
+
def retract(self, elt):
|
|
2420
|
+
r"""
|
|
2421
|
+
Retract ``elt`` from the ambient quantum group to ``self``.
|
|
2422
|
+
|
|
2423
|
+
EXAMPLES::
|
|
2424
|
+
|
|
2425
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2426
|
+
sage: B = Q.lower_half()
|
|
2427
|
+
sage: x = Q.an_element(); x
|
|
2428
|
+
1 + (q)*F[a1] + E[a1] + (q^2-1-q^-2 + q^-4)*[ K1 ; 2 ]
|
|
2429
|
+
+ K1 + (-q^-1 + q^-3)*K1[ K1 ; 1 ]
|
|
2430
|
+
sage: B.retract(x)
|
|
2431
|
+
1 + (q)*F[a1]
|
|
2432
|
+
"""
|
|
2433
|
+
return self.element_class(self, self._proj(elt)._libgap)
|
|
2434
|
+
|
|
2435
|
+
class Element(QuaGroupModuleElement):
|
|
2436
|
+
"""
|
|
2437
|
+
An element of the lower half of the quantum group.
|
|
2438
|
+
"""
|
|
2439
|
+
def _acted_upon_(self, scalar, self_on_left=False):
|
|
2440
|
+
r"""
|
|
2441
|
+
Return the action of ``scalar`` on ``self``.
|
|
2442
|
+
|
|
2443
|
+
EXAMPLES::
|
|
2444
|
+
|
|
2445
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2446
|
+
sage: B = Q.lower_half()
|
|
2447
|
+
sage: F1, F2 = Q.F_simple()
|
|
2448
|
+
sage: v = B.highest_weight_vector(); v
|
|
2449
|
+
1
|
|
2450
|
+
sage: 2 * v
|
|
2451
|
+
(2)*1
|
|
2452
|
+
sage: v * (3/2)
|
|
2453
|
+
(3/2)*1
|
|
2454
|
+
sage: F1 * v
|
|
2455
|
+
F[a1]
|
|
2456
|
+
sage: F2 * (F1 * v)
|
|
2457
|
+
(q)*F[a1]*F[a2] + F[a1+a2]
|
|
2458
|
+
sage: (F1 * v) * F2
|
|
2459
|
+
F[a1]*F[a2]
|
|
2460
|
+
"""
|
|
2461
|
+
try:
|
|
2462
|
+
if scalar.parent() is self.parent()._Q:
|
|
2463
|
+
if self_on_left:
|
|
2464
|
+
ret = self._libgap * scalar._libgap
|
|
2465
|
+
else:
|
|
2466
|
+
ret = scalar._libgap * self._libgap
|
|
2467
|
+
return self.__class__(self.parent(), self.parent()._proj(ret)._libgap)
|
|
2468
|
+
except AttributeError:
|
|
2469
|
+
pass
|
|
2470
|
+
return QuaGroupModuleElement._acted_upon_(self, scalar, self_on_left)
|
|
2471
|
+
|
|
2472
|
+
_lmul_ = _acted_upon_
|
|
2473
|
+
|
|
2474
|
+
def _mul_(self, other):
|
|
2475
|
+
r"""
|
|
2476
|
+
Multiply ``self`` and ``other``.
|
|
2477
|
+
|
|
2478
|
+
EXAMPLES::
|
|
2479
|
+
|
|
2480
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2481
|
+
sage: B = Q.lower_half()
|
|
2482
|
+
sage: F1, F2 = Q.F_simple()
|
|
2483
|
+
sage: v = B.highest_weight_vector()
|
|
2484
|
+
sage: f1, f2 = F1 * v, F2 * v
|
|
2485
|
+
sage: f1 * f2
|
|
2486
|
+
F[a1]*F[a2]
|
|
2487
|
+
sage: f1^2 * f2
|
|
2488
|
+
(q + q^-1)*F[a1]^(2)*F[a2]
|
|
2489
|
+
sage: f2 * f1^2 * f2
|
|
2490
|
+
(q + q^-1)*F[a1]*F[a1+a2]*F[a2]
|
|
2491
|
+
+ (q^4 + 2*q^2 + 1)*F[a1]^(2)*F[a2]^(2)
|
|
2492
|
+
"""
|
|
2493
|
+
ret = self.parent()._proj(self._libgap * other._libgap)
|
|
2494
|
+
return self.__class__(self.parent(), ret._libgap)
|
|
2495
|
+
|
|
2496
|
+
def monomial_coefficients(self, copy=True):
|
|
2497
|
+
r"""
|
|
2498
|
+
Return the dictionary of ``self`` whose keys are the basis
|
|
2499
|
+
indices and the values are coefficients.
|
|
2500
|
+
|
|
2501
|
+
EXAMPLES::
|
|
2502
|
+
|
|
2503
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2504
|
+
sage: B = Q.lower_half()
|
|
2505
|
+
sage: x = B.retract(Q.an_element()); x
|
|
2506
|
+
1 + (q)*F[a1]
|
|
2507
|
+
sage: sorted(x.monomial_coefficients().items(), key=str)
|
|
2508
|
+
[((0, 0, 0), 1), ((1, 0, 0), q)]
|
|
2509
|
+
"""
|
|
2510
|
+
ext_rep = self._libgap.ExtRepOfObj()
|
|
2511
|
+
num_pos_roots = len(self.parent()._pos_roots)
|
|
2512
|
+
R = self.parent().base_ring()
|
|
2513
|
+
d = {}
|
|
2514
|
+
for i in range(len(ext_rep)//2):
|
|
2515
|
+
exp = [0] * num_pos_roots
|
|
2516
|
+
mon = ext_rep[2*i].sage()
|
|
2517
|
+
for j in range(len(mon)//2):
|
|
2518
|
+
exp[mon[2*j]-1] = mon[2*j+1]
|
|
2519
|
+
d[tuple(exp)] = R(str(ext_rep[2*i+1]))
|
|
2520
|
+
return d
|
|
2521
|
+
|
|
2522
|
+
def bar(self):
|
|
2523
|
+
r"""
|
|
2524
|
+
Return the bar involution on ``self``.
|
|
2525
|
+
|
|
2526
|
+
EXAMPLES::
|
|
2527
|
+
|
|
2528
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2529
|
+
sage: F1, F2 = Q.F_simple()
|
|
2530
|
+
sage: B = Q.lower_half()
|
|
2531
|
+
sage: x = B(Q.an_element()); x
|
|
2532
|
+
1 + (q)*F[a1]
|
|
2533
|
+
sage: x.bar()
|
|
2534
|
+
1 + (q^-1)*F[a1]
|
|
2535
|
+
sage: (F1*x).bar() == F1 * x.bar()
|
|
2536
|
+
True
|
|
2537
|
+
sage: (F2*x).bar() == F2 * x.bar()
|
|
2538
|
+
True
|
|
2539
|
+
|
|
2540
|
+
sage: Q = QuantumGroup(['G',2])
|
|
2541
|
+
sage: F1, F2 = Q.F_simple()
|
|
2542
|
+
sage: q = Q.q()
|
|
2543
|
+
sage: B = Q.lower_half()
|
|
2544
|
+
sage: x = B(q^-2*F1*F2^2*F1)
|
|
2545
|
+
sage: x
|
|
2546
|
+
(q + q^-5)*F[a1]*F[a1+a2]*F[a2]
|
|
2547
|
+
+ (q^8 + q^6 + q^2 + 1)*F[a1]^(2)*F[a2]^(2)
|
|
2548
|
+
sage: x.bar()
|
|
2549
|
+
(q^5 + q^-1)*F[a1]*F[a1+a2]*F[a2]
|
|
2550
|
+
+ (q^12 + q^10 + q^6 + q^4)*F[a1]^(2)*F[a2]^(2)
|
|
2551
|
+
"""
|
|
2552
|
+
bar = self.parent()._libgap.BarAutomorphism()
|
|
2553
|
+
# bar does not introduce E/K/Ki's
|
|
2554
|
+
return self.__class__(self.parent(), libgap.Image(bar, self._libgap))
|
|
2555
|
+
|
|
2556
|
+
def tau(self):
|
|
2557
|
+
r"""
|
|
2558
|
+
Return the action of the `\tau` anti-automorphism on ``self``.
|
|
2559
|
+
|
|
2560
|
+
EXAMPLES::
|
|
2561
|
+
|
|
2562
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2563
|
+
sage: F1, F2 = Q.F_simple()
|
|
2564
|
+
sage: B = Q.lower_half()
|
|
2565
|
+
sage: x = B(Q.an_element()); x
|
|
2566
|
+
1 + (q)*F[a1]
|
|
2567
|
+
sage: x.tau()
|
|
2568
|
+
1 + (q)*F[a1]
|
|
2569
|
+
sage: (F1*x).tau() == x.tau() * F1.tau()
|
|
2570
|
+
True
|
|
2571
|
+
sage: (F2*x).tau() == x.tau() * F2.tau()
|
|
2572
|
+
True
|
|
2573
|
+
|
|
2574
|
+
sage: Q = QuantumGroup(['G',2])
|
|
2575
|
+
sage: F1, F2 = Q.F_simple()
|
|
2576
|
+
sage: q = Q.q()
|
|
2577
|
+
sage: B = Q.lower_half()
|
|
2578
|
+
sage: x = B(q^-2*F1*F2^2*F1)
|
|
2579
|
+
sage: x
|
|
2580
|
+
(q + q^-5)*F[a1]*F[a1+a2]*F[a2]
|
|
2581
|
+
+ (q^8 + q^6 + q^2 + 1)*F[a1]^(2)*F[a2]^(2)
|
|
2582
|
+
sage: x.tau()
|
|
2583
|
+
(q + q^-5)*F[a1]*F[a1+a2]*F[a2]
|
|
2584
|
+
+ (q^8 + q^6 + q^2 + 1)*F[a1]^(2)*F[a2]^(2)
|
|
2585
|
+
"""
|
|
2586
|
+
tau = self.parent()._libgap.AntiAutomorphismTau()
|
|
2587
|
+
# tau does not introduce E/K/Ki's
|
|
2588
|
+
return self.__class__(self.parent(), libgap.Image(tau, self._libgap))
|
|
2589
|
+
|
|
2590
|
+
def braid_group_action(self, braid):
|
|
2591
|
+
r"""
|
|
2592
|
+
Return the action of the braid group element ``braid``
|
|
2593
|
+
projected into ``self``.
|
|
2594
|
+
|
|
2595
|
+
INPUT:
|
|
2596
|
+
|
|
2597
|
+
- ``braid`` -- a reduced word of a braid group element
|
|
2598
|
+
|
|
2599
|
+
EXAMPLES::
|
|
2600
|
+
|
|
2601
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2602
|
+
sage: L = Q.lower_half()
|
|
2603
|
+
sage: v = L.highest_weight_vector().f_tilde([1,2,2,1]); v
|
|
2604
|
+
F[a1]*F[a1+a2]*F[a2]
|
|
2605
|
+
sage: v.braid_group_action([1])
|
|
2606
|
+
(-q^3-q)*F[a2]^(2)
|
|
2607
|
+
sage: v.braid_group_action([]) == v
|
|
2608
|
+
True
|
|
2609
|
+
"""
|
|
2610
|
+
if not braid:
|
|
2611
|
+
return self
|
|
2612
|
+
Q = self.parent()
|
|
2613
|
+
QU = Q._libgap
|
|
2614
|
+
tau = QU.AntiAutomorphismTau()
|
|
2615
|
+
f = QU.IdentityMapping()
|
|
2616
|
+
for i in braid:
|
|
2617
|
+
if i < 0:
|
|
2618
|
+
i = -i
|
|
2619
|
+
T = QU.AutomorphismTalpha(i)
|
|
2620
|
+
f *= tau * T * tau
|
|
2621
|
+
else:
|
|
2622
|
+
f *= QU.AutomorphismTalpha(i)
|
|
2623
|
+
ret = libgap.Image(f, self._libgap)
|
|
2624
|
+
return self.__class__(Q, Q._proj(ret)._libgap)
|
|
2625
|
+
|
|
2626
|
+
def _et(self, i):
|
|
2627
|
+
r"""
|
|
2628
|
+
Return the action of `\widetilde{e}_i` on ``self``.
|
|
2629
|
+
|
|
2630
|
+
EXAMPLES::
|
|
2631
|
+
|
|
2632
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2633
|
+
sage: L = Q.lower_half()
|
|
2634
|
+
sage: v = L.highest_weight_vector()
|
|
2635
|
+
sage: v._et(1)
|
|
2636
|
+
0
|
|
2637
|
+
sage: w = v.f_tilde([1,2,1]); w
|
|
2638
|
+
F[a1]*F[a1+a2]
|
|
2639
|
+
sage: w._et(1)
|
|
2640
|
+
F[a1+a2]
|
|
2641
|
+
sage: w._et(2)
|
|
2642
|
+
F[a1]^(2)
|
|
2643
|
+
sage: L.zero().e_tilde(1)
|
|
2644
|
+
0
|
|
2645
|
+
"""
|
|
2646
|
+
if not self: # self == 0
|
|
2647
|
+
return self
|
|
2648
|
+
Q = self.parent()
|
|
2649
|
+
ret = self._libgap.Ealpha(i)
|
|
2650
|
+
if not ret:
|
|
2651
|
+
return self.parent().zero()
|
|
2652
|
+
return self.__class__(Q, Q._proj(ret)._libgap)
|
|
2653
|
+
|
|
2654
|
+
def _ft(self, i):
|
|
2655
|
+
r"""
|
|
2656
|
+
Return the action of `\widetilde{e}_i` on ``self``.
|
|
2657
|
+
|
|
2658
|
+
EXAMPLES::
|
|
2659
|
+
|
|
2660
|
+
sage: Q = QuantumGroup(['A',2])
|
|
2661
|
+
sage: L = Q.lower_half()
|
|
2662
|
+
sage: v = L.highest_weight_vector()
|
|
2663
|
+
sage: v._ft(1)
|
|
2664
|
+
F[a1]
|
|
2665
|
+
sage: L.zero().f_tilde(1)
|
|
2666
|
+
0
|
|
2667
|
+
"""
|
|
2668
|
+
if not self: # self == 0
|
|
2669
|
+
return self
|
|
2670
|
+
Q = self.parent()
|
|
2671
|
+
ret = self._libgap.Falpha(i)
|
|
2672
|
+
if not ret:
|
|
2673
|
+
return self.parent().zero()
|
|
2674
|
+
return self.__class__(Q, Q._proj(ret)._libgap)
|
|
2675
|
+
|
|
2676
|
+
|
|
2677
|
+
def _unpickle_generic_element(parent, data):
|
|
2678
|
+
"""
|
|
2679
|
+
Used to unpickle an element of ``parent`` using ``data``.
|
|
2680
|
+
|
|
2681
|
+
EXAMPLES::
|
|
2682
|
+
|
|
2683
|
+
sage: Q = QuantumGroup(['D',4])
|
|
2684
|
+
sage: x = Q.an_element()
|
|
2685
|
+
sage: loads(dumps(x)) == x # indirect doctest
|
|
2686
|
+
True
|
|
2687
|
+
"""
|
|
2688
|
+
F = parent._libgap.FamilyObj().ElementsFamily()
|
|
2689
|
+
ret = []
|
|
2690
|
+
# We need to multiply by this to get the right type in GAP
|
|
2691
|
+
one = parent._libgap_base.One()
|
|
2692
|
+
for i in range(len(data) // 2):
|
|
2693
|
+
ret.append(libgap(data[2 * i]))
|
|
2694
|
+
ret.append(one * libgap(data[2 * i + 1].subs(q=parent._libgap_q)))
|
|
2695
|
+
return parent.element_class(parent, F.ObjByExtRep(ret))
|