Bases: sage.categories.category_types.Category_over_base_ring
The category of weight lattice realizations over a given base ring
A weight lattice realization over a base ring
is a free
module (or vector space if
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
a root lattice realization.
Typical weight lattice realizations over include the weight
lattice, and ambient lattice. Typical weight lattice realizations
over
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 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 , and embed the weight
lattice element
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 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 is a subring of
, then one could in theory have an
embedding from the weight space over
to any weight lattice
realization over
; 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])
Return the symmetric form of self with la.
Return the pairing on the weight lattice. See Chapter 6
in Kac, Infinite Dimensional Lie Algebras for more details.
Warning
For affine root systems, if you are not working in the extended weight lattice/space, this may return incorrect results.
EXAMPLES:
sage: P = RootSystem(['C',2]).weight_lattice()
sage: al = P.simple_roots()
sage: al[1].symmetric_form(al[1])
2
sage: al[1].symmetric_form(al[2])
-2
sage: al[2].symmetric_form(al[1])
-2
sage: Q = RootSystem(['C',2]).root_lattice()
sage: alQ = Q.simple_roots()
sage: all(al[i].symmetric_form(al[j]) == alQ[i].symmetric_form(alQ[j])
....: for i in P.index_set() for j in P.index_set())
True
sage: P = RootSystem(['C',2,1]).weight_lattice(extended=True)
sage: al = P.simple_roots()
sage: al[1].symmetric_form(al[1])
2
sage: al[1].symmetric_form(al[2])
-2
sage: al[1].symmetric_form(al[0])
-2
sage: al[0].symmetric_form(al[1])
-2
sage: Q = RootSystem(['C',2,1]).root_lattice()
sage: alQ = Q.simple_roots()
sage: all(al[i].symmetric_form(al[j]) == alQ[i].symmetric_form(alQ[j])
....: for i in P.index_set() for j in P.index_set())
True
sage: La = P.basis()
sage: [La['delta'].symmetric_form(al) for al in P.simple_roots()]
[0, 0, 0]
sage: [La[0].symmetric_form(al) for al in P.simple_roots()]
[1, 0, 0]
sage: P = RootSystem(['C',2,1]).weight_lattice()
sage: Q = RootSystem(['C',2,1]).root_lattice()
sage: al = P.simple_roots()
sage: alQ = Q.simple_roots()
sage: all(al[i].symmetric_form(al[j]) == alQ[i].symmetric_form(alQ[j])
....: for i in P.index_set() for j in P.index_set())
True
The result of should be
, however we
get
because we are not working in the extended weight
lattice:
sage: La = P.basis()
sage: [La[0].symmetric_form(al) for al in P.simple_roots()]
[0, 0, 0]
TESTS:
We check that has 3 different root lengths:
sage: P = RootSystem(['A',4,2]).weight_lattice()
sage: al = P.simple_roots()
sage: [al[i].symmetric_form(al[i]) for i in P.index_set()]
[2, 4, 8]
Returns the Dynkin diagram automorphism induced by an alcove morphism
INPUT:
This method returns the Dynkin diagram automorphism for
the decomposition (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 of the decomposition, and see how
permutes the simple roots.
Embed the classical weight in the level level hyperplane
This is achieved by translating the straightforward
embedding of by
for
some appropriate
scalar.
INPUT:
EXAMPLES:
sage: L = RootSystem(["B",3,1]).weight_space()
sage: L0 = L.classical()
sage: alpha = L0.simple_roots()
sage: omega = L0.fundamental_weights()
sage: L.embed_at_level(omega[1], 1)
Lambda[1]
sage: L.embed_at_level(omega[2], 1)
-Lambda[0] + Lambda[2]
sage: L.embed_at_level(omega[3], 1)
Lambda[3]
sage: L.embed_at_level(alpha[1], 1)
Lambda[0] + 2*Lambda[1] - Lambda[2]
Returns the fundamental weight
INPUT:
By a slight notational abuse, for an affine type this method
should also accept "delta" as input, and return the image
of 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 ...>
Returns the family 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)]
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
INPUT:
Let be the fundamental alcove. This returns a reduced word
such that the affine Weyl group element
maps the alcove
back
to
. In other words, the alcove walk
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 . The extended
affine Weyl group is then the group of linear maps on
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:
where is in the Weyl group, and
is a function which
maps the fundamental alcove to itself. As
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 , whereas the method
dynkin_diagram_automorphism_of_alcove_morphism() returns
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 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 :
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
Given an element of the root lattice, this returns a reduced
word such that the Weyl group element
implements the “translation”
where
maps to
. In other words, the alcove walk
brings the fundamental alcove to the
corresponding translated alcove.
Note: there are some technical conditions for 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
EXAMPLES:
sage: RootSystem(['A',3]).ambient_lattice().rho()
(3, 2, 1, 0)
Return the embedding at level 0 of of the classical lattice.
EXAMPLES:
sage: RootSystem(['C',4,1]).weight_lattice().rho_classical()
-4*Lambda[0] + Lambda[1] + Lambda[2] + Lambda[3] + Lambda[4]
sage: L = RootSystem(['D',4,1]).weight_lattice()
sage: L.rho_classical().scalar(L.null_coroot())
0
Warning
In affine type BC dual, this does not live in the weight lattice:
sage: L = CartanType(["BC",2,2]).dual().root_system().weight_space()
sage: L.rho_classical()
-3/2*Lambda[0] + Lambda[1] + Lambda[2]
sage: L = CartanType(["BC",2,2]).dual().root_system().weight_lattice()
sage: L.rho_classical()
Traceback (most recent call last):
...
ValueError: 5 is not divisible by 2
Let walk = denote an alcove walk starting
from the fundamental alcove
, crossing at step 1 the
wall
, and so on.
For each , set
, and denote
by
the alcove reached after
steps. Then,
is obtained recursively from
by applying the
following reflection:
The step is said positive if is a
negative root (considering
as element of the
classical Weyl group and
as a classical
root) and negative otherwise. The algorithm implemented
here use the equivalent property:
.. MATH:: \langle w_{k-1}^{-1} \rho_0, \alpha^\vee_{i_k}\rangle > 0
Where is the sum of the classical fundamental
weights embedded at level 0 in this space (see
rho_classical()), and
is the
simple coroot associated to
.
This function returns a list of the form ,
where the
entry denotes whether the
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]
sage: L = RootSystem(['B',2,1]).coweight_lattice()
sage: L.signs_of_alcovewalk([0,1,2,0,1,2])
[1, -1, 1, -1, 1, 1]
Warning
This method currently does not work in the weight
lattice for type BC dual because does not
live in this lattice (but an integral multiple of it
would do the job as well).
Returns the -th simple root
This default implementation takes the -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 versus
interpretation of type
; see the thematic tutorial on Lie
Methods and Related Combinatorics in Sage for details.
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'>
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]