# Root lattice realizations¶

class sage.combinat.root_system.root_lattice_realizations.RootLatticeRealizations(base, name=None)

The category of root lattice realizations over a given base ring

A root 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.

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

To describe the embedding, a root lattice realization must implement a method simple_root() returning for each $$i$$ in the index set the image of the simple root $$\alpha_i$$ under the embedding.

A root lattice realization must further implement a method on elements scalar(), computing the scalar product with elements of the coroot lattice or coroot space.

Using those, this category provides tools for reflections, roots, the Weyl group and its action, …

EXAMPLES:

Here, we consider the root system of type $$A_7$$, and embed the root lattice element $$x = \alpha_2 + 2 \alpha_6$$ in several root lattice realizations:

sage: R = RootSystem(["A",7])
sage: alpha = R.root_lattice().simple_roots()
sage: x = alpha + 2 * alpha

sage: L = R.root_space()
sage: L(x)
alpha + 2*alpha

sage: L = R.weight_lattice()
sage: L(x)
-Lambda + 2*Lambda - Lambda - 2*Lambda + 4*Lambda - 2*Lambda

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


We embed the root space element $$x = \alpha_2 + 1/2 \alpha_6$$ in several root lattice realizations:

sage: alpha = R.root_space().simple_roots()
sage: x = alpha + 1/2 * alpha

sage: L = R.weight_space()
sage: L(x)
-Lambda + 2*Lambda - Lambda - 1/2*Lambda + Lambda - 1/2*Lambda

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


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

