atlas Library · Script File
W_classes.at
This file serves to compute with Weyl group conjugacy classes and characters. A large initial part is dedicated to deciding conjugacy in the Weyl group, and finding an explicit witness of conjugacy from a class representative. A first major task is to list the $W$ conjugacy classes. Every Weyl group element $w$ has an associated Levi subgroup (not necessarily standard), whose roots are those whose reflections fix all weights fixed by $w$ (its eigenspace for $1$ in the reflection representation). The function |Levi_info@WeylElt| defined in Levi_subgroups.at computes the |Levi_info| for this Levi subgroup. Then $w$ is in the Weyl group of this Levi subgroup, and by construction it is a relatively elliptic element there. The Weyl subgroup of any Levi subgroup is conjugate in $W$ to that of a standard Levi subgroup, so for the purpose of finding the conjugacy classes of $W$ it suffices to consider only standard Levi subgroups. These have been classified (under conjugacy by $W$) in Levi_subgroups.at. The function |standard_Levi_conjugacy_representatives| defined there lists standard Levi conjugacy class representatives, and the function |classify_standard_Levis| provides for a root datum more complete information in the form of a |StdLeviTable|, which also lists Levi conjugacy orbits for easy looking up. A subsidiary task is to enumerate elliptic conjugacy classes for each standard Levi subsystem. The function |elliptics_for_standard_Levi@(RootDatum,[int])| defined in elliptic.at accomplishes this, partly by explicit listing.
Definitions in source order
conjugacy_class_reps
conjugacy_class_reps (RootDatum rd) = [WeylElt]list of conjugacy class representatives of W(rd)
Levi_of
Levi_of (WeylElt w) = [int]posroot indices for simples of |w| system
avoiding construction of a |RootDatum|
StdLeviEltImage type
set_type StdLeviEltImage =
(WeylElt actor { conjugator from |image| back to original |w| }
, [int] Levi { simples for a standard Levi }
, WeylElt image { an element for Levi, conjugate in |W| to original |w| }
)Fields: actor, Levi, image
StdLeviReducer type
set_type StdLeviReducer = (WeylElt->StdLeviEltImage)
conjugate_from_some_standard_Levi
conjugate_from_some_standard_Levi = StdLeviReducerit is easy (but not very useful) to find some "standard" conjugate of |w|
The usefulness of a |StdLeviReducer| is limited if it can choose different standard Levis for different elements, even though they are conjugate. To be more useful, we must force finding a Levi from a fixed set of representatives. Both |levi_lookup| methods from Levi_subgroups.at will force choosing a Levi from a fixed set of representatives of classes of standard Levi subgroups.L67
conjugate_from_elected_Levi
conjugate_from_elected_Levi (StdLeviFinder lookup) = StdLeviReducerLevi_reducer declared
Levi_reducer : (RootDatum->StdLeviReducer)make this a variable; implements a map to standard LeviL79
Levi_reducer_rho
Levi_reducer_rho (RootDatum rd) = StdLeviReducerLevi_reducer_classify
Levi_reducer_classify (RootDatum rd) = StdLeviReducerthis appears to be fasterL86
ConjugacyWitnesser type
set_type ConjugacyWitnesser = (WeylElt->(WeylElt->Maybe<WeylElt>))
Conjugacy tests will always be curried (take one |WeylElt| first, then possibly after some preparation produce a function that takes a second one) and come in two forms: a strong one that can produce a withness of conjugacy in case it holds, and a weak one that just tells whether conjugacy holds. Our approach always begins with reducing to the relatively elliptic case: each $w$ is relatively elliptic in the (generally not standard) Levi subgroup |Levi_of(w)| and if $w,w'$ have |Levi_of(w)=Levi_of(w')| and are conjugate in $W$ they are already conjugate in |Levi_of(w)|; therefore to test an arbitrary pair for conjugacy we can first test their Levi subgroups for conjugacy, and if so conjugate the elements to a common Levi subgroup and test conjugacy there. (For practical reasons that common Levi will be taken to be standard.) To avoid unnecessarily creation of (sub-) root data, the reduced test will be performed inside the original Weyl group, but with a specified list of generators of the Levi subgroup passed as argument (being a stardard Levi, this will be a subset of the simple roots, not necessarily listed increasing).
ConjugacyTester type
set_type ConjugacyTester = (WeylElt->(WeylElt->bool))
LeviConjugacyWitnesser type
set_type LeviConjugacyWitnesser = ([int],WeylElt->(WeylElt->Maybe<WeylElt>))
LeviConjugacyTester type
set_type LeviConjugacyTester = ([int],WeylElt->(WeylElt->bool))
conjugacy test, using a provided |classify| method and an elliptic case testL110
conjugacy_witness
conjugacy_witness (StdLeviReducer classify, LeviConjugacyWitnesser Lcw) = ConjugacyWitnesseralso in this file at line 278
conjugacy_test
conjugacy_test (StdLeviReducer classify, LeviConjugacyTester Levi_test) = ConjugacyTesterUsing an elliptic case test that does not provide a witness in case of a positive result, we can use the same approach but omit all the conjugacy computations (other than conjugating the given elements |w| to the elected standard Levi in the orbit of of |Levi_of(w)|, which happens inside |classify|.
Our next task is giving a conjugacy test for the elliptic case. For that we shall use an explicit enumeration of the set of minimal length representatives of an elliptic element; once this is done for one element, we can test the other element by finding a minimal length conjugate and looking it up.L155
The following greedy algorithm is guaranteed to give at least one minimal length conjugate of any eleent |w| it may be applied to, and moreover to give *all* such conjugates if |w| is elliptic; these facts are due to He. This essentially says that one can conjugate |w| to a minimal length conjugate doing one simple, weakly length decreasing conjugation at a time; moreover, for a given minimal length elliptic element, all its conjugates of the same length can be obtained by a sequence of length-preserving simple conjugations. NOTE: in A2 the two simple generators are conjugate, but (obviously) not by either one of them, which shows that the elliptic hypothesis in the second part of the above claim cannot be dropped. So: given a Weyl group element |w|, generate simple conjugates of it that are not longer than it, replacing |w| whenever a shorter conjugate is found, while restarting the generation; as long as that does not happen, make a collection of all equal length conjugates generated, which is also used for producing furtehr simple conjugates (and cleared at a restart). For every conjugate generated, also record a conjugating element towards it from the original |w|. The function |minima_He| implements this. For generating equal length conjugates we use an orbit generation by shells of distance from the starting point at the current length.L161
hash_code
hash_code (WeylElt w,int mod) = intalso defined in hash.at
minima_He
minima_He ([int] Levi,WeylElt w) = [WeylElt,WeylElt]$(w', g)$ with $g*w*/g = w'$
minimal_representative_with_witness
minimal_representative_with_witness (WeylElt w) = (WeylElt,WeylElt)one selected minimal length class representative, witness conjugating to it; this works whether or not |w| is (relatively) elliptic
also in this file at line 232
minimal_representative
minimal_representative (WeylElt w) = WeylEltoften one does not need a witness, so the following can be used instead
also in this file at line 235
minimal_representative_with_witness
minimal_representative_with_witness (([int],WeylElt) a) = (WeylElt,WeylElt)Even though finding a minimum can be done without, we can restrict to a Levi
also in this file at line 225
minimal_representative
minimal_representative (([int],WeylElt) a) = WeylEltoften one does not need a witness, so the following can be used instead
also in this file at line 228
is_elliptic_for_Levi
is_elliptic_for_Levi ([int] Levi,WeylElt w) = boolminimal_representatives_with_witness
minimal_representatives_with_witness (([int],WeylElt)args) = [WeylElt,WeylElt]minimal_representatives
minimal_representatives (([int],WeylElt)args) = [WeylElt]He_witnesser
He_witnesser = LeviConjugacyWitnesserHe_tester
He_tester = LeviConjugacyTesterConjugacy test, using reduction to elliptic We use the fact that x,y are conjugate iff L_x=x.Levi_datum is conjugate to L_y=y.Levi_datum, and, after conjugating L_y to L_x, x_ell is L_x conjugate to y_ell, where x_ell, y_ell are the elliptic classes in L_x, L_y corresponding to x,y Note that there is a choice of how to conjugate L_y to L_x, however the result is independent of that choice, essentially because the only elliptic class in type A is the Coxeter element, and the elliptic classes in a simple group are fixed by all outer automorphisms.L262
is_conjugate_in
is_conjugate_in (RootDatum rd) = ConjugacyTesterconjugacy_witness
conjugacy_witness (StdLeviReducer classify) = ConjugacyWitnessersimilarly default to |He_witnesser| for |conjugacy_witness|
also in this file at line 112
conjugacy_witness_in
conjugacy_witness_in (RootDatum rd) = ConjugacyWitnesseruntabled_tester
untabled_tester (LeviConjugacyTester Levi_test) = ConjugacyTesterWe can test for conjugacy without doing a classificatin of the standard Levis. The function |untabled_tester| conjugates |Levi_of(x)| for the first candidate |x| to some standard Levi |sLevi|, and generates the |rho_stabiliser_orbit| (which tabulates all Levis conjugate to it that have a dominant |two_rho| value). For the other candidate |y|, it first does some quick checks that will rule out many non-conjugate elements, and if this is not decisive, finds a Levi |L| conjugate to |Levi_of(y))| that has dominant |two_rho|; if this matches, |L| must be tabulated and we can find a conjugate from |Levi_of(y)| via |L| to |sLevi|; after conjugating both |x| and |y| into |sLevi|, the provided |LeviConjugacyTester| is applied to compare the images of |x| and |y|. Note that although we are not interested in getting a witness for conjugacy in case it should hold, we still must keep track of elemeent that conjugate the Levi subgroups in question to each other.
the following inefficient function is unused, but motivates the one after itL340
Levi_orbit
Levi_orbit (RootDatum rd, [int] Levi ) = [[int]]$W$-orbit of (non standard) Levi subsystem, represented by simple systems
posroot indices
Computing just the size of this Levi orbit can be done a bit more efficiently than generating it, though it requires a some preliminary computation. The e idea is to use the stabiliser subgroup $M$ in $W$ of $\rho_L$; although it does not contain the normaliser $N_L$ of the parabolic subgroup $L$ ow $W$ (since elements of $N_L$ can send |simples(L)| to a different set that also generates $L$), the intersection $M\cap N_L$ has known index in $N_L$, namely the size of $W_L$ (every coset by $W_L$ meets the intersection uniquely: there is a unique element of $W_L$ that sends the image of |simples(L)| by an element of $N_L$ back to |simples(L)| as a set). So we generate the (hopefully small) orbit under $M$ of images of the Levi system |simples(L)|, then by dividing the size of $M$ by that of the orbit find the size of $M\cap N_L$, which multiplied by the size of $W_L$ gives the size of $N_L$; finally dividing the size of $W$ by that gives our Levi orbit size. The orbit generation here is tailored to the specific situation, whence we do it using local code (the |begin|-|end| block below) rather than writing or using a more general orbit generation. The special circumstance is that we know that all elements of the acting subgroup fix $\rho_L$, so the only way they can map all simple generators of $L$ to roots of $L$ is by permuting them among each other. We can then ignore the distinction between a root and its opposite (working only with positive root indices) and not worry about choosing the simple generators for the positive part of each Levi system (which is why we had to single out the "do nothing" case above): the Levi system implied by a set of indices is the one additively generated by those roots and their opposites, and this results in the same system only if the indices are the same up to permutation. So again we can use an equality test for orbit membership, provided we sort our lists of indices to be increasing.L372
Levi_normalizer_index
Levi_normalizer_index ((RootDatum,(int->bool))(rd,select):Levi_info) = intindex of $W_L$ in $N_L$L439
Levi_orbit_size
Levi_orbit_size ((RootDatum,(int->bool))(rd,):Levi_info) = intelliptic_simple_decomposition
elliptic_simple_decomposition (WeylElt w) = [WeylElt,(string,int)]Now onward to the task of getting the size of the conjugacy class of |w| for |Levi_datum(w)|, where, ignoring the central torus, it is elliptic. This root datum can have multiple simple factors, and we can decompose |w| as commuting product of elements of the Weyl groups of the simple factors, and its conjugacy class will be the Cartesian product of the conjugacy classes of the factors (the same goes for the centraliser). The following function determines this decomposition, where each |WeylElt| in the result is associated to a different root datum, which is simple up to a central torus.
word in simple factor root datum, and latter type
centralizer_order
centralizer_order = (WeylElt->int)also defined in combinatorics.at, character_tables.at
size_of_conjugacy_class
size_of_conjugacy_class (WeylElt w) = intnumber of elements of a conjugacy class
sizes_of_conjugacy_classes
sizes_of_conjugacy_classes (RootDatum rd) = [int]WeylClassTable type
set_type [ WeylClassTable = ( int order_W , [WeylElt] class_representatives , (WeylElt->int) class_of , [int] class_sizes , (int,int->int) class_power , [int] trivial , [int] sign , [int] reflection , ([int]->int) dimension , ([int]->int) norm2 , ([int],[int]->int) inner , ([int],[int]->[int]) direct_sum , ([int],int->[int]) Cartesian_power , ([int],[int]->[int]) tensor , ([int],int->[int]) tensor_power , (int->[int]) sym_power_refl ) ]
Fields: order_W, class_representatives, class_of, class_sizes, class_power, trivial, sign, reflection, dimension, norm2, inner, direct_sum, Cartesian_power, tensor, tensor_power, sym_power_refl
A final production is a type for storing data relevant to W-characters, notably information about conjugacy classes. This will be a (mildly) "stateful value" in that some data, notably for the symmetric powers of the reflection representation, are computed and stored on demand only. In order to achieve this access is often via function components that can access the hidden state.
W_class_table 2 overloads
W_class_table ( RootDatum rd , [WeylElt] !reps , (int->int) class_size , (WeylElt->int) class_nr_of , (int,int->int) power_map ) = WeylClassTableFrom the above functions, the generic table constructor will only use |conjugacy_class_reps|, |size_of_conjugacy_class|, and |is_conjugate| to get its information (and choices) concerning conjugacy. Since these general purpose functions may be much slower than type specific ones, our main constructor takes additional arguments in their place, and then the generic constructor will provide mentioned functions in thir place.
conjugacy class representatives
size of class, by class numer
conjugacy classification
for conjugacy classes
W_class_table ( RootDatum rd , [WeylElt] reps , (WeylElt->int) class_size , ConjugacyTester is_conjugate_to ) = WeylClassTableW_class_table_generic
W_class_table_generic (RootDatum rd) = WeylClassTablea version with no help to find conjugacy classes, potentially much slower
W_class_table_untabled
W_class_table_untabled (RootDatum rd) = WeylClassTabletrivial_class_table
!trivial_class_table = W_class_table_generic(adjoint(""))A valid class table that can be used to initialise local variables
n_classes
n_classes (WeylClassTable tab) = intalso defined in character_tables.at
root_datum
root_datum (WeylClassTable tab) = RootDatumat least one class exists
also defined in basic.at, W_reps.at, K_Nilpotent.at, sommers.at, parabolics.at, K.at, nilpotent_orbits.at, extended_misc.at, character_tables.at, springer_tables.at, disconnected.at, cyclotomic_Lie_algebra.at, bracket.at, exceptional.at
reorder
reorder (WeylClassTable tab, [WeylElt] reps) = WeylClassTableadapt an existing table to an externally imposed order of the classes
class_representative
class_representative (WeylClassTable tab) = (int i) WeylEltalso defined in character_tables.at
class_size
class_size (WeylClassTable tab) = (int i) intalso defined in combinatorics.at, character_tables.at
conjugacy_class_number
conjugacy_class_number (WeylClassTable ct,WeylElt w) = intindex i for which w is conjugate to classes[i], in given WeylClassTable
character_value
character_value (WeylClassTable ct,[int] char, WeylElt w) = intvalue of character char at w\in W
Adams
Adams (WeylClassTable tab) = ([int]char, int n) [int]Adams's operation (not Jeff's): evaluate character at class of $w^n$
sym_power
sym_power (WeylClassTable tab) = ([int]char, int n) [int]symmetric power of a character
also defined in character_tables.at
last symmetric power is the one we wantL690
ext_power
ext_power (WeylClassTable tab) = ([int]char, int n) [int]exterior power of a character
also defined in character_tables.at
last symmetric power is the one we wantL705
Convenience functionsL707
print_classes
print_classes(WeylClassTable tab) = voidtest_size_of_conjugacy_classes 2 overloads
test_size_of_conjugacy_classes (RootDatum rd,[WeylElt] c) = (int,int)test: sum of sizes of conjugacy class = |W|
test_size_of_conjugacy_classes (RootDatum rd) = boolprint_conjugacy_classes
print_conjugacy_classes ([WeylElt] C) = voidprint order, length, Levi.
also in this file at line 764
print_conjugacy_classes_med
print_conjugacy_classes_med ([WeylElt] C) = voidprint order, length, Levi.
print_conjugacy_classes_long
print_conjugacy_classes_long ([WeylElt] C) = voidalso in this file at line 767
print_conjugacy_classes
print_conjugacy_classes (RootDatum rd) = voidalso in this file at line 730
print_conjugacy_classes_long
print_conjugacy_classes_long (RootDatum rd) = voidalso in this file at line 752
print_elliptic_conjugacy_classes
print_elliptic_conjugacy_classes (RootDatum rd) = voidprint elliptic classes only
print_elliptic_conjugacy_classes_long
print_elliptic_conjugacy_classes_long (RootDatum rd) = voidGenerated from atlas-scripts at commit 648506c (2026-10-13).