Weight lattice realizations

class sage.combinat.root_system.weight_lattice_realizations.WeightLatticeRealizations(base, name=None)

Bases: sage.categories.category_types.Category_over_base_ring

The category of weight lattice realizations over a given base ring

A weight lattice realization L over a base ring R is a free module (or vector space if R is a field) endowed with an embedding of the root lattice of some root system. By restriction, this embedding defines an embedding of the root lattice of this root system, which makes L a root lattice realization.

Typical weight lattice realizations over \ZZ include the weight lattice, and ambient lattice. Typical weight lattice realizations over \QQ include the weight space, and ambient space.

To describe the embedding, a weight lattice realization must implement a method fundamental_weight`(i) returning for each `i() in the index set the image of the fundamental weight \Lambda_i under the embedding.

In order to be a proper root lattice realization, a weight lattice realization should also implement the scalar product with the coroot lattice; on the other hand, the embedding of the simple roots is given for free.

EXAMPLES:

Here, we consider the root system of type A_7, and embed the weight lattice element x = \Lambda_1 + 2 \Lambda_3 in several root lattice realizations:

sage: R = RootSystem(["A",7])
sage: Lambda = R.weight_lattice().fundamental_weights()
sage: x = Lambda[2] + 2 * Lambda[5]

sage: L = R.weight_space()
sage: L(x)
Lambda[2] + 2*Lambda[5]

sage: L = R.ambient_lattice()
sage: L(x)
(3, 3, 2, 2, 2, 0, 0, 0)

We embed the weight space element x = \Lambda_1 + 1/2 \Lambda_3 in the ambient space:

sage: Lambda = R.weight_space().fundamental_weights()
sage: x = Lambda[2] + 1/2 * Lambda[5]

sage: L = R.ambient_space()
sage: L(x)
(3/2, 3/2, 1/2, 1/2, 1/2, 0, 0, 0)

Of course, one can’t embed the weight space in the ambient lattice:

sage: L = R.ambient_lattice()
sage: L(x)
Traceback (most recent call last):
...
TypeError: do not know how to make x (= Lambda[2] + 1/2*Lambda[5]) an element of self (=Ambient lattice of the Root system of type ['A', 7])

If K_1 is a subring of K_2, then one could in theory have an embedding from the weight space over K_1 to any weight lattice realization over K_2; this is not implemented:

sage: K1 = QQ
sage: K2 = QQ['q']
sage: L = R.ambient_space(K2)

sage: Lambda = R.weight_space(K2).fundamental_weights()
sage: L(Lambda[1])
(1, 0, 0, 0, 0, 0, 0, 0)

sage: Lambda = R.weight_space(K1).fundamental_weights()
sage: L(Lambda[1])
Traceback (most recent call last):
...
TypeError: do not know how to make x (= Lambda[1]) an element of self (=Ambient space of the Root system of type ['A', 7])
class ParentMethods
dynkin_diagram_automorphism_of_alcove_morphism(f)

Returns the Dynkin diagram automorphism induced by an alcove morphism

INPUT:

  • f - a linear map from self to self which preserves alcoves

This method returns the Dynkin diagram automorphism for the decomposition f = d w (see reduced_word_of_alcove_morphism()), as a dictionnary mapping elements of the index set to itself.

EXAMPLES:

sage: R = RootSystem(["A",2,1]).weight_lattice()
sage: alpha = R.simple_roots()
sage: Lambda = R.fundamental_weights()

Translations by elements of the root lattice induce a trivial Dynkin diagram automorphism:

sage: R.dynkin_diagram_automorphism_of_alcove_morphism(alpha[0].translation)
{0: 0, 1: 1, 2: 2}
sage: R.dynkin_diagram_automorphism_of_alcove_morphism(alpha[1].translation)
{0: 0, 1: 1, 2: 2}
sage: R.dynkin_diagram_automorphism_of_alcove_morphism(alpha[2].translation)
{0: 0, 1: 1, 2: 2}

This is no more the case for translations by general elements of the (classical) weight lattice at level 0:

sage: omega1 = Lambda[1] - Lambda[0]
sage: omega2 = Lambda[2] - Lambda[0]

sage: R.dynkin_diagram_automorphism_of_alcove_morphism(omega1.translation)
{0: 1, 1: 2, 2: 0}
sage: R.dynkin_diagram_automorphism_of_alcove_morphism(omega2.translation)
{0: 2, 1: 0, 2: 1}