sage: L = R.weight_lattice()
sage: L(x)
Traceback (most recent call last):
...
TypeError: do not know how to make x (= alpha + 1/2*alpha) an element of self (=Weight 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 root space over $$K_1$$ to any root lattice realization over $$K_2$$; this is not implemented:

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

sage: alpha = R.root_space(K2).simple_roots()
sage: L(alpha)
2*Lambda - Lambda

sage: alpha = R.root_space(K1).simple_roots()
sage: L(alpha)
Traceback (most recent call last):
...
TypeError: do not know how to make x (= alpha) an element of self (=Weight space over the Univariate Polynomial Ring in q over Rational Field of the Root system of type ['A', 7])


By a slight abuse, the embedding of the root lattice is not actually required to be faithful. Typically for an affine root system, the null root of the root lattice is killed in the non extended weight lattice:

sage: R = RootSystem(["A", 3, 1])
sage: delta = R.root_lattice().null_root()
sage: L = R.weight_lattice()
sage: L(delta)
0

Algebras
class ElementMethods
affine_orbit()

The orbit of self under the dot or affine action of the Weyl group.

EXAMPLES:

sage: L = RootSystem(['A', 2]).ambient_lattice()
sage: sorted(L.rho().dot_orbit())          # the output order is not specified
[(-2, 1, 4), (-2, 3, 2), (2, -1, 2),
(2, 1, 0), (0, -1, 4), (0, 3, 0)]

sage: L = RootSystem(['B',2]).weight_lattice()
sage: sorted(L.fundamental_weights().dot_orbit())   # the output order is not specified
[-4*Lambda, -4*Lambda + 4*Lambda,
-3*Lambda - 2*Lambda, -3*Lambda + 4*Lambda,
Lambda, Lambda - 6*Lambda,
2*Lambda - 6*Lambda, 2*Lambda - 2*Lambda]


We compare the dot action orbit to the regular orbit:

sage: L = RootSystem(['A', 3]).weight_lattice()
sage: len(L.rho().dot_orbit())
24
sage: len((-L.rho()).dot_orbit())
1
sage: La = L.fundamental_weights()
sage: len(La.dot_orbit())
24
sage: len(La.orbit())
4
sage: len((-L.rho() + La).dot_orbit())
4
sage: len(La.dot_orbit())
24
sage: len(La.orbit())
6
sage: len((-L.rho() + La).dot_orbit())
6

associated_coroot()

Returns the coroot associated to this root

EXAMPLES:

sage: alpha = RootSystem(["A", 3]).root_space().simple_roots()
sage: alpha.associated_coroot()
alphacheck

associated_reflection()

Given a positive root self, returns a reduced word for the reflection orthogonal to self.

Since the answer is cached, it is a tuple instead of a list.

EXAMPLES:

sage: RootSystem(['C',3]).root_lattice().simple_root(3).weyl_action([1,2]).associated_reflection()
(1, 2, 3, 2, 1)
sage: RootSystem(['C',3]).root_lattice().simple_root(2).associated_reflection()
(2,)

descents(index_set=None, positive=False)

Returns the descents of pt

EXAMPLES:

sage: space=RootSystem(['A',5]).weight_space()
sage: alpha=space.simple_roots()
sage: (alpha+alpha+alpha).descents()
[3, 5]

dot_action(w, inverse=False)

Act on self by w using the dot or affine action.

Let $$w$$ be an element of the Weyl group. The dot action or affine action is given by:

$w \bullet \lambda = w (\lambda + \rho) - \rho,$

where $$\rho$$ is the sum of the fundamental weights.

INPUT:

• w – an element of a Coxeter or Weyl group of the same Cartan type, or a tuple or a list (such as a reduced word) of elements from the index set
• inverse – a boolean (default: False); whether to act by the inverse element

EXAMPLES:

sage: P = RootSystem(['B',3]).weight_lattice()
sage: La = P.fundamental_weights()
sage: mu = La + 2*La - 3*La
sage: mu.dot_action()
-3*Lambda + 4*Lambda - 3*Lambda
sage: mu.dot_action()
Lambda + Lambda
sage: mu.dot_action([1,2,3])
-4*Lambda + Lambda + 3*Lambda


We check that the origin of this action is at $$-\rho$$:

sage: all((-P.rho()).dot_action([i]) == -P.rho()
....:     for i in P.index_set())
True


REFERENCES:

dot_orbit()

The orbit of self under the dot or affine action of the Weyl group.

EXAMPLES:

sage: L = RootSystem(['A', 2]).ambient_lattice()
sage: sorted(L.rho().dot_orbit())          # the output order is not specified
[(-2, 1, 4), (-2, 3, 2), (2, -1, 2),
(2, 1, 0), (0, -1, 4), (0, 3, 0)]

sage: L = RootSystem(['B',2]).weight_lattice()
sage: sorted(L.fundamental_weights().dot_orbit())   # the output order is not specified
[-4*Lambda, -4*Lambda + 4*Lambda,
-3*Lambda - 2*Lambda, -3*Lambda + 4*Lambda,
Lambda, Lambda - 6*Lambda,
2*Lambda - 6*Lambda, 2*Lambda - 2*Lambda]


We compare the dot action orbit to the regular orbit:

sage: L = RootSystem(['A', 3]).weight_lattice()
sage: len(L.rho().dot_orbit())
24
sage: len((-L.rho()).dot_orbit())
1
sage: La = L.fundamental_weights()
sage: len(La.dot_orbit())
24
sage: len(La.orbit())
4
sage: len((-L.rho() + La).dot_orbit())
4
sage: len(La.dot_orbit())
24
sage: len(La.orbit())
6
sage: len((-L.rho() + La).dot_orbit())
6

extraspecial_pair()

Return the extraspecial pair of self under the ordering defined by positive_roots_by_height().

The extraspecial pair of a positive root $$\gamma$$ with some total ordering $$<$$ of the root lattice that respects height is the pair of positive roots $$(\alpha, \beta)$$ such that $$\gamma = \alpha + \beta$$ and $$\alpha$$ is as small as possible.

EXAMPLES:

sage: Q = RootSystem(['G', 2]).root_lattice()
sage: Q.highest_root().extraspecial_pair()
(alpha, 3*alpha + alpha)

first_descent(index_set=None, positive=False)

Returns the first descent of pt

One can use the index_set option to restrict to the parabolic subgroup indexed by index_set.

EXAMPLES:

sage: space=RootSystem(['A',5]).weight_space()
sage: alpha=space.simple_roots()
sage: (alpha+alpha+alpha).first_descent()
3
sage: (alpha+alpha+alpha).first_descent([1,2,5])
5
sage: (alpha+alpha+alpha).first_descent([1,2,5,3,4])
5

greater()

Returns the elements in the orbit of self which are greater than self in the weak order.

EXAMPLES:

sage: L = RootSystem(['A',3]).ambient_lattice()
sage: e = L.basis()
sage: e.greater()
[(0, 0, 1, 0), (0, 0, 0, 1)]
sage: len(L.rho().greater())
24
sage: len((-L.rho()).greater())
1
sage: sorted([len(x.greater()) for x in L.rho().orbit()])
[1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 8, 8, 8, 8, 12, 12, 12, 24]

has_descent(i, positive=False)

Test if self has a descent at position $$i$$, that is if self is on the strict negative side of the $$i^{th}$$ simple reflection hyperplane.

If positive if True, tests if it is on the strict positive side instead.

EXAMPLES:

sage: space=RootSystem(['A',5]).weight_space()
sage: alpha=RootSystem(['A',5]).weight_space().simple_roots()
sage: [alpha[i].has_descent(1) for i in space.index_set()]
[False, True, False, False, False]
sage: [(-alpha[i]).has_descent(1) for i in space.index_set()]
[True, False, False, False, False]
sage: [alpha[i].has_descent(1, True) for i in space.index_set()]
[True, False, False, False, False]
sage: [(-alpha[i]).has_descent(1, True) for i in space.index_set()]
[False, True, False, False, False]
sage: (alpha+alpha+alpha).has_descent(3)
True
sage: (alpha+alpha+alpha).has_descent(1)
False
sage: (alpha+alpha+alpha).has_descent(1, True)
True

height()

Return the height of self.

The height of a root $$\alpha = \sum_i a_i \alpha_i$$ is defined to be $$h(\alpha) := \sum_i a_i$$.

EXAMPLES:

sage: Q = RootSystem(['G', 2]).root_lattice()
sage: Q.highest_root().height()
5

is_dominant(index_set=None, positive=True)

Returns whether self is dominant.

This is done with respect to the subrootsystem indicated by the subset of Dynkin nodes index_set. If index_set is None then the entire Dynkin node set is used. If positive is False then the dominance condition is replaced by antidominance.

EXAMPLES:

sage: L = RootSystem(['A',2]).ambient_lattice()
sage: Lambda = L.fundamental_weights()
sage: [x.is_dominant() for x in Lambda]
[True, True]
sage: [x.is_dominant(positive=False) for x in Lambda]
[False, False]
sage: (Lambda-Lambda).is_dominant()
False
sage: (-Lambda+Lambda).is_dominant()
False
sage: (Lambda-Lambda).is_dominant()
True
sage: (Lambda-Lambda).is_dominant()
False
sage: [x.is_dominant() for x in L.roots()]
[False, True, False, False, False, False]
sage: [x.is_dominant(positive=False) for x in L.roots()]
[False, False, False, False, True, False]

is_dominant_weight()

Test whether self is a dominant element of the weight lattice.

EXAMPLES:

sage: L = RootSystem(['A',2]).ambient_lattice()
sage: Lambda = L.fundamental_weights()
sage: [x.is_dominant() for x in Lambda]
[True, True]
sage: (3*Lambda+Lambda).is_dominant()
True
sage: (Lambda-Lambda).is_dominant()
False
sage: (-Lambda+Lambda).is_dominant()
False


Tests that the scalar products with the coroots are all nonnegative integers. For example, if $$x$$ is the sum of a dominant element of the weight lattice plus some other element orthogonal to all coroots, then the implementation correctly reports $$x$$ to be a dominant weight:

sage: x = Lambda + L([-1,-1,-1])
sage: x.is_dominant_weight()
True

is_imaginary_root()

Return True if self is an imaginary root.

A root $$\alpha$$ is imaginary if it is not $$W$$ conjugate to a simple root where $$W$$ is the corresponding Weyl group.

EXAMPLES:

sage: Q = RootSystem(['B',2,1]).root_lattice()
sage: alpha = Q.simple_roots()
sage: alpha.is_imaginary_root()
False
sage: elt = alpha + alpha + 2*alpha
sage: elt.is_imaginary_root()
True

is_long_root()

Return True if self is a long (real) root.

EXAMPLES:

sage: Q = RootSystem(['B',2,1]).root_lattice()
sage: alpha = Q.simple_roots()
sage: alpha.is_long_root()
True
sage: alpha.is_long_root()
True
sage: alpha.is_long_root()
False

is_parabolic_root(index_set)

Supposing that self is a root, is it in the parabolic subsystem with Dynkin nodes index_set?

INPUT:

• index_set – the Dynkin node set of the parabolic subsystem.

Todo

This implementation is only valid in the root or weight lattice

EXAMPLES:

sage: alpha = RootSystem(['A',3]).root_lattice().from_vector(vector([1,1,0]))
sage: alpha.is_parabolic_root([1,3])
False
sage: alpha.is_parabolic_root([1,2])
True
sage: alpha.is_parabolic_root()
False

is_real_root()

Return True if self is a real root.

A root $$\alpha$$ is real if it is $$W$$ conjugate to a simple root where $$W$$ is the corresponding Weyl group.

EXAMPLES:

sage: Q = RootSystem(['B',2,1]).root_lattice()
sage: alpha = Q.simple_roots()
sage: alpha.is_real_root()
True
sage: elt = alpha + alpha + 2*alpha
sage: elt.is_real_root()
False

is_short_root()

Return True if self is a short (real) root.

Returns False unless the parent is an irreducible root system of finite type having two root lengths and self is of the shorter length. There is no check of whether self is actually a root.

EXAMPLES:

sage: Q = RootSystem(['C',2]).root_lattice()
sage: al = Q.simple_root(1).weyl_action([1,2]); al
alpha + alpha
sage: al.is_short_root()
True
sage: bt = Q.simple_root(2).weyl_action([2,1,2]); bt
-2*alpha - alpha
sage: bt.is_short_root()
False
sage: RootSystem(['A',2]).root_lattice().simple_root(1).is_short_root()
False


An example in affine type:

sage: Q = RootSystem(['B',2,1]).root_lattice()
sage: alpha = Q.simple_roots()
sage: alpha.is_short_root()
False
sage: alpha.is_short_root()
False
sage: alpha.is_short_root()
True

level()

EXAMPLES:

sage: L = RootSystem(['A',2,1]).weight_lattice()
sage: L.rho().level()
3

norm_squared()

Return the norm squared of self with respect to the symmetric form.

EXAMPLES:

sage: Q = RootSystem(['B',2,1]).root_lattice()
sage: alpha = Q.simple_roots()
sage: alpha.norm_squared()
4
sage: alpha.norm_squared()
2
sage: elt = alpha - 3*alpha + alpha
sage: elt.norm_squared()
50
sage: elt = alpha + alpha + 2*alpha
sage: elt.norm_squared()
0
sage: Q = RootSystem(CartanType(['A',4,2]).dual()).root_lattice()
sage: Qc = RootSystem(['A',4,2]).coroot_lattice()
sage: alpha = Q.simple_roots()
sage: alphac = Qc.simple_roots()
sage: elt = alpha + 2*alpha + 2*alpha
sage: eltc = alphac + 2*alphac + 2*alphac
sage: elt.norm_squared()
0
sage: eltc.norm_squared()
0

orbit()

The orbit of self under the action of the Weyl group.

EXAMPLES:

$$\rho$$ is a regular element whose orbit is in bijection with the Weyl group. In particular, it has 6 elements for the symmetric group $$S_3$$:

sage: L = RootSystem(["A", 2]).ambient_lattice()
sage: sorted(L.rho().orbit())               # the output order is not specified
[(1, 2, 0), (1, 0, 2), (2, 1, 0),
(2, 0, 1), (0, 1, 2), (0, 2, 1)]

sage: L = RootSystem(["A", 3]).weight_lattice()
sage: len(L.rho().orbit())
24
sage: len(L.fundamental_weights().orbit())
4
sage: len(L.fundamental_weights().orbit())
6

pred(index_set=None)

Return the immediate predecessors of self for the weak order.

INPUT:

• index_set - a subset (as a list or iterable) of the nodes of the Dynkin diagram; (default: None for all of them)

If index_set is specified, the successors for the corresponding parabolic subsystem are returned.

EXAMPLES:

sage: L = RootSystem(['A',3]).weight_lattice()
sage: Lambda = L.fundamental_weights()
sage: Lambda.pred()
[]
sage: L.rho().pred()
[]
sage: (-L.rho()).pred()
[Lambda - 2*Lambda - Lambda, -2*Lambda + Lambda - 2*Lambda, -Lambda - 2*Lambda + Lambda]
sage: (-L.rho()).pred(index_set=)
[Lambda - 2*Lambda - Lambda]

reduced_word(index_set=None, positive=True)

Returns a reduced word for the inverse of the shortest Weyl group element that sends the vector self into the dominant chamber.

With the index_set optional parameter, this is done with respect to the corresponding parabolic subgroup.

If positive is False, use the antidominant chamber instead.

EXAMPLES:

sage: space=RootSystem(['A',5]).weight_space()
sage: alpha=RootSystem(['A',5]).weight_space().simple_roots()
sage: alpha.reduced_word()
[2, 3, 4, 5]
sage: alpha.reduced_word([1,2])


reflection(root, use_coroot=False)

Reflects self across the hyperplane orthogonal to root.

If use_coroot is True, root is interpreted as a coroot.

EXAMPLES:

sage: R = RootSystem(['C',4])
sage: weight_lattice = R.weight_lattice()
sage: mu = weight_lattice.from_vector(vector([0,0,1,2]))
sage: coroot_lattice = R.coroot_lattice()
sage: alphavee = coroot_lattice.from_vector(vector([0,0,1,1]))
sage: mu.reflection(alphavee, use_coroot=True)
6*Lambda - 5*Lambda + 2*Lambda
sage: root_lattice = R.root_lattice()
sage: beta = root_lattice.from_vector(vector([0,1,1,0]))
sage: mu.reflection(beta)
Lambda - Lambda + 3*Lambda

scalar(lambdacheck)

Implement the natural pairing with the coroot lattice.

INPUT:

• self – an element of a root lattice realization
• lambdacheck – an element of the coroot lattice or coroot space

OUTPUT: the scalar product of self and lambdacheck

EXAMPLES:

sage: L = RootSystem(['A',4]).root_lattice()
sage: alpha      = L.simple_roots()
sage: alphacheck = L.simple_coroots()
sage: alpha.scalar(alphacheck)
2
sage: alpha.scalar(alphacheck)
-1
sage: matrix([ [ alpha[i].scalar(alphacheck[j])
....:            for i in L.index_set() ]
....:          for j in L.index_set() ])
[ 2 -1  0  0]
[-1  2 -1  0]
[ 0 -1  2 -1]
[ 0  0 -1  2]

simple_reflection(i)

Returns the image of self by the $$i$$-th simple reflection.

EXAMPLES:

sage: alpha = RootSystem(["A", 3]).root_lattice().alpha()
sage: alpha.simple_reflection(2)
alpha + alpha

sage: Q = RootSystem(['A', 3, 1]).weight_lattice(extended = True)
sage: Lambda = Q.fundamental_weights()
sage: L = Lambda + Q.null_root()
sage: L.simple_reflection(0)
-Lambda + Lambda + Lambda

simple_reflections()

The images of self by all the simple reflections

EXAMPLES:

sage: alpha = RootSystem(["A", 3]).root_lattice().alpha()
sage: alpha.simple_reflections()
[-alpha, alpha + alpha, alpha]

smaller()

Returns the elements in the orbit of self which are smaller than self in the weak order.

EXAMPLES:

sage: L = RootSystem(['A',3]).ambient_lattice()
sage: e = L.basis()
sage: e.smaller()
[(0, 0, 1, 0), (0, 1, 0, 0), (1, 0, 0, 0)]
sage: len(L.rho().smaller())
1
sage: len((-L.rho()).smaller())
24
sage: sorted([len(x.smaller()) for x in L.rho().orbit()])
[1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 8, 8, 8, 8, 12, 12, 12, 24]

succ(index_set=None)

Return the immediate successors of self for the weak order.

INPUT:

• index_set - a subset (as a list or iterable) of the nodes of the Dynkin diagram; (default: None for all of them)

If index_set is specified, the successors for the corresponding parabolic subsystem are returned.

EXAMPLES:

sage: L = RootSystem(['A',3]).weight_lattice()
sage: Lambda = L.fundamental_weights()
sage: Lambda.succ()
[-Lambda + Lambda]
sage: L.rho().succ()
[-Lambda + 2*Lambda + Lambda, 2*Lambda - Lambda + 2*Lambda, Lambda + 2*Lambda - Lambda]
sage: (-L.rho()).succ()
[]
sage: L.rho().succ(index_set=)
[-Lambda + 2*Lambda + Lambda]
sage: L.rho().succ(index_set=)
[2*Lambda - Lambda + 2*Lambda]

symmetric_form(alpha)

Return the symmetric form of self with alpha.

Consider the simple roots $$\alpha_i$$ and let $$(b_{ij})_{ij}$$ denote the symmetrized Cartan matrix $$(a_{ij})_{ij}$$, we have

$(\alpha_i | \alpha_j) = b_{ij}$

and extended bilinearly. See Chapter 6 in Kac, Infinite Dimensional Lie Algebras for more details.

EXAMPLES:

sage: Q = RootSystem(['B',2,1]).root_lattice()
sage: alpha = Q.simple_roots()
sage: alpha.symmetric_form(alpha)
0
sage: alpha.symmetric_form(alpha)
4
sage: elt = alpha - 3*alpha + alpha
sage: elt.symmetric_form(alpha)
-14
sage: elt.symmetric_form(alpha+2*alpha)
14
sage: Q = RootSystem(CartanType(['A',4,2]).dual()).root_lattice()
sage: Qc = RootSystem(['A',4,2]).coroot_lattice()
sage: alpha = Q.simple_roots()
sage: alphac = Qc.simple_roots()
sage: elt = alpha + 2*alpha + 2*alpha
sage: eltc = alphac + 2*alphac + 2*alphac
sage: elt.symmetric_form(alpha)
0
sage: eltc.symmetric_form(alphac)
0

to_ambient()

Map self to the ambient space.

EXAMPLES:

sage: alpha = CartanType(['B',4]).root_system().root_lattice().an_element(); alpha
2*alpha + 2*alpha + 3*alpha
sage: alpha.to_ambient()
(2, 0, 1, -3)
sage: mu = CartanType(['B',4]).root_system().weight_lattice().an_element(); mu
2*Lambda + 2*Lambda + 3*Lambda
sage: mu.to_ambient()
(7, 5, 3, 0)
sage: v = CartanType(['B',4]).root_system().ambient_space().an_element(); v
(2, 2, 3, 0)
sage: v.to_ambient()
(2, 2, 3, 0)
sage: alphavee = CartanType(['B',4]).root_system().coroot_lattice().an_element(); alphavee
2*alphacheck + 2*alphacheck + 3*alphacheck
sage: alphavee.to_ambient()
(2, 0, 1, -3)

to_classical()

Map self to the classical lattice/space.

Only makes sense for affine type.

EXAMPLES:

sage: R = CartanType(['A',3,1]).root_system()
sage: alpha = R.root_lattice().an_element(); alpha
2*alpha + 2*alpha + 3*alpha
sage: alb = alpha.to_classical(); alb
alpha - 2*alpha
sage: alb.parent()
Root lattice of the Root system of type ['A', 3]
sage: v = R.ambient_space().an_element(); v
2*e + 2*e + 3*e
sage: v.to_classical()
(2, 2, 3, 0)

to_dominant_chamber(index_set=None, positive=True, reduced_word=False)

Returns the unique dominant element in the Weyl group orbit of the vector self.

If positive is False, returns the antidominant orbit element.

With the index_set optional parameter, this is done with respect to the corresponding parabolic subgroup.

If reduced_word is True, returns the 2-tuple (weight, direction) where weight is the (anti)dominant orbit element and direction is a reduced word for the Weyl group element sending weight to self.

Warning

In infinite type, an orbit may not contain a dominant element. In this case the function may go into an infinite loop.

For affine root systems, errors are generated if the orbit does not contain the requested kind of representative. If the input vector is of positive (resp. negative) level, then there is a dominant (resp. antidominant) element in its orbit but not an antidominant (resp. dominant) one. If the vector is of level zero, then there are neither dominant nor antidominant orbit representatives, except for multiples of the null root, which are themselves both dominant and antidominant orbit representatives.

EXAMPLES:

sage: space=RootSystem(['A',5]).weight_space()
sage: alpha=RootSystem(['A',5]).weight_space().simple_roots()
sage: alpha.to_dominant_chamber()
Lambda + Lambda
sage: alpha.to_dominant_chamber([1,2])
Lambda + Lambda - Lambda
sage: wl=RootSystem(['A',2,1]).weight_lattice(extended=True)
sage: mu=wl.from_vector(vector([1,-3,0]))
sage: mu.to_dominant_chamber(positive=False, reduced_word = True)
(-Lambda - Lambda - delta, [0, 2])

sage: R = RootSystem(['A',1,1])
sage: rl = R.root_lattice()
sage: nu = rl.zero()
sage: nu.to_dominant_chamber()
0
sage: nu.to_dominant_chamber(positive=False)
0
sage: mu = rl.from_vector(vector([0,1]))
sage: mu.to_dominant_chamber()
Traceback (most recent call last):
...
ValueError: alpha is not in the orbit of the fundamental chamber
sage: mu.to_dominant_chamber(positive=False)
Traceback (most recent call last):
...
ValueError: alpha is not in the orbit of the negative of the fundamental chamber

to_dual_type_cospace()

Map self to the dual type cospace.

For example, if self is in the root lattice of type $$['B',2]$$, send it to the coroot lattice of type $$['C',2]$$.

EXAMPLES:

sage: v = CartanType(['C',3]).root_system().weight_lattice().an_element(); v
2*Lambda + 2*Lambda + 3*Lambda
sage: w = v.to_dual_type_cospace(); w
2*Lambdacheck + 2*Lambdacheck + 3*Lambdacheck
sage: w.parent()
Coweight lattice of the Root system of type ['B', 3]

to_simple_root(reduced_word=False)

Return (the index of) a simple root in the orbit of the positive root self.

INPUT:

• self – a positive root
• reduced_word – a boolean (default: False)

OUTPUT:

• The index $$i$$ of a simple root $$\alpha_i$$. If reduced_word is True, this returns instead a pair (i, word), where word is a sequence of reflections mapping $$\alpha_i$$ up the root poset to self.

EXAMPLES:

sage: L = RootSystem(["A",3]).root_lattice()
sage: positive_roots = L.positive_roots()
sage: for alpha in sorted(positive_roots):
....:     print("{} {}".format(alpha, alpha.to_simple_root()))
alpha 1
alpha + alpha 2
alpha + alpha + alpha 3
alpha 2
alpha + alpha 3
alpha 3
sage: for alpha in sorted(positive_roots):
....:     print("{} {}".format(alpha, alpha.to_simple_root(reduced_word=True)))
alpha (1, ())
alpha + alpha (2, (1,))
alpha + alpha + alpha (3, (1, 2))
alpha (2, ())
alpha + alpha (3, (2,))
alpha (3, ())


ALGORITHM:

This method walks from self down to the antidominant chamber by applying successively the simple reflection given by the first descent. Since self is a positive root, each step goes down the root poset, and one must eventually cross a simple root $$\alpha_i$$.

Warning

The behavior is not specified if the input is not a positive root. For a finite root system, this is currently caught (albeit with a not perfect message):

sage: alpha = L.simple_roots()
sage: (2*alpha).to_simple_root()
Traceback (most recent call last):
...
ValueError: -2*alpha - 2*alpha - 2*alpha is not a positive root


For an infinite root system, this method may run into an infinite recursion if the input is not a positive root.

translation(x)
INPUT:
• self - an element $$t$$ at level $$0$$
• x - an element of the same space

Returns $$x$$ translated by $$t$$, that is $$x+level(x) t$$

EXAMPLES:

sage: L = RootSystem(['A',2,1]).weight_lattice()
sage: alpha = L.simple_roots()
sage: Lambda = L.fundamental_weights()
sage: t = alpha


Let us look at the translation of an element of level $$1$$:

sage: Lambda.level()
1
sage: t.translation(Lambda)
-Lambda + 2*Lambda
sage: Lambda + t
-Lambda + 2*Lambda


and of an element of level $$0$$:

sage: alpha .level()
0
sage: t.translation(alpha )
-Lambda + 2*Lambda - Lambda
sage: alpha + 0*t
-Lambda + 2*Lambda - Lambda


The arguments are given in this seemingly unnatural order to make it easy to construct the translation function:

sage: f = t.translation
sage: f(Lambda)
-Lambda + 2*Lambda

weyl_action(element, inverse=False)

Act on self by an element of the Coxeter or Weyl group.

INPUT:

• element – an element of a Coxeter or Weyl group of the same Cartan type, or a tuple or a list (such as a reduced word) of elements from the index set
• inverse – a boolean (default: False); whether to act by the inverse element

EXAMPLES:

sage: wl = RootSystem(['A',3]).weight_lattice()
sage: mu = wl.from_vector(vector([1,0,-2]))
sage: mu
Lambda - 2*Lambda
sage: mudom, rw = mu.to_dominant_chamber(positive=False, reduced_word = True)
sage: mudom, rw
(-Lambda - Lambda, [1, 2])


Acting by a (reduced) word:

sage: mudom.weyl_action(rw)
Lambda - 2*Lambda
sage: mu.weyl_action(rw, inverse = True)
-Lambda - Lambda


Acting by an element of the Coxeter or Weyl group on a vector in its own lattice of definition (implemented by matrix multiplication on a vector):

sage: w = wl.weyl_group().from_reduced_word([1, 2])
sage: mudom.weyl_action(w)
Lambda - 2*Lambda


Acting by an element of an isomorphic Coxeter or Weyl group (implemented by the action of a corresponding reduced word):

sage: W = WeylGroup(['A',3], prefix="s")
sage: w = W.from_reduced_word([1, 2])
sage: wl.weyl_group() == W
False
sage: mudom.weyl_action(w)
Lambda - 2*Lambda

weyl_stabilizer(index_set=None)

Returns the subset of Dynkin nodes whose reflections fix self.

If index_set is not None, only consider nodes in this set. Note that if self is dominant or antidominant, then its stabilizer is the parabolic subgroup defined by the returned node set.

EXAMPLES:

sage: wl = RootSystem(['A',2,1]).weight_lattice(extended = True)
sage: al = wl.null_root()
sage: al.weyl_stabilizer()
[0, 1, 2]
sage: wl = RootSystem(['A',4]).weight_lattice()
sage: mu = wl.from_vector(vector([1,1,0,0]))
sage: mu.weyl_stabilizer()
[3, 4]
sage: mu.weyl_stabilizer(index_set = [1,2,3])


class ParentMethods
a_long_simple_root()

Returns a long simple root, corresponding to the highest outgoing edge in the Dynkin diagram.

Caveat: this may be break in affine type $$A_{2n}^{(2)}$$

Caveat: meaningful/broken for non irreducible?

TODO: implement CartanType.nodes_by_length as in MuPAD-Combinat (using CartanType.symmetrizer), and use it here.

almost_positive_roots()

Returns the almost positive roots of self

These are the positive roots together with the simple negative roots.

almost_positive_root_decomposition(), tau_plus_minus()

EXAMPLES:

sage: L = RootSystem(['A',2]).root_lattice()
sage: L.almost_positive_roots()
[-alpha, alpha, alpha + alpha, -alpha, alpha]

almost_positive_roots_decomposition()

Returns the decomposition of the almost positive roots of self

This is the list of the orbits of the almost positive roots under the action of the dihedral group generated by the operators $$\tau_+$$ and $$\tau_-$$.

EXAMPLES:

sage: RootSystem(['A',2]).root_lattice().almost_positive_roots_decomposition()
[[-alpha, alpha, alpha + alpha, alpha, -alpha]]

sage: RootSystem(['B',2]).root_lattice().almost_positive_roots_decomposition()
[[-alpha, alpha, alpha + 2*alpha], [-alpha, alpha, alpha + alpha]]

sage: RootSystem(['D',4]).root_lattice().almost_positive_roots_decomposition()
[[-alpha, alpha, alpha + alpha, alpha + alpha + alpha],
[-alpha, alpha, alpha + alpha + alpha + alpha, alpha + 2*alpha + alpha + alpha],
[-alpha, alpha, alpha + alpha, alpha + alpha + alpha],
[-alpha, alpha, alpha + alpha, alpha + alpha + alpha]]

alpha()

Returns the family $$(\alpha_i)_{i\in I}$$ of the simple roots, with the extra feature that, for simple irreducible root systems, $$\alpha_0$$ yields the opposite of the highest root.

EXAMPLES:

sage: alpha = RootSystem(["A",2]).root_lattice().alpha()
sage: alpha
alpha
sage: alpha
-alpha - alpha

alphacheck()

Returns the family $$( \alpha^\vee_i)_{i\in I}$$ of the simple coroots, with the extra feature that, for simple irreducible root systems, $$\alpha^\vee_0$$ yields the coroot associated to the opposite of the highest root (caveat: for non simply laced root systems, this is not the opposite of the highest coroot!)

EXAMPLES:

sage: alphacheck = RootSystem(["A",2]).ambient_space().alphacheck()
sage: alphacheck
Finite family {1: (1, -1, 0), 2: (0, 1, -1)}


Here is now $$\alpha^\vee_0$$:

(-1, 0, 1)

Todo

add a non simply laced example

Finaly, here is an affine example:

sage: RootSystem(["A",2,1]).weight_space().alphacheck()
Finite family {0: alphacheck, 1: alphacheck, 2: alphacheck}

sage: RootSystem(["A",3]).ambient_space().alphacheck()
Finite family {1: (1, -1, 0, 0), 2: (0, 1, -1, 0), 3: (0, 0, 1, -1)}

basic_imaginary_roots()

Return the basic imaginary roots of self.

The basic imaginary roots $$\delta$$ are the set of imaginary roots in $$-C^{\vee}$$ where $$C$$ is the dominant chamber (i.e., $$\langle \beta, \alpha_i^{\vee} \rangle \leq 0$$ for all $$i \in I$$). All imaginary roots are $$W$$-conjugate to a simple imaginary root.

EXAMPLES:

sage: RootSystem(['A', 2]).root_lattice().basic_imaginary_roots()
()
sage: Q = RootSystem(['A', 2, 1]).root_lattice()
sage: Q.basic_imaginary_roots()
(alpha + alpha + alpha,)
sage: delta = Q.basic_imaginary_roots()
sage: all(delta.scalar(Q.simple_coroot(i)) <= 0 for i in Q.index_set())
True

cartan_type()

EXAMPLES:

sage: r = RootSystem(['A',4]).root_space()
sage: r.cartan_type()
['A', 4]

classical()

Return the corresponding root/weight/ambient lattice/space.

EXAMPLES:

sage: RootSystem(["A",4,1]).root_lattice().classical()
Root lattice of the Root system of type ['A', 4]
sage: RootSystem(["A",4,1]).weight_lattice().classical()
Weight lattice of the Root system of type ['A', 4]
sage: RootSystem(["A",4,1]).ambient_space().classical()
Ambient space of the Root system of type ['A', 4]

cohighest_root()

Returns the associated coroot of the highest root.

Note

this is usually not the highest coroot.

EXAMPLES:

sage: RootSystem(['A', 3]).ambient_space().cohighest_root()
(1, 0, 0, -1)

coroot_lattice()

Returns the coroot lattice.

EXAMPLES:

sage: RootSystem(['A',2]).root_lattice().coroot_lattice()
Coroot lattice of the Root system of type ['A', 2]

coroot_space(base_ring=Rational Field)

Return the coroot space over base_ring.

INPUT:

• base_ring – a ring (default: $$\QQ$$)

EXAMPLES:

sage: RootSystem(['A',2]).root_lattice().coroot_space()
Coroot space over the Rational Field of the Root system of type ['A', 2]

sage: RootSystem(['A',2]).root_lattice().coroot_space(QQ['q'])
Coroot space over the Univariate Polynomial Ring in q over Rational Field of the Root system of type ['A', 2]

dual_type_cospace()

Returns the cospace of dual type.

For example, if invoked on the root lattice of type $$['B',2]$$, returns the coroot lattice of type $$['C',2]$$.

Warning

Not implemented for ambient spaces.

EXAMPLES:

sage: CartanType(['B',2]).root_system().root_lattice().dual_type_cospace()
Coroot lattice of the Root system of type ['C', 2]
sage: CartanType(['F',4]).root_system().coweight_lattice().dual_type_cospace()
Weight lattice of the Root system of type ['F', 4] relabelled by {1: 4, 2: 3, 3: 2, 4: 1}

dynkin_diagram()

EXAMPLES:

sage: r = RootSystem(['A',4]).root_space()
sage: r.dynkin_diagram()
O---O---O---O
1   2   3   4
A4

fundamental_weights_from_simple_roots()

Return the fundamental weights.

This is computed from the simple roots by using the inverse of the Cartan matrix. This method is therefore only valid for finite types and if this realization of the root lattice is large enough to contain them.

EXAMPLES:

In the root space, we retrieve the inverse of the Cartan matrix:

sage: L = RootSystem(["B",3]).root_space()
sage: L.fundamental_weights_from_simple_roots()
Finite family {1:     alpha +   alpha +     alpha,
2:     alpha + 2*alpha +   2*alpha,
3: 1/2*alpha +   alpha + 3/2*alpha}
sage: ~L.cartan_type().cartan_matrix()
[  1   1 1/2]
[  1   2   1]
[  1   2 3/2]


In the weight lattice and the ambient space, we retrieve the fundamental weights:

sage: L = RootSystem(["B",3]).weight_lattice()
sage: L.fundamental_weights_from_simple_roots()
Finite family {1: Lambda, 2: Lambda, 3: Lambda}

sage: L = RootSystem(["B",3]).ambient_space()
sage: L.fundamental_weights()
Finite family {1: (1, 0, 0), 2: (1, 1, 0), 3: (1/2, 1/2, 1/2)}
sage: L.fundamental_weights_from_simple_roots()
Finite family {1: (1, 0, 0), 2: (1, 1, 0), 3: (1/2, 1/2, 1/2)}


However the fundamental weights do not belong to the root lattice:

sage: L = RootSystem(["B",3]).root_lattice()
sage: L.fundamental_weights_from_simple_roots()
Traceback (most recent call last):
...
ValueError: The fundamental weights do not live in this realization of the root lattice


Beware of the usual $$GL_n$$ vs $$SL_n$$ catch in type $$A$$:

sage: L = RootSystem(["A",3]).ambient_space()
sage: L.fundamental_weights()
Finite family {1: (1, 0, 0, 0), 2: (1, 1, 0, 0), 3: (1, 1, 1, 0)}
sage: L.fundamental_weights_from_simple_roots()
Finite family {1: (3/4, -1/4, -1/4, -1/4), 2: (1/2, 1/2, -1/2, -1/2), 3: (1/4, 1/4, 1/4, -3/4)}

sage: L = RootSystem(["A",3]).ambient_lattice()
sage: L.fundamental_weights_from_simple_roots()
Traceback (most recent call last):
...
ValueError: The fundamental weights do not live in this realization of the root lattice

generalized_nonnesting_partition_lattice(m, facade=False)

Return the lattice of $$m$$-nonnesting partitions

This has been defined by Athanasiadis, see chapter 5 of [Arm06].

INPUT:

• $$m$$ – integer

EXAMPLES:

sage: R = RootSystem(['A', 2])
sage: RS = R.root_lattice()
sage: P = RS.generalized_nonnesting_partition_lattice(2); P
Finite lattice containing 12 elements
sage: P.coxeter_transformation()**20 == 1
True

highest_root()

Returns the highest root (for an irreducible finite root system)

EXAMPLES:

sage: RootSystem(['A',4]).ambient_space().highest_root()
(1, 0, 0, 0, -1)

sage: RootSystem(['E',6]).weight_space().highest_root()
Lambda

index_set()

EXAMPLES:

sage: r = RootSystem(['A',4]).root_space()
sage: r.index_set()
(1, 2, 3, 4)

long_roots()

Return a list of the long roots of self.

EXAMPLES:

sage: L = RootSystem(['B',3]).root_lattice()
sage: sorted(L.long_roots())
[-alpha, -alpha - 2*alpha - 2*alpha,
-alpha - alpha, -alpha - alpha - 2*alpha,
alpha, alpha + alpha,
alpha + alpha + 2*alpha,
alpha + 2*alpha + 2*alpha, -alpha,
-alpha - 2*alpha, alpha, alpha + 2*alpha]

negative_roots()

Returns the negative roots of self.

EXAMPLES:

sage: L = RootSystem(['A', 2]).weight_lattice()
sage: sorted(L.negative_roots())
[-2*Lambda + Lambda, -Lambda - Lambda, Lambda - 2*Lambda]


Algorithm: negate the positive roots

nonnesting_partition_lattice(facade=False)

Return the lattice of nonnesting partitions

This is the lattice of order ideals of the root poset.

This has been defined by Postnikov, see Remark 2 in [Reiner97].

EXAMPLES:

sage: R = RootSystem(['A', 3])
sage: RS = R.root_lattice()
sage: P = RS.nonnesting_partition_lattice(); P
Finite lattice containing 14 elements
sage: P.coxeter_transformation()**10 == 1
True

sage: R = RootSystem(['B', 3])
sage: RS = R.root_lattice()
sage: P = RS.nonnesting_partition_lattice(); P
Finite lattice containing 20 elements
sage: P.coxeter_transformation()**7 == 1
True


REFERENCES:

 [Reiner97] Victor Reiner. Non-crossing partitions for classical reflection groups. Discrete Mathematics 177 (1997)
 [Arm06] Drew Armstrong. Generalized Noncrossing Partitions and Combinatorics of Coxeter Groups. arXiv math/0611106
nonparabolic_positive_root_sum(index_set=None)

Return the sum of positive roots not in a parabolic subsystem.

The conventions for index_set are as in nonparabolic_positive_roots().

EXAMPLES:

sage: Q = RootSystem(['A',3]).root_lattice()
sage: Q.nonparabolic_positive_root_sum((1,2))
alpha + 2*alpha + 3*alpha
sage: Q.nonparabolic_positive_root_sum()
0
sage: Q.nonparabolic_positive_root_sum(())
3*alpha + 4*alpha + 3*alpha

nonparabolic_positive_roots(index_set=None)

Return the positive roots of self that are not in the parabolic subsystem indicated by index_set.

If index_set is None, as in positive_roots() it is assumed to be the entire Dynkin node set. Then the parabolic subsystem consists of all positive roots and the empty list is returned.

EXAMPLES:

sage: L = RootSystem(['A',3]).root_lattice()
sage: L.nonparabolic_positive_roots()
[]
sage: sorted(L.nonparabolic_positive_roots((1,2)))
[alpha + alpha + alpha, alpha + alpha, alpha]
sage: sorted(L.nonparabolic_positive_roots(()))
[alpha, alpha + alpha, alpha + alpha + alpha, alpha, alpha + alpha, alpha]

null_coroot()

Returns the null coroot of self.

The null coroot is the smallest non trivial positive coroot which is orthogonal to all simple roots. It exists for any affine root system.

EXAMPLES:

sage: RootSystem(['C',2,1]).root_lattice().null_coroot()
alphacheck + alphacheck + alphacheck
sage: RootSystem(['D',4,1]).root_lattice().null_coroot()
alphacheck + alphacheck + 2*alphacheck + alphacheck + alphacheck
sage: RootSystem(['F',4,1]).root_lattice().null_coroot()
alphacheck + 2*alphacheck + 3*alphacheck + 2*alphacheck + alphacheck

null_root()

Returns the null root of self. The null root is the smallest non trivial positive root which is orthogonal to all simple coroots. It exists for any affine root system.

EXAMPLES:

sage: RootSystem(['C',2,1]).root_lattice().null_root()
alpha + 2*alpha + alpha
sage: RootSystem(['D',4,1]).root_lattice().null_root()
alpha + alpha + 2*alpha + alpha + alpha
sage: RootSystem(['F',4,1]).root_lattice().null_root()
alpha + 2*alpha + 3*alpha + 4*alpha + 2*alpha

plot(roots='simple', coroots=False, reflection_hyperplanes='simple', fundamental_weights=None, fundamental_chamber=None, alcoves=None, alcove_labels=False, alcove_walk=None, **options)

Return a picture of this root lattice realization.

INPUT:

• roots – which roots to display, if any. Can be one of the following:

• "simple" – The simple roots (the default)
• "classical" – Not yet implemented
• "all" – Only works in the finite case
• A list or tuple of roots
• False
• coroots – which coroots to display, if any. Can be one of the following:

• "simple" – The simple coroots (the default)
• "classical" – Not yet implemented
• "all" – Only works in the finite case
• A list or tuple of coroots
• False
• fundamental_weights – a boolean or None (default: None) whether to display the fundamental weights. If None, the fundamental weights are drawn if available.

• reflection_hyperplanes – which reflection hyperplanes to display, if any. Can be one of the following:

• "simple" – The simple roots
• "classical" – Not yet implemented
• "all" – Only works in the finite case
• A list or tuple of roots
• False (the default)
• fundamental_chamber – whether and how to draw the fundamental chamber. Can be one of the following:

• A boolean – Set to True to draw the fundamental chamber
• "classical" – Draw the classical fundamental chamber
• None – (the default) The fundamental chamber is drawn except in the root lattice where this is not yet implemented. For affine types the classical fundamental chamber is drawn instead.
• alcoves – one of the following (default: True):

• A boolean – Whether to display the alcoves
• A list of alcoves – The alcoves to be drawn. Each alcove is specified by the coordinates of its center in the root lattice (affine type only). Otherwise the alcoves that intersect the bounding box are drawn.
• alcove_labels – one of the following (default: False):

• A boolean – Whether to display the elements of the Weyl group indexing the alcoves. This currently requires to also set the alcoves option.
• A number $$l$$ – The label is drawn at level $$l$$ (affine type only), which only makes sense if affine is False.
• bounding_box – a rational number or a list of pairs thereof (default: 3)

Specifies a bounding box, in the coordinate system for this plot, in which to plot alcoves and other infinite objects. If the bounding box is a number $$a$$, then the bounding box is of the form $$[-a,a]$$ in all directions. Beware that there can be some border effects and the returned graphic is not necessarily strictly contained in the bounding box.

• alcove_walk – an alcove walk or None (default: None)

The alcove walk is described by a list (or iterable) of vertices of the Dynkin diagram which specifies which wall is crossed at each step, starting from the fundamental alcove.

• projection – one of the following (default: True):

• True – The default projection for the root lattice realization is used.
• False – No projection is used.
• barycentric – A barycentric projection is used.
• A function – If a function is specified, it should implement a linear (or affine) map taking as input an element of this root lattice realization and returning its desired coordinates in the plot, as a vector with rational coordinates.
• color – a function mapping vertices of the Dynkin diagram to colors (default: "black" for 0, "blue" for 1, "red" for 2, "green" for 3)

This is used to set the color for the simple roots, fundamental weights, reflection hyperplanes, alcove facets, etc. If the color is None, the object is not drawn.

• labels – a boolean (default: True) whether to display labels on the simple roots, fundamental weights, etc.

EXAMPLES:

sage: L = RootSystem(["A",2,1]).ambient_space().plot()    # long time

plot_alcove_walk(word, start=None, foldings=None, color='orange', **options)

Plot an alcove walk.

INPUT:

• word – a list of elements of the index set
• foldings – a list of booleans or None (default: None)
• start – an element of this space (default: None for $$\rho$$)
• **options – plotting options

EXAMPLES:

An alcove walk of type $$A_2^{(1)}$$:

sage: L = RootSystem(["A",2,1]).ambient_space()
sage: w1 = [0,2,1,2,0,2,1,0,2,1,2,1,2,0,2,0,1,2,0]
sage: p = L.plot_alcoves(bounding_box=5)           # long time (5s)
sage: p += L.plot_alcove_walk(w1)                  # long time
sage: p                                            # long time
Graphics object consisting of 375 graphics primitives


The same plot with another alcove walk:

sage: w2 = [2,1,2,0,2,0,2,1,2,0,1,2,1,2,1,0,1,2,0,2,0,1,2,0,2]
sage: p += L.plot_alcove_walk(w2, color="orange")  # long time


And another with some foldings:

sage: L.plot_alcoves(bounding_box=3) +\
....: L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1],
....:                      foldings = [False, False, True, False, False, False, True, False, True, False],
....:                      color="green")            # long time (3s)
Graphics object consisting of 155 graphics primitives

plot_alcoves(alcoves=True, alcove_labels=False, wireframe=False, **options)

Plot the alcoves and optionaly their labels.

INPUT:

• alcoves – a list of alcoves or True (default: True)
• alcove_labels – a boolean or a number specifying at which level to put the label (default: False)
• **options – Plotting options

EXAMPLES:

2D plots:

sage: RootSystem(["B",2,1]).ambient_space().plot_alcoves()                      # long time (3s)
Graphics object consisting of 228 graphics primitives


3D plots:

sage: RootSystem(["A",2,1]).weight_space() .plot_alcoves(affine=False)          # long time (3s)
Graphics3d Object
sage: RootSystem(["G",2,1]).ambient_space().plot_alcoves(affine=False, level=1) # long time (3s)
Graphics3d Object


Here we plot a single alcove:

sage: L = RootSystem(["A",3,1]).ambient_space()
sage: W = L.weyl_group()
sage: L.plot(alcoves=[W.one()], reflection_hyperplanes=False, bounding_box=2)
Graphics3d Object

plot_bounding_box(**options)

Plot the bounding box.

INPUT:

• **options – Plotting options

This is mostly for testing purposes.

EXAMPLES:

sage: L = RootSystem(["A",2,1]).ambient_space()
sage: L.plot_bounding_box()
Graphics object consisting of 1 graphics primitive