sage: R = RootSystem(['C',2,1]).weight_lattice()
sage: alpha = R.simple_roots()
sage: R.dynkin_diagram_automorphism_of_alcove_morphism(alpha[1].translation)
{0: 2, 1: 1, 2: 0}

sage: R = RootSystem(['D',5,1]).weight_lattice()
sage: Lambda = R.fundamental_weights()
sage: omega1 = Lambda[1] - Lambda[0]
sage: omega2 = Lambda[2] - 2*Lambda[0]
sage: R.dynkin_diagram_automorphism_of_alcove_morphism(omega1.translation)
{0: 1, 1: 0, 2: 2, 3: 3, 4: 5, 5: 4}
sage: R.dynkin_diagram_automorphism_of_alcove_morphism(omega2.translation)
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5}

Algorithm: computes w of the decomposition, and see how f\circ w^{-1} permutes the simple roots.

fundamental_weight(i)

Returns the i^{th} fundamental weight

INPUT:

  • i – an element of the index set

By a slight notational abuse, for an affine type this method should also accept "delta" as input, and return the image of \delta of the extended weight lattice in this realization.

This should be overridden by any subclass, and typically be implemented as a cached method for efficiency.

EXAMPLES:

sage: L = RootSystem(["A",3]).ambient_lattice()
sage: L.fundamental_weight(1)
(1, 0, 0, 0)

sage: L = RootSystem(["A",3,1]).weight_lattice(extended=True)
sage: L.fundamental_weight(1)
Lambda[1]
sage: L.fundamental_weight("delta")
delta

TESTS:

sage: super(sage.combinat.root_system.weight_space.WeightSpace, L).fundamental_weight(1)
Traceback (most recent call last):
...
NotImplementedError: <abstract method fundamental_weight at ...>
fundamental_weights()

Returns the family (\Lambda_i)_{i\in I} of the fundamental weights.

EXAMPLES:

sage: e = RootSystem(['A',3]).ambient_lattice()
sage: f = e.fundamental_weights()
sage: [f[i] for i in [1,2,3]]
[(1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0)]
is_extended()

Returns whether this is a realization of the extended weight lattice

EXAMPLES:

sage: RootSystem(["A",3,1]).weight_lattice().is_extended()
False
sage: RootSystem(["A",3,1]).weight_lattice(extended=True).is_extended()
True

This method is irrelevant for finite root systems, since the weight lattice need not be extended to ensure that the root lattice embeds faithfully:

sage: RootSystem(["A",3]).weight_lattice().is_extended()
False
plot(size=[[0], [0]], projection='usual', simple_roots=True, fundamental_weights=True, alcovewalks=[])

Return a graphics object built from a space of weight(space/lattice). There is a different technic to plot if the Cartan type is affine or not. The graphics returned is a Graphics object.

This function is experimental, and is subject to short term evolutions.

EXAMPLES:

By default, the plot returned has no axes and the ratio between axes is 1.
  sage: G = RootSystem(['C',2]).weight_lattice().plot()
  sage: G.axes(True)
  sage: G.set_aspect_ratio(2)

For a non affine Cartan type, the plot method work for type with 2 generators,
it will draw the hyperlane(line for this dimension) accrow the fundamentals weights.
  sage: G = RootSystem(['A',2]).weight_lattice().plot()
  sage: G = RootSystem(['B',2]).weight_lattice().plot()
  sage: G = RootSystem(['G',2]).weight_lattice().plot()

The plot returned has a size of one fundamental polygon by default. We can
ask plot to give a bigger plot by using the argument size
  sage: G = RootSystem(['G',2,1]).weight_space().plot(size = [[0..1],[-1..1]])
  sage: G = RootSystem(['A',2,1]).weight_space().plot(size = [[-1..1],[-1..1]])

A very important argument is the projection which will draw the plot. There are
some usual projections is this method. If you want to draw in the plane a very
special Cartan type, Sage will ask you to specify the projection. The projection
is a matrix over a ring. In practice, calcul over float is a good way to draw.
  sage: L = RootSystem(['A',2,1]).weight_space()
  sage: G = L.plot(projection=matrix(RR, [[0,0.5,-0.5],[0,0.866,0.866]]))
  sage: G = RootSystem(['C',2,1]).weight_space().plot()

By default, the plot method draw the simple roots, this can be disabled by setting
the argument simple_roots=False
  sage: G = RootSystem(['A',2]).weight_space().plot(simple_roots=False)

By default, the plot method draw the fundamental weights,this can be disabled by
setting the argument fundamental_weights=False
  sage: G = RootSystem(['A',2]).weight_space().plot(fundamental_weights=False, simple_roots=False)

There is in a plot an argument to draw alcoves walks. The good way to do this is
to use the crystals theory. the plot method contains only the drawing part...
  sage: L = RootSystem(['A',2,1]).weight_space()
  sage: G = L.plot(size=[[-1..1],[-1..1]],alcovewalks=[[0,2,0,1,2,1,2,0,2,1]])
reduced_word_of_alcove_morphism(f)

INPUT:

  • f – a linear map from self to self which preserves alcoves.

Let A be the fundamental alcove. This returns a reduced word i_1,...,i_k such that the affine Weyl group element w =
s_{i_1} \circ \dots \circ s_{i_k} maps the alcove f(A) back to A. In other words, the alcove walk i_1,...,i_k brings the fundamental alcove to the corresponding translated alcove.

Let us throw in a bit of context to explain the main use case. It is customary to realize the alcove picture in the coroot or coweight lattice R^\vee. The extended affine Weyl group is then the group of linear maps on R^\vee which preserve the alcoves. By [Kac “Infinite-dimensional Lie algebra”, Proposition 6.5] the affine Weyl group is the semidirect product of the associated finite Weyl group and the group of translations in the coroot lattice (the extended affine Weyl group uses the coweight lattice instead). In other words, an element of the extended affine Weyl group admits a unique decomposition of the form:

f = d w ,

where w is in the Weyl group, and d is a function which maps the fundamental alcove to itself. As d permutes the walls of the fundamental alcove, it permutes accordingly the corresponding simple roots, which induces an automorphism of the Dynkin diagram.

This method returns a reduced word for w, whereas the method dynkin_diagram_automorphism_of_alcove_morphism() returns d as a permutation of the nodes of the Dynkin diagram.

Nota bene: recall that the coroot (resp. coweight) lattice is implemented as the root (resp weight) lattice of the dual root system. Hence, this method is implemented for weight lattice realizations, but in practice is most of the time used on the dual side.

EXAMPLES:

We start with type A which is simply laced; hence we do not have to worry about the distinction between the weight and coweight lattice:

sage: R = RootSystem(["A",2,1]).weight_lattice()
sage: alpha = R.simple_roots()
sage: Lambda = R.fundamental_weights()

We consider first translations by elements of the root lattice:

sage: R.reduced_word_of_alcove_morphism(alpha[0].translation)
[1, 2, 1, 0]
sage: R.reduced_word_of_alcove_morphism(alpha[1].translation)
[0, 2, 0, 1]
sage: R.reduced_word_of_alcove_morphism(alpha[2].translation)
[0, 1, 0, 2]

We continue with translations by elements of the classical weight lattice, embedded at level 0:

sage: omega1 = Lambda[1] - Lambda[0] sage: omega2 = Lambda[2] - Lambda[0]

sage: R.reduced_word_of_alcove_morphism(omega1.translation) [0, 2] sage: R.reduced_word_of_alcove_morphism(omega2.translation) [0, 1]

The following tests ensure that the code agrees with the tables in Kashiwara’s private notes on affine quantum algebras (2008).

TESTS:

sage: R = RootSystem(['A',5,1]).weight_lattice()
sage: alpha = R.simple_roots()
sage: Lambda = R.fundamental_weights()
sage: omega1 = Lambda[1] - Lambda[0]
sage: R.reduced_word_of_alcove_morphism(omega1.translation)
[0, 5, 4, 3, 2]
sage: R.reduced_word_of_alcove_morphism(alpha[0].translation)
[1, 2, 3, 4, 5, 4, 3, 2, 1, 0]