plot_coroots(collection='simple', **options)

Plot the (simple/classical) coroots of this root lattice.

INPUT:

• collection – which coroots to display. Can be one of the following:
• "simple" (the default)
• "classical"
• "all"
• **options – Plotting options

EXAMPLES:

sage: RootSystem(["B",3]).ambient_space().plot_coroots()
Graphics3d Object

plot_crystal(crystal, plot_labels=True, label_color='black', edge_labels=False, circle_size=0.06, circle_thickness=1.6, **options)

Plot a finite crystal.

INPUT:

• crystal – the finite crystal to plot
• plot_labels – (default: True) can be one of the following:
• True - use the latex labels
• 'circles' - use circles for multiplicity up to 4; if the multiplicity is larger, then it uses the multiplicity
• 'multiplicities' - use the multiplicities
• label_color – (default: 'black') the color of the labels
• edge_labels – (default: False) if True, then draw in the edge label
• circle_size – (default: 0.06) the size of the circles
• circle_thickness – (default: 1.6) the thinkness of the extra rings of circles
• **options – plotting options

EXAMPLES:

sage: L = RootSystem(['A',2]).ambient_space()
sage: C = crystals.Tableaux(['A',2], shape=[2,1])
sage: L.plot_crystal(C)
Graphics object consisting of 16 graphics primitives
sage: C = crystals.Tableaux(['A',2], shape=[8,4])
sage: p = L.plot_crystal(C, plot_labels='circles')
sage: p.show(figsize=15)


A 3-dimensional example:

sage: L = RootSystem(['B',3]).ambient_space()
sage: C = crystals.Tableaux(['B',3], shape=[2,1])
sage: L.plot_crystal(C, plot_labels='circles', edge_labels=True) # long time
Graphics3d Object

plot_fundamental_chamber(style='normal', **options)

Plot the (classical) fundamental chamber.

INPUT:

• style"normal" or "classical" (default: "normal")
• **options – Plotting options

EXAMPLES:

2D plots:

sage: RootSystem(["B",2]).ambient_space().plot_fundamental_chamber()
Graphics object consisting of 1 graphics primitive
sage: RootSystem(["B",2,1]).ambient_space().plot_fundamental_chamber()
Graphics object consisting of 1 graphics primitive
sage: RootSystem(["B",2,1]).ambient_space().plot_fundamental_chamber("classical")
Graphics object consisting of 1 graphics primitive


3D plots:

sage: RootSystem(["A",3,1]).weight_space() .plot_fundamental_chamber()
Graphics3d Object
sage: RootSystem(["B",3,1]).ambient_space().plot_fundamental_chamber()
Graphics3d Object


This feature is currently not available in the root lattice/space:

sage: list(RootSystem(["A",2]).root_lattice().plot_fundamental_chamber())
Traceback (most recent call last):
...
TypeError: classical fundamental chamber not yet available in the root lattice

plot_fundamental_weights(**options)

Plot the fundamental weights of this root lattice.

INPUT:

• **options – Plotting options

EXAMPLES:

sage: RootSystem(["B",3]).ambient_space().plot_fundamental_weights()
Graphics3d Object

plot_hedron(**options)

Plot the polyhedron whose vertices are given by the orbit of $$\rho$$.

In type $$A$$, this is the usual permutohedron.

EXAMPLES:

sage: RootSystem(["A",2]).ambient_space().plot_hedron()
Graphics object consisting of 8 graphics primitives
sage: RootSystem(["A",3]).ambient_space().plot_hedron()
Graphics3d Object
sage: RootSystem(["B",3]).ambient_space().plot_hedron()
Graphics3d Object
sage: RootSystem(["C",3]).ambient_space().plot_hedron()
Graphics3d Object
sage: RootSystem(["D",3]).ambient_space().plot_hedron()
Graphics3d Object


Surprise: polyhedra of large dimension know how to project themselves nicely:

sage: RootSystem(["F",4]).ambient_space().plot_hedron() # long time
Graphics3d Object

plot_ls_paths(paths, plot_labels=None, colored_labels=True, **options)

Plot LS paths.

INPUT:

• paths – a finite crystal or list of LS paths
• plot_labels – (default: None) the distance to plot the LS labels from the endpoint of the path; set to None to not display the labels
• colored_labels – (default: True) if True, then color the labels the same color as the LS path
• **options – plotting options

EXAMPLES:

sage: B = crystals.LSPaths(['A',2], [1,1])
sage: L = RootSystem(['A',2]).ambient_space()
sage: L.plot_fundamental_weights() + L.plot_ls_paths(B)
Graphics object consisting of 14 graphics primitives


This also works in 3 dimensions:

sage: B = crystals.LSPaths(['B',3], [2,0,0])
sage: L = RootSystem(['B',3]).ambient_space()
sage: L.plot_ls_paths(B)
Graphics3d Object

plot_mv_polytope(mv_polytope, mark_endpoints=True, circle_size=0.06, circle_thickness=1.6, wireframe='blue', fill='green', alpha=1, **options)

Plot an MV polytope.

INPUT:

• mv_polytope – an MV polytope
• mark_endpoints – (default: True) mark the endpoints of the MV polytope
• circle_size – (default: 0.06) the size of the circles
• circle_thickness – (default: 1.6) the thinkness of the extra rings of circles
• wireframe – (default: 'blue') color to draw the wireframe of the polytope with
• fill – (default: 'green') color to fill the polytope with
• alpha – (default: 1) the alpha value (opacity) of the fill
• **options – plotting options

EXAMPLES:

sage: B = crystals.infinity.MVPolytopes(['C',2])
sage: L = RootSystem(['C',2]).ambient_space()
sage: p = B.highest_weight_vector().f_string([1,2,1,2])
sage: L.plot_fundamental_weights() + L.plot_mv_polytope(p)
Graphics object consisting of 14 graphics primitives


This also works in 3 dimensions:

sage: B = crystals.infinity.MVPolytopes(['A',3])
sage: L = RootSystem(['A',3]).ambient_space()
sage: p = B.highest_weight_vector().f_string([2,1,3,2])
sage: L.plot_mv_polytope(p)
Graphics3d Object

plot_parse_options(**args)

Return an option object to be used for root system plotting.

EXAMPLES:

sage: L = RootSystem(["A",2,1]).ambient_space()
sage: options = L.plot_parse_options()
sage: options
<sage.combinat.root_system.plot.PlotOptions object at ...>


plot_reflection_hyperplanes(collection='simple', **options)

Plot the simple reflection hyperplanes.

INPUT:

• collection – which reflection hyperplanes to display. Can be one of the following:
• "simple" (the default)
• "classical"
• "all"
• **options – Plotting options

EXAMPLES:

sage: RootSystem(["A",2,1]).ambient_space().plot_reflection_hyperplanes()
Graphics object consisting of 6 graphics primitives
sage: RootSystem(["G",2,1]).ambient_space().plot_reflection_hyperplanes()
Graphics object consisting of 6 graphics primitives
sage: RootSystem(["A",3]).weight_space().plot_reflection_hyperplanes()
Graphics3d Object
sage: RootSystem(["B",3]).ambient_space().plot_reflection_hyperplanes()
Graphics3d Object
sage: RootSystem(["A",3,1]).weight_space().plot_reflection_hyperplanes()
Graphics3d Object
sage: RootSystem(["B",3,1]).ambient_space().plot_reflection_hyperplanes()
Graphics3d Object
sage: RootSystem(["A",2,1]).weight_space().plot_reflection_hyperplanes(affine=False, level=1)
Graphics3d Object
sage: RootSystem(["A",2]).root_lattice().plot_reflection_hyperplanes()
Graphics object consisting of 4 graphics primitives


Todo

Provide an option for transparency?

plot_roots(collection='simple', **options)

Plot the (simple/classical) roots of this root lattice.

INPUT:

• collection – which roots to display can be one of the following:
• "simple" (the default)
• "classical"
• "all"
• **options – Plotting options

EXAMPLES:

sage: RootSystem(["B",3]).ambient_space().plot_roots()
Graphics3d Object
sage: RootSystem(["B",3]).ambient_space().plot_roots("all")
Graphics3d Object

positive_imaginary_roots()

Return the positive imaginary roots of self.

EXAMPLES:

sage: L = RootSystem(['A',3]).root_lattice()
sage: L.positive_imaginary_roots()
()

sage: L = RootSystem(['A',3,1]).root_lattice()
sage: PIR = L.positive_imaginary_roots(); PIR
Positive imaginary roots of type ['A', 3, 1]
sage: [PIR.unrank(i) for i in range(5)]
[alpha + alpha + alpha + alpha,
2*alpha + 2*alpha + 2*alpha + 2*alpha,
3*alpha + 3*alpha + 3*alpha + 3*alpha,
4*alpha + 4*alpha + 4*alpha + 4*alpha,
5*alpha + 5*alpha + 5*alpha + 5*alpha]

positive_real_roots()

Return the positive real roots of self.

EXAMPLES:

sage: L = RootSystem(['A',3]).root_lattice()
sage: sorted(L.positive_real_roots())
[alpha, alpha + alpha, alpha + alpha + alpha,
alpha, alpha + alpha, alpha]

sage: L = RootSystem(['A',3,1]).root_lattice()
sage: PRR = L.positive_real_roots(); PRR
Positive real roots of type ['A', 3, 1]
sage: [PRR.unrank(i) for i in range(10)]
[alpha,
alpha,
alpha,
alpha + alpha,
alpha + alpha,
alpha + alpha + alpha,
alpha + 2*alpha + alpha + alpha,
alpha + alpha + 2*alpha + alpha,
alpha + alpha + alpha + 2*alpha,
alpha + 2*alpha + 2*alpha + alpha]

sage: Q = RootSystem(['A',4,2]).root_lattice()
sage: PR = Q.positive_roots()
sage: [PR.unrank(i) for i in range(5)]
[alpha,
alpha,
alpha + alpha,
2*alpha + alpha,
alpha + alpha + alpha]

sage: Q = RootSystem(['D',3,2]).root_lattice()
sage: PR = Q.positive_roots()
sage: [PR.unrank(i) for i in range(5)]
[alpha,
alpha,
alpha + 2*alpha,
alpha + alpha,
alpha + alpha + 2*alpha]

positive_roots(index_set=None)

Return the positive roots of self.

If index_set is not None, returns the positive roots of the parabolic subsystem with simple roots in index_set.

Algorithm for finite type: generate them from the simple roots by applying successive reflections toward the positive chamber.

EXAMPLES:

sage: L = RootSystem(['A',3]).root_lattice()
sage: sorted(L.positive_roots())
[alpha, alpha + alpha,
alpha + alpha + alpha, alpha,
alpha + alpha, alpha]
sage: sorted(L.positive_roots((1,2)))
[alpha, alpha + alpha, alpha]
sage: sorted(L.positive_roots(()))
[]

sage: L = RootSystem(['A',3,1]).root_lattice()
sage: PR = L.positive_roots(); PR
Disjoint union of Family (Positive real roots of type ['A', 3, 1],
Positive imaginary roots of type ['A', 3, 1])
sage: [PR.unrank(i) for i in range(10)]
[alpha,
alpha,
alpha,
alpha + alpha,
alpha + alpha,
alpha + alpha + alpha,
alpha + 2*alpha + alpha + alpha,
alpha + alpha + 2*alpha + alpha,
alpha + alpha + alpha + 2*alpha,
alpha + 2*alpha + 2*alpha + alpha]

positive_roots_by_height(increasing=True)

Returns a list of positive roots in increasing order by height.

If increasing is False, returns them in decreasing order.

Warning

Raise an error if the Cartan type is not finite.

EXAMPLES:

sage: L = RootSystem(['C',2]).root_lattice()
sage: L.positive_roots_by_height()
[alpha, alpha, alpha + alpha, 2*alpha + alpha]
sage: L.positive_roots_by_height(increasing = False)
[2*alpha + alpha, alpha + alpha, alpha, alpha]

sage: L = RootSystem(['A',2,1]).root_lattice()
sage: L.positive_roots_by_height()
Traceback (most recent call last):
...
NotImplementedError: Only implemented for finite Cartan type

positive_roots_nonparabolic(index_set=None)

Returns the set of positive roots outside the parabolic subsystem with Dynkin node set index_set.

INPUT:

• index_set – (default:None) the Dynkin node set of the parabolic subsystem. It should be a tuple. The default value implies the entire Dynkin node set

EXAMPLES:

sage: lattice =  RootSystem(['A',3]).root_lattice()
sage: sorted(lattice.positive_roots_nonparabolic((1,3)), key=str)
[alpha + alpha, alpha + alpha + alpha, alpha, alpha + alpha]
sage: sorted(lattice.positive_roots_nonparabolic((2,3)), key=str)
[alpha, alpha + alpha, alpha + alpha + alpha]
sage: lattice.positive_roots_nonparabolic()
[]
sage: lattice.positive_roots_nonparabolic((1,2,3))
[]


Warning

This returns an error if the Cartan type is not finite.

positive_roots_nonparabolic_sum(index_set=None)

Returns the sum of positive roots outside the parabolic subsystem with Dynkin node set index_set.

INPUT:

• index_set – (default:None) the Dynkin node set of the parabolic subsystem. It should be a tuple. The default value implies the entire Dynkin node set

EXAMPLES:

sage: lattice =  RootSystem(['A',3]).root_lattice()
sage: lattice.positive_roots_nonparabolic_sum((1,3))
2*alpha + 4*alpha + 2*alpha
sage: lattice.positive_roots_nonparabolic_sum((2,3))
3*alpha + 2*alpha + alpha
sage: lattice.positive_roots_nonparabolic_sum(())
3*alpha + 4*alpha + 3*alpha
sage: lattice.positive_roots_nonparabolic_sum()
0
sage: lattice.positive_roots_nonparabolic_sum((1,2,3))
0


Warning

This returns an error if the Cartan type is not finite.

positive_roots_parabolic(index_set=None)

Return the set of positive roots for the parabolic subsystem with Dynkin node set index_set.

INPUT:

• index_set – (default:None) the Dynkin node set of the parabolic subsystem. It should be a tuple. The default value implies the entire Dynkin node set

EXAMPLES:

sage: lattice =  RootSystem(['A',3]).root_lattice()
sage: sorted(lattice.positive_roots_parabolic((1,3)), key=str)
[alpha, alpha]
sage: sorted(lattice.positive_roots_parabolic((2,3)), key=str)
[alpha, alpha + alpha, alpha]
sage: sorted(lattice.positive_roots_parabolic(), key=str)
[alpha, alpha + alpha, alpha + alpha + alpha, alpha, alpha + alpha, alpha]


Warning

This returns an error if the Cartan type is not finite.

projection(root, coroot=None, to_negative=True)

Returns the projection along the root, and across the hyperplane define by coroot, as a function $$\pi$$ from self to self. $$\pi$$ is a half-linear map which stabilizes the negative half space, and acts by reflection on the positive half space.

If to_negative is False, then this project onto the positive half space instead.

EXAMPLES:

sage: space = RootSystem(['A',2]).weight_lattice()
sage: x=space.simple_roots()
sage: y=space.simple_coroots()
sage: pi = space.projection(x,y)
sage: x
2*Lambda - Lambda
sage: pi(x)
-2*Lambda + Lambda
sage: pi(-x)
-2*Lambda + Lambda
sage: pi = space.projection(x,y,False)
sage: pi(-x)
2*Lambda - Lambda

reflection(root, coroot=None)

Returns the reflection along the root, and across the hyperplane define by coroot, as a function from self to self.

EXAMPLES:

sage: space = RootSystem(['A',2]).weight_lattice()
sage: x=space.simple_roots()
sage: y=space.simple_coroots()
sage: s = space.reflection(x,y)
sage: x
2*Lambda - Lambda
sage: s(x)
-2*Lambda + Lambda
sage: s(-x)
2*Lambda - Lambda

root_poset(restricted=False, facade=False)

Returns the (restricted) root poset associated to self.

The elements are given by the positive roots (resp. non-simple, positive roots), and $$\alpha \leq \beta$$ iff $$\beta - \alpha$$ is a non-negative linear combination of simple roots.

INPUT:

• restricted – (default:False) if True, only non-simple roots are considered.
• facade – (default:False) passes facade option to the poset generator.

EXAMPLES:

sage: Phi = RootSystem(['A',1]).root_poset(); Phi
Finite poset containing 1 elements
sage: Phi.cover_relations()
[]

sage: Phi = RootSystem(['A',2]).root_poset(); Phi
Finite poset containing 3 elements

sage: sorted(Phi.cover_relations(), key=str)
[[alpha, alpha + alpha], [alpha, alpha + alpha]]

sage: Phi = RootSystem(['A',3]).root_poset(restricted=True); Phi
Finite poset containing 3 elements
sage: sorted(Phi.cover_relations(), key=str)
[[alpha + alpha, alpha + alpha + alpha], [alpha + alpha, alpha + alpha + alpha]]

sage: Phi = RootSystem(['B',2]).root_poset(); Phi
Finite poset containing 4 elements
sage: sorted(Phi.cover_relations(), key=str)
[[alpha + alpha, alpha + 2*alpha],
[alpha, alpha + alpha],
[alpha, alpha + alpha]]

roots()

Return the roots of self.

EXAMPLES:

sage: RootSystem(['A',2]).ambient_lattice().roots()
[(1, -1, 0), (1, 0, -1), (0, 1, -1), (-1, 1, 0), (-1, 0, 1), (0, -1, 1)]


This matches with Wikipedia article Root_systems:

sage: for T in CartanType.samples(finite = True, crystallographic = True):
....:     print("%s %3s %3s"%(T, len(RootSystem(T).root_lattice().roots()), len(RootSystem(T).weight_lattice().roots())))
['A', 1]   2   2
['A', 5]  30  30
['B', 1]   2   2
['B', 5]  50  50
['C', 1]   2   2
['C', 5]  50  50
['D', 2]   4   4
['D', 3]  12  12
['D', 5]  40  40
['E', 6]  72  72
['E', 7] 126 126
['E', 8] 240 240
['F', 4]  48  48
['G', 2]  12  12


Todo

The result should be an enumerated set, and handle infinite root systems.

s()

Return the family $$(s_i)_{i\in I}$$ of the simple reflections of this root system.

EXAMPLES:

sage: r = RootSystem(["A", 2]).root_lattice()
sage: s = r.simple_reflections()
sage: s( r.simple_root(1) )
-alpha

short_roots()

Return a list of the short roots of self.

EXAMPLES:

sage: L = RootSystem(['B',3]).root_lattice()
sage: sorted(L.short_roots())
[-alpha - alpha - alpha,
alpha + alpha + alpha,
-alpha - alpha,
alpha + alpha,
-alpha,
alpha]

simple_coroot(i)

Returns the $$i^{th}$$ simple coroot.

EXAMPLES:

sage: RootSystem(['A',2]).root_lattice().simple_coroot(1)
alphacheck

simple_coroots()

Returns the family $$( \alpha^\vee_i)_{i\in I}$$ of the simple coroots.

EXAMPLES:

sage: alphacheck = RootSystem(['A',3]).root_lattice().simple_coroots()
sage: [alphacheck[i] for i in [1, 2, 3]]
[alphacheck, alphacheck, alphacheck]

simple_projection(i, to_negative=True)

Returns the projection along the $$i^{th}$$ simple root, and across the hyperplane define by the $$i^{th}$$ simple coroot, as a function from self to self.

INPUT:

• i - i is in self’s index set

EXAMPLES:

sage: space = RootSystem(['A',2]).weight_lattice()
sage: x = space.simple_roots()
sage: pi = space.simple_projection(1)
sage: x
2*Lambda - Lambda
sage: pi(x)
-2*Lambda + Lambda
sage: pi(-x)
-2*Lambda + Lambda
sage: pi = space.simple_projection(1,False)
sage: pi(-x)
2*Lambda - Lambda

simple_projections(to_negative=True)

Returns the family $$(s_i)_{i\in I}$$ of the simple projections of this root system

EXAMPLES:

sage: space = RootSystem(['A',2]).weight_lattice()
sage: pi = space.simple_projections()
sage: x = space.simple_roots()
sage: pi(x)
-Lambda + 2*Lambda

simple_reflection(i)

Returns the $$i^{th}$$ simple reflection, as a function from self to self.

INPUT:

• i - i is in self’s index set

EXAMPLES:

sage: space = RootSystem(['A',2]).ambient_lattice()
sage: s = space.simple_reflection(1)
sage: x = space.simple_roots()
sage: x
(1, -1, 0)
sage: s(x)
(-1, 1, 0)

simple_reflections()

Return the family $$(s_i)_{i\in I}$$ of the simple reflections of this root system.

EXAMPLES:

sage: r = RootSystem(["A", 2]).root_lattice()
sage: s = r.simple_reflections()
sage: s( r.simple_root(1) )
-alpha

simple_root(i)

Returns the $$i^{th}$$ simple root.

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

EXAMPLES:

sage: r = RootSystem(["A",3]).root_lattice()
sage: r.simple_root(1)
alpha

simple_roots()

Returns the family $$(\alpha_i)_{i\in I}$$ of the simple roots.

EXAMPLES:

sage: alpha = RootSystem(["A",3]).root_lattice().simple_roots()
sage: [alpha[i] for i in [1,2,3]]
[alpha, alpha, alpha]

simple_roots_tilde()

Return the family $$(\tilde\alpha_i)_{i\in I}$$ of the simple roots.

INPUT:

• self – an affine root lattice realization

The $$\tilde \alpha_i$$ give the embedding of the root lattice of the other affinization of the same classical root lattice into this root lattice (space?).

This uses the fact that $$\alpha_i = \tilde \alpha_i$$ for $$i$$ not a special node, and that

$\delta = \sum a_i \alpha_i = \sum b_i \tilde \alpha_i$

EXAMPLES:

In simply laced cases, this is boring:

sage: RootSystem(["A",3, 1]).root_lattice().simple_roots_tilde()
Finite family {0: alpha, 1: alpha, 2: alpha, 3: alpha}


This was checked by hand:

sage: RootSystem(["C",2,1]).coroot_lattice().simple_roots_tilde()
Finite family {0: alphacheck - alphacheck, 1: alphacheck, 2: alphacheck}
sage: RootSystem(["B",2,1]).coroot_lattice().simple_roots_tilde()
Finite family {0: alphacheck - alphacheck, 1: alphacheck, 2: alphacheck}


some_elements()

Return some elements of this root lattice realization

EXAMPLES:

sage: L = RootSystem(["A",2]).weight_lattice()
sage: L.some_elements()
[2*Lambda + 2*Lambda, 2*Lambda - Lambda, -Lambda + 2*Lambda, Lambda, Lambda]
sage: L = RootSystem(["A",2]).root_lattice()
sage: L.some_elements()
[2*alpha + 2*alpha, alpha, alpha]

tau_epsilon_operator_on_almost_positive_roots(J)

The $$\tau_\epsilon$$ operator on almost positive roots

Given a subset $$J$$ of non adjacent vertices of the Dynkin diagram, this constructs the operator on the almost positive roots which fixes the negative simple roots $$\alpha_i$$ for $$i$$ not in $$J$$, and acts otherwise by:

$\tau_+( \beta ) = (\prod_{i \in J} s_i) (\beta)$

See Equation (1.2) of [CFZ2002].

EXAMPLES:

sage: L = RootSystem(['A',4]).root_lattice()
sage: tau = L.tau_epsilon_operator_on_almost_positive_roots([1,3])
sage: alpha = L.simple_roots()


The action on a negative simple root not in $$J$$:

sage: tau(-alpha)
-alpha


The action on a negative simple root in $$J$$:

sage: tau(-alpha)
alpha


The action on all almost positive roots:

sage: for root in L.almost_positive_roots():
....:     print('tau({:<41}) = {}'.format(str(root), tau(root)))
tau(-alpha                                ) = alpha
tau(alpha                                 ) = -alpha
tau(alpha + alpha                      ) = alpha + alpha
tau(alpha + alpha + alpha           ) = alpha
tau(alpha + alpha + alpha + alpha) = alpha + alpha + alpha
tau(-alpha                                ) = -alpha
tau(alpha                                 ) = alpha + alpha + alpha
tau(alpha + alpha                      ) = alpha + alpha
tau(alpha + alpha + alpha           ) = alpha + alpha + alpha + alpha
tau(-alpha                                ) = alpha
tau(alpha                                 ) = -alpha
tau(alpha + alpha                      ) = alpha
tau(-alpha                                ) = -alpha
tau(alpha                                 ) = alpha + alpha


This method works on any root lattice realization:

sage: L = RootSystem(['B',3]).ambient_space()
sage: tau = L.tau_epsilon_operator_on_almost_positive_roots([1,3])
sage: for root in L.almost_positive_roots():
....:     print('tau({:<41}) = {}'.format(str(root), tau(root)))
tau((-1, 1, 0)                               ) = (1, -1, 0)
tau((1, 0, 0)                                ) = (0, 1, 0)
tau((1, -1, 0)                               ) = (-1, 1, 0)
tau((1, 1, 0)                                ) = (1, 1, 0)
tau((1, 0, -1)                               ) = (0, 1, 1)
tau((1, 0, 1)                                ) = (0, 1, -1)
tau((0, -1, 1)                               ) = (0, -1, 1)
tau((0, 1, 0)                                ) = (1, 0, 0)
tau((0, 1, -1)                               ) = (1, 0, 1)
tau((0, 1, 1)                                ) = (1, 0, -1)
tau((0, 0, -1)                               ) = (0, 0, 1)
tau((0, 0, 1)                                ) = (0, 0, -1)

tau_plus_minus()

Returns the $$\tau^+$$ and $$\tau^-$$ piecewise linear operators on self

Those operators are induced by the bipartition $$\{L,R\}$$ of the simple roots of self, and stabilize the almost positive roots. Namely, $$\tau_+$$ fixes the negative simple roots $$\alpha_i$$ for $$i$$ in $$R$$, and acts otherwise by:

$\tau_+( \beta ) = (\prod_{i \in L} s_i) (\beta)$

$$\tau_-$$ acts analogously, with $$L$$ and $$R$$ interchanged.

Those operators are used to construct the associahedron, a polytopal realization of the cluster complex (see Associahedron).

EXAMPLES:

We explore the example of [CFZ2002] Eq.(1.3):

sage: S = RootSystem(['A',2]).root_lattice()
sage: taup, taum = S.tau_plus_minus()
sage: for beta in S.almost_positive_roots(): print("{} , {} , {}".format(beta, taup(beta), taum(beta)))
-alpha , alpha , -alpha
alpha , -alpha , alpha + alpha
alpha + alpha , alpha , alpha
-alpha , -alpha , alpha
alpha , alpha + alpha , -alpha

to_ambient_space_morphism()

Return the morphism to the ambient space.

EXAMPLES:

sage: CartanType(['B',2]).root_system().root_lattice().to_ambient_space_morphism()
Generic morphism:
From: Root lattice of the Root system of type ['B', 2]
To:   Ambient space of the Root system of type ['B', 2]
sage: CartanType(['B',2]).root_system().coroot_lattice().to_ambient_space_morphism()
Generic morphism:
From: Coroot lattice of the Root system of type ['B', 2]
To:   Ambient space of the Root system of type ['B', 2]
sage: CartanType(['B',2]).root_system().weight_lattice().to_ambient_space_morphism()
Generic morphism:
From: Weight lattice of the Root system of type ['B', 2]
To:   Ambient space of the Root system of type ['B', 2]

weyl_group(prefix=None)

Returns the Weyl group associated to self.

EXAMPLES:

sage: RootSystem(['F',4]).ambient_space().weyl_group()
Weyl Group of type ['F', 4] (as a matrix group acting on the ambient space)
sage: RootSystem(['F',4]).root_space().weyl_group()
Weyl Group of type ['F', 4] (as a matrix group acting on the root space)

super_categories()

EXAMPLES:

sage: from sage.combinat.root_system.root_lattice_realizations import RootLatticeRealizations
sage: RootLatticeRealizations(QQ).super_categories()
[Category of vector spaces with basis over Rational Field]