sage: R = RootSystem(['C',3,1]).weight_lattice()
sage: alpha = R.simple_roots()
sage: Lambda = R.fundamental_weights()
sage: omega1 = 2*(Lambda[1] - Lambda[0])
sage: omega2 = 2*(Lambda[2] - Lambda[0])
sage: omega3 = Lambda[3] - Lambda[0]
sage: R.reduced_word_of_alcove_morphism(omega1.translation)
[0, 1, 2, 3, 2, 1]
sage: R.reduced_word_of_alcove_morphism(omega2.translation)
[0, 1, 0, 2, 1, 3, 2, 1, 3, 2]
sage: R.reduced_word_of_alcove_morphism(omega3.translation)
[0, 1, 0, 2, 1, 0]
sage: W = WeylGroup(['C',3,1])
sage: s = W.simple_reflections()
sage: w = s[0]*s[1]*s[2]*s[3]*s[2]
sage: W.from_reduced_word(R.reduced_word_of_alcove_morphism(omega2.translation)) == w*w
True
sage: w = s[0]*s[1]*s[2]*s[0]*s[1]*s[0]
sage: W.from_reduced_word(R.reduced_word_of_alcove_morphism(omega3.translation)) == w
True

sage: R = RootSystem(['D',4,1]).weight_lattice()
sage: Lambda = R.fundamental_weights()
sage: omega1 = Lambda[1] - Lambda[0]
sage: omega2 = Lambda[2] - 2*Lambda[0]
sage: omega3 = Lambda[3] - Lambda[0]
sage: omega4 = Lambda[4] - Lambda[0]
sage: R.reduced_word_of_alcove_morphism(omega1.translation)
[0, 2, 3, 4, 2, 0]
sage: R.reduced_word_of_alcove_morphism(omega2.translation)
[0, 2, 1, 3, 2, 4, 2, 1, 3, 2]
sage: R.reduced_word_of_alcove_morphism(omega3.translation)
[0, 2, 1, 4, 2, 0]
sage: R.reduced_word_of_alcove_morphism(omega4.translation)
[0, 2, 1, 3, 2, 0]
sage: W = WeylGroup(['D',4,1])
sage: s = W.simple_reflections()
sage: w = s[0]*s[2]*s[3]*s[4]*s[2]
sage: w1= s[1]*s[2]*s[3]*s[4]*s[2]
sage: W.from_reduced_word(R.reduced_word_of_alcove_morphism(omega2.translation)) == w*w1
True

sage: R = RootSystem(['D',5,1]).weight_lattice()
sage: Lambda = R.fundamental_weights()
sage: omega1 = Lambda[1] - Lambda[0]
sage: omega2 = Lambda[2] - 2*Lambda[0]
sage: R.reduced_word_of_alcove_morphism(omega1.translation)
[0, 2, 3, 4, 5, 3, 2, 0]
sage: W = WeylGroup(['D',5,1])
sage: s = W.simple_reflections()
sage: w = s[0]*s[2]*s[3]*s[4]*s[5]*s[3]*s[2]
sage: w1= s[1]*s[2]*s[3]*s[4]*s[5]*s[3]*s[2]
sage: W.from_reduced_word(R.reduced_word_of_alcove_morphism(omega2.translation)) == w*w1
True
reduced_word_of_translation(t)

Given an element of the root lattice, this returns a reduced word i_1,...,i_k such that the Weyl group element s_{i_1}
\circ \dots \circ s_{i_k} implements the “translation” where x maps to x + level(x)*t. In other words, the alcove walk i_1,...,i_k brings the fundamental alcove to the corresponding translated alcove.

Note: there are some technical conditions for t to actually be a translation; those are not tested (TODO: detail).

EXAMPLES:

sage: R = RootSystem(["A",2,1]).weight_lattice()
sage: alpha = R.simple_roots()
sage: R.reduced_word_of_translation(alpha[1])
[0, 2, 0, 1]
sage: R.reduced_word_of_translation(alpha[2])
[0, 1, 0, 2]
sage: R.reduced_word_of_translation(alpha[0])
[1, 2, 1, 0]

sage: R = RootSystem(['D',5,1]).weight_lattice()
sage: Lambda = R.fundamental_weights()
sage: omega1 = Lambda[1] - Lambda[0]
sage: omega2 = Lambda[2] - 2*Lambda[0]
sage: R.reduced_word_of_translation(omega1)
[0, 2, 3, 4, 5, 3, 2, 0]
sage: R.reduced_word_of_translation(omega2)
[0, 2, 1, 3, 2, 4, 3, 5, 3, 2, 1, 4, 3, 2]

A non simply laced case:

sage: R = RootSystem(["C",2,1]).weight_lattice()
sage: Lambda = R.fundamental_weights()
sage: c = R.cartan_type().translation_factors()
sage: c
Finite family {0: 1, 1: 2, 2: 1}
sage: R.reduced_word_of_translation((Lambda[1]-Lambda[0]) * c[1])
[0, 1, 2, 1]
sage: R.reduced_word_of_translation((Lambda[2]-Lambda[0]) * c[2])
[0, 1, 0]

See also _test_reduced_word_of_translation().

TODO:

  • Add a picture in the doc
  • Add a method which, given an element of the classical weight lattice, constructs the appropriate value for t
rho()

EXAMPLES:

sage: RootSystem(['A',3]).ambient_lattice().rho()
(3, 2, 1, 0)
rho_classical()

For an affine type in a weight space, rho_classical is the analog of rho in the classical parabolic subgroup. it lives in the level 0.

EXAMPLES:

sage: RootSystem(['C',4,1]).weight_space().rho_classical()
-4*Lambda[0] + Lambda[1] + Lambda[2] + Lambda[3] + Lambda[4]
sage: WS = RootSystem(['D',4,1]).weight_space()
sage: WS.rho_classical().scalar(WS.null_coroot())
0
signs_of_alcovewalk(walk)

Let walk = [i_1,\dots,i_n] denote an alcove walk starting from the fundamental alcove y_0, crossing at step 1 the wall i_1, and so on.

For each k, set w_k = s_{i_1} \circ s_{i_k}, and denote by y_k = w_k(y_0) the alcove reached after k steps. Then, y_k is obtained recursively from y_{k-1} by applying the following reflection:

y_k = s_{w_{k-1} \alpha_{i_k}} y_{k-1}

The step is said positive if w_{k-1} \alpha_{i_k} is a negative root (considering w_{k-1} as element of the classical Weyl group and \alpha_{i_k} as a classical root) and negative otherwise.

This function returns a list of the form [+1,+1,-1,...], where the k^{th} entry denotes whether the k^{th} step was positive or negative.

See equation 3.4, of Ram: Alcove walks ..., arxiv:math/0601343v1 [math.RT]

EXAMPLES:

sage: L = RootSystem(['C',2,1]).weight_lattice()
sage: L.signs_of_alcovewalk([1,2,0,1,2,1,2,0,1,2])
[-1, -1, 1, -1, 1, 1, 1, 1, 1, 1]
sage: L = RootSystem(['A',2,1]).weight_lattice()
sage: L.signs_of_alcovewalk([0,1,2,1,2,0,1,2,0,1,2,0])
[1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1]
simple_root(i)

Returns the i-th simple root

This default implementation takes the i-th simple root in the weight lattice and embeds it in self.

EXAMPLES:

Since all the weight lattice realizations in Sage currently implement a simple_root method, we have to call this one by hand:

sage: from sage.combinat.root_system.weight_lattice_realizations import WeightLatticeRealizations
sage: simple_root = WeightLatticeRealizations(QQ).parent_class.simple_root.f
sage: L = RootSystem("A3").ambient_space()
sage: simple_root(L, 1)
(1, -1, 0, 0)
sage: simple_root(L, 2)
(0, 1, -1, 0)
sage: simple_root(L, 3)
(1, 1, 2, 0)

Note that this last root differs from the one implemented in L by a multiple of the vector (1,1,1,1):

sage: L.simple_roots()
Finite family {1: (1, -1, 0, 0), 2: (0, 1, -1, 0), 3: (0, 0, 1, -1)}

This is a harmless artefact of the SL versus GL interpretation of type A; see the thematic tutorial on Lie Methods and Related Combinatorics in Sage for details.

weyl_dimension(highest_weight)

EXAMPLES:

sage: RootSystem(['A',3]).ambient_lattice().weyl_dimension([2,1,0,0])
20

sage: type(RootSystem(['A',3]).ambient_lattice().weyl_dimension([2,1,0,0]))
<type 'sage.rings.integer.Integer'>
WeightLatticeRealizations.super_categories()

EXAMPLES:

sage: from sage.combinat.root_system.weight_lattice_realizations import WeightLatticeRealizations
sage: WeightLatticeRealizations(QQ).super_categories()
[Category of root lattice realizations over Rational Field]

Previous topic

Root lattice realizations

Next topic

Root lattices and root spaces

This Page