Bases: sage.categories.category_types.Category_over_base_ring
The category of root lattice realizations over a given base ring
A root 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.
Typical root lattice realizations over include the root
lattice, weight lattice, and ambient lattice. Typical root lattice
realizations over
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 in the index set the image of the simple root
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 , and embed the root
lattice element
in several root lattice
realizations:
sage: R = RootSystem(["A",7])
sage: alpha = R.root_lattice().simple_roots()
sage: x = alpha[2] + 2 * alpha[5]
sage: L = R.root_space()
sage: L(x)
alpha[2] + 2*alpha[5]
sage: L = R.weight_lattice()
sage: L(x)
-Lambda[1] + 2*Lambda[2] - Lambda[3] - 2*Lambda[4] + 4*Lambda[5] - 2*Lambda[6]
sage: L = R.ambient_space()
sage: L(x)
(0, 1, -1, 0, 2, -2, 0, 0)
We embed the root space element in
several root lattice realizations:
sage: alpha = R.root_space().simple_roots()
sage: x = alpha[2] + 1/2 * alpha[5]
sage: L = R.weight_space()
sage: L(x)
-Lambda[1] + 2*Lambda[2] - Lambda[3] - 1/2*Lambda[4] + Lambda[5] - 1/2*Lambda[6]
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[2] + 1/2*alpha[5]) an element of self (=Weight lattice of the Root system of type ['A', 7])
If is a subring of
, then one could in theory have
an embedding from the root space over
to any root
lattice realization over
; 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[1])
2*Lambda[1] - Lambda[2]
sage: alpha = R.root_space(K1).simple_roots()
sage: L(alpha[1])
Traceback (most recent call last):
...
TypeError: do not know how to make x (= alpha[1]) 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
TESTS:
sage: TestSuite(L).run()
Returns the coroot associated to this root
EXAMPLES:
sage: alpha = RootSystem(["A", 3]).root_space().simple_roots()
sage: alpha[1].associated_coroot()
alphacheck[1]
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,)
Returns the descents of pt
EXAMPLES:
sage: space=RootSystem(['A',5]).weight_space()
sage: alpha=space.simple_roots()
sage: (alpha[1]+alpha[2]+alpha[4]).descents()
[3, 5]
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[1]+alpha[2]+alpha[4]).first_descent()
3
sage: (alpha[1]+alpha[2]+alpha[4]).first_descent([1,2,5])
5
sage: (alpha[1]+alpha[2]+alpha[4]).first_descent([1,2,5,3,4])
5
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[2].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]
Test if self has a descent at position , that is if self is
on the strict negative side of the
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[1]+alpha[2]+alpha[4]).has_descent(3)
True
sage: (alpha[1]+alpha[2]+alpha[4]).has_descent(1)
False
sage: (alpha[1]+alpha[2]+alpha[4]).has_descent(1, True)
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[1]-Lambda[2]).is_dominant()
False
sage: (-Lambda[1]+Lambda[2]).is_dominant()
False
sage: (Lambda[1]-Lambda[2]).is_dominant([1])
True
sage: (Lambda[1]-Lambda[2]).is_dominant([2])
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]
Tests 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[1]+Lambda[2]).is_dominant()
True
sage: (Lambda[1]-Lambda[2]).is_dominant()
False
sage: (-Lambda[1]+Lambda[2]).is_dominant()
False
Warning
The current implementation tests that the scalar products
with the coroots are all non negative integers, which is not
sufficient. For example, if is the sum of a dominant
element of the weight lattice plus some other element
orthogonal to all coroots, then the current implementation
erroneously reports
to be a dominant weight:
sage: x = Lambda[1] + L([-1,-1,-1])
sage: x.is_dominant_weight()
True
Return True if self is an imaginary root.
A root is imaginary if it is not
conjugate
to a simple root where
is the corresponding Weyl group.
EXAMPLES:
sage: Q = RootSystem(['B',2,1]).root_lattice()
sage: alpha = Q.simple_roots()
sage: alpha[0].is_imaginary_root()
False
sage: elt = alpha[0] + alpha[1] + 2*alpha[2]
sage: elt.is_imaginary_root()
True
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[0].is_long_root()
True
sage: alpha[1].is_long_root()
True
sage: alpha[2].is_long_root()
False
Supposing that self is a root, is it in the parabolic subsystem with Dynkin nodes index_set?
INPUT:
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([2])
False
Return True if self is a real root.
A root is real if it is
conjugate to a simple
root where
is the corresponding Weyl group.
EXAMPLES:
sage: Q = RootSystem(['B',2,1]).root_lattice()
sage: alpha = Q.simple_roots()
sage: alpha[0].is_real_root()
True
sage: elt = alpha[0] + alpha[1] + 2*alpha[2]
sage: elt.is_real_root()
False
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[1] + alpha[2]
sage: al.is_short_root()
True
sage: bt = Q.simple_root(2).weyl_action([2,1,2]); bt
-2*alpha[1] - alpha[2]
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[0].is_short_root()
False
sage: alpha[1].is_short_root()
False
sage: alpha[2].is_short_root()
True
EXAMPLES:
sage: L = RootSystem(['A',2,1]).weight_lattice()
sage: L.rho().level()
3
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[1].norm_squared()
4
sage: alpha[2].norm_squared()
2
sage: elt = alpha[0] - 3*alpha[1] + alpha[2]
sage: elt.norm_squared()
50
sage: elt = alpha[0] + alpha[1] + 2*alpha[2]
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[0] + 2*alpha[1] + 2*alpha[2]
sage: eltc = alphac[0] + 2*alphac[1] + 2*alphac[2]
sage: elt.norm_squared()
0
sage: eltc.norm_squared()
0
The orbit of self under the action of the Weyl group
EXAMPLES:
is a regular element whose orbit is in bijection with the Weyl group.
In particular, it as 6 elements for the symmetric group
:
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()[1].orbit())
4
sage: len(L.fundamental_weights()[2].orbit())
6
Return the immediate predecessors of self for the weak order.
INPUT:
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[1].pred()
[]
sage: L.rho().pred()
[]
sage: (-L.rho()).pred()
[Lambda[1] - 2*Lambda[2] - Lambda[3], -2*Lambda[1] + Lambda[2] - 2*Lambda[3], -Lambda[1] - 2*Lambda[2] + Lambda[3]]
sage: (-L.rho()).pred(index_set=[1])
[Lambda[1] - 2*Lambda[2] - Lambda[3]]
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[1].reduced_word()
[2, 3, 4, 5]
sage: alpha[1].reduced_word([1,2])
[2]
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[2] - 5*Lambda[3] + 2*Lambda[4]
sage: root_lattice = R.root_lattice()
sage: beta = root_lattice.from_vector(vector([0,1,1,0]))
sage: mu.reflection(beta)
Lambda[1] - Lambda[2] + 3*Lambda[4]
Implement the natural pairing with the coroot lattice.
INPUT:
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[1].scalar(alphacheck[1])
2
sage: alpha[1].scalar(alphacheck[2])
-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]
TESTS:
sage: super(sage.combinat.root_system.root_space.RootSpaceElement,alpha[1]).scalar(alphacheck[1])
Traceback (most recent call last):
...
NotImplementedError: <abstract method scalar at ...>
Returns the image of self by the -th simple reflection.
EXAMPLES:
sage: alpha = RootSystem(["A", 3]).root_lattice().alpha()
sage: alpha[1].simple_reflection(2)
alpha[1] + alpha[2]
sage: Q = RootSystem(['A', 3, 1]).weight_lattice(extended = True)
sage: Lambda = Q.fundamental_weights()
sage: L = Lambda[0] + Q.null_root()
sage: L.simple_reflection(0)
-Lambda[0] + Lambda[1] + Lambda[3]
The images of self by all the simple reflections
EXAMPLES:
sage: alpha = RootSystem(["A", 3]).root_lattice().alpha()
sage: alpha[1].simple_reflections()
[-alpha[1], alpha[1] + alpha[2], alpha[1]]
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[2].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]
Return the immediate successors of self for the weak order.
INPUT:
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[1].succ()
[-Lambda[1] + Lambda[2]]
sage: L.rho().succ()
[-Lambda[1] + 2*Lambda[2] + Lambda[3], 2*Lambda[1] - Lambda[2] + 2*Lambda[3], Lambda[1] + 2*Lambda[2] - Lambda[3]]
sage: (-L.rho()).succ()
[]
sage: L.rho().succ(index_set=[1])
[-Lambda[1] + 2*Lambda[2] + Lambda[3]]
sage: L.rho().succ(index_set=[2])
[2*Lambda[1] - Lambda[2] + 2*Lambda[3]]
Return the symmetric form of self with alpha.
Consider the simple roots and let
denote the symmetrized Cartan matrix
, we have
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[1].symmetric_form(alpha[0])
0
sage: alpha[1].symmetric_form(alpha[1])
4
sage: elt = alpha[0] - 3*alpha[1] + alpha[2]
sage: elt.symmetric_form(alpha[1])
-14
sage: elt.symmetric_form(alpha[0]+2*alpha[2])
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[0] + 2*alpha[1] + 2*alpha[2]
sage: eltc = alphac[0] + 2*alphac[1] + 2*alphac[2]
sage: elt.symmetric_form(alpha[1])
0
sage: eltc.symmetric_form(alphac[1])
0
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[1].to_dominant_chamber()
Lambda[1] + Lambda[5]
sage: alpha[1].to_dominant_chamber([1,2])
Lambda[1] + Lambda[2] - Lambda[3]
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[1] - Lambda[2] - 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[1] is not in the orbit of the fundamental chamber
sage: mu.to_dominant_chamber(positive=False)
Traceback (most recent call last):
...
ValueError: alpha[1] is not in the orbit of the negative of the fundamental chamber
Return (the index of) a simple root in the orbit of the positive root self.
INPUT:
OUTPUT:
EXAMPLES:
sage: L = RootSystem(["A",3]).root_lattice()
sage: positive_roots = L.positive_roots()
sage: for alpha in positive_roots:
... print alpha, alpha.to_simple_root()
alpha[1] 1
alpha[2] 2
alpha[3] 3
alpha[1] + alpha[2] 2
alpha[2] + alpha[3] 3
alpha[1] + alpha[2] + alpha[3] 3
sage: for alpha in positive_roots:
... print alpha, alpha.to_simple_root(reduced_word=True)
alpha[1] (1, ())
alpha[2] (2, ())
alpha[3] (3, ())
alpha[1] + alpha[2] (2, (1,))
alpha[2] + alpha[3] (3, (2,))
alpha[1] + alpha[2] + alpha[3] (3, (1, 2))
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 .
See also
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[1]).to_simple_root()
Traceback (most recent call last):
...
ValueError: -2*alpha[1] - 2*alpha[2] - 2*alpha[3] is not a positive root
For an infinite root systems, this method may run into an infinite reccursion if the input is not a positive root.
Returns translated by
, that is
EXAMPLES:
sage: L = RootSystem(['A',2,1]).weight_lattice()
sage: alpha = L.simple_roots()
sage: Lambda = L.fundamental_weights()
sage: t = alpha[2]
Let us look at the translation of an element of level :
sage: Lambda[1].level()
1
sage: t.translation(Lambda[1])
-Lambda[0] + 2*Lambda[2]
sage: Lambda[1] + t
-Lambda[0] + 2*Lambda[2]
and of an element of level :
sage: alpha [1].level()
0
sage: t.translation(alpha [1])
-Lambda[0] + 2*Lambda[1] - Lambda[2]
sage: alpha[1] + 0*t
-Lambda[0] + 2*Lambda[1] - Lambda[2]
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[1])
-Lambda[0] + 2*Lambda[2]
Acts on self by an element of the Coxeter or Weyl group.
INPUT:
EXAMPLES:
sage: wl = RootSystem(['A',3]).weight_lattice()
sage: mu = wl.from_vector(vector([1,0,-2]))
sage: mu
Lambda[1] - 2*Lambda[3]
sage: mudom, rw = mu.to_dominant_chamber(positive=False, reduced_word = True)
sage: mudom, rw
(-Lambda[2] - Lambda[3], [1, 2])
Acting by a (reduced) word:
sage: mudom.weyl_action(rw)
Lambda[1] - 2*Lambda[3]
sage: mu.weyl_action(rw, inverse = True)
-Lambda[2] - Lambda[3]
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[1] - 2*Lambda[3]
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[1] - 2*Lambda[3]
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])
[3]
Returns a long simple root, corresponding to the highest outgoing edge in the Dynkin diagram.
Caveat: this may be break in affine type
Caveat: meaningful/broken for non irreducible?
TODO: implement CartanType.nodes_by_length as in MuPAD-Combinat (using CartanType.symmetrizer), and use it here.
TESTS:
sage: X=RootSystem(['A',1]).weight_space()
sage: X.a_long_simple_root()
2*Lambda[1]
sage: X=RootSystem(['A',5]).weight_space()
sage: X.a_long_simple_root()
2*Lambda[1] - Lambda[2]
Returns the almost positive roots of self
These are the positive roots together with the simple negative roots.
See also
almost_positive_root_decomposition(), tau_plus_minus()
EXAMPLES:
sage: L = RootSystem(['A',2]).root_lattice()
sage: L.almost_positive_roots()
[-alpha[1], alpha[1], alpha[1] + alpha[2], -alpha[2], alpha[2]]
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 and
.
See also
EXAMPLES:
sage: RootSystem(['A',2]).root_lattice().almost_positive_roots_decomposition()
[[-alpha[1], alpha[1], alpha[1] + alpha[2], alpha[2], -alpha[2]]]
sage: RootSystem(['B',2]).root_lattice().almost_positive_roots_decomposition()
[[-alpha[1], alpha[1], alpha[1] + 2*alpha[2]], [-alpha[2], alpha[2], alpha[1] + alpha[2]]]
sage: RootSystem(['D',4]).root_lattice().almost_positive_roots_decomposition()
[[-alpha[1], alpha[1], alpha[1] + alpha[2], alpha[2] + alpha[3] + alpha[4]],
[-alpha[2], alpha[2], alpha[1] + alpha[2] + alpha[3] + alpha[4], alpha[1] + 2*alpha[2] + alpha[3] + alpha[4]],
[-alpha[3], alpha[3], alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[4]],
[-alpha[4], alpha[4], alpha[2] + alpha[4], alpha[1] + alpha[2] + alpha[3]]]
REFERENCES:
[CFZ2] | Chapoton, Fomin, Zelevinsky - Polytopal realizations of generalized associahedra |
Returns the family of the simple roots,
with the extra feature that, for simple irreducible root
systems,
yields the opposite of the highest root.
EXAMPLES:
sage: alpha = RootSystem(["A",2]).root_lattice().alpha()
sage: alpha[1]
alpha[1]
sage: alpha[0]
-alpha[1] - alpha[2]
Returns the family of the simple
coroots, with the extra feature that, for simple irreducible
root systems,
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 :
(-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[0], 1: alphacheck[1], 2: alphacheck[2]}
sage: RootSystem(["A",3]).ambient_space().alphacheck()
Finite family {1: (1, -1, 0, 0), 2: (0, 1, -1, 0), 3: (0, 0, 1, -1)}
Return the basic imaginary roots of self.
The basic imaginary roots are the set of imaginary roots
in
where
is the dominant chamger (i.e.,
for all
).
All imaginary roots are
-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[0] + alpha[1] + alpha[2],)
sage: delta = Q.basic_imaginary_roots()[0]
sage: all(delta.scalar(Q.simple_coroot(i)) <= 0 for i in Q.index_set())
True
EXAMPLES:
sage: r = RootSystem(['A',4]).root_space()
sage: r.cartan_type()
['A', 4]
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]
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)
Returns the coroot lattice.
EXAMPLES:
sage: RootSystem(['A',2]).root_lattice().coroot_lattice()
Coroot lattice of the Root system of type ['A', 2]
Returns the coroot space over base_ring
INPUT:
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]
EXAMPLES:
sage: r = RootSystem(['A',4]).root_space()
sage: r.dynkin_diagram()
O---O---O---O
1 2 3 4
A4
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[1] + alpha[2] + alpha[3],
2: alpha[1] + 2*alpha[2] + 2*alpha[3],
3: 1/2*alpha[1] + alpha[2] + 3/2*alpha[3]}
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[1], 2: Lambda[2], 3: Lambda[3]}
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 vs
catch in type
:
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
Return the lattice of -nonnesting partitions
This has been defined by Athanasiadis, see chapter 5 of [Arm06].
INPUT:
See also
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
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[2]
EXAMPLES:
sage: r = RootSystem(['A',4]).root_space()
sage: r.index_set()
(1, 2, 3, 4)
Return a list of the long roots of self.
EXAMPLES:
sage: L = RootSystem(['B',3]).root_lattice()
sage: sorted(L.long_roots())
[-alpha[1], -alpha[1] - 2*alpha[2] - 2*alpha[3],
-alpha[1] - alpha[2], -alpha[1] - alpha[2] - 2*alpha[3],
alpha[1], alpha[1] + alpha[2],
alpha[1] + alpha[2] + 2*alpha[3],
alpha[1] + 2*alpha[2] + 2*alpha[3], -alpha[2],
-alpha[2] - 2*alpha[3], alpha[2], alpha[2] + 2*alpha[3]]
Returns the negative roots of self.
EXAMPLES:
sage: L = RootSystem(['A', 2]).weight_lattice()
sage: sorted(L.negative_roots())
[-2*Lambda[1] + Lambda[2], -Lambda[1] - Lambda[2], Lambda[1] - 2*Lambda[2]]
Algorithm: negate the positive roots
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 |
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[1] + 2*alpha[2] + 3*alpha[3]
sage: Q.nonparabolic_positive_root_sum()
0
sage: Q.nonparabolic_positive_root_sum(())
3*alpha[1] + 4*alpha[2] + 3*alpha[3]
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[1] + alpha[2] + alpha[3], alpha[2] + alpha[3], alpha[3]]
sage: sorted(L.nonparabolic_positive_roots(()))
[alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], alpha[2], alpha[2] + alpha[3], alpha[3]]
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[0] + alphacheck[1] + alphacheck[2]
sage: RootSystem(['D',4,1]).root_lattice().null_coroot()
alphacheck[0] + alphacheck[1] + 2*alphacheck[2] + alphacheck[3] + alphacheck[4]
sage: RootSystem(['F',4,1]).root_lattice().null_coroot()
alphacheck[0] + 2*alphacheck[1] + 3*alphacheck[2] + 2*alphacheck[3] + alphacheck[4]
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[0] + 2*alpha[1] + alpha[2]
sage: RootSystem(['D',4,1]).root_lattice().null_root()
alpha[0] + alpha[1] + 2*alpha[2] + alpha[3] + alpha[4]
sage: RootSystem(['F',4,1]).root_lattice().null_root()
alpha[0] + 2*alpha[1] + 3*alpha[2] + 4*alpha[3] + 2*alpha[4]
Return a picture of this root lattice realization.
INPUT:
roots – which roots to display, if any. Can be one of the following:
coroots – which coroots to display, if any. Can be one of the following:
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:
fundamental_chamber – whether and how to draw the fundamental chamber. Can be one of the following:
alcoves – one of the following (default: True):
alcove_labels – one of the following (default: 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 , then the
bounding box is of the form
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):
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()
Plot an alcove walk.
INPUT:
See also
EXAMPLES:
An alcove walk of type :
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
TESTS:
sage: L = RootSystem(["A",2,1]).weight_space()
sage: p = 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",
... start=L.rho())
sage: print p.description()
Line defined by 2 points: [(-1.0, 8.0), (-1.5, 9.0)]
Line defined by 2 points: [(1.0, 4.0), (1.5, 4.5)]
Line defined by 2 points: [(1.0, 7.0), (1.5, 6.0)]
Arrow from (-1.0,5.0) to (-2.0,7.0)
Arrow from (-1.0,8.0) to (1.0,7.0)
Arrow from (-1.5,9.0) to (-1.0,8.0)
Arrow from (-2.0,7.0) to (-1.0,8.0)
Arrow from (1.0,1.0) to (2.0,2.0)
Arrow from (1.0,4.0) to (-1.0,5.0)
Arrow from (1.0,7.0) to (2.0,8.0)
Arrow from (1.5,4.5) to (1.0,4.0)
Arrow from (1.5,6.0) to (1.0,7.0)
Arrow from (2.0,2.0) to (1.0,4.0)
Plot the alcoves and optionaly their labels.
INPUT:
See also
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
TESTS:
sage: L = RootSystem(["A",2,1]).weight_space()
sage: p = L.plot_alcoves(alcoves=[[0,0]])
sage: print p.description()
Line defined by 2 points: [(-1.0, 0.0), (0.0, -1.0)]
Line defined by 2 points: [(-1.0, 1.0), (-1.0, 0.0)]
Line defined by 2 points: [(-1.0, 1.0), (0.0, 0.0)]
Line defined by 2 points: [(0.0, 0.0), (-1.0, 0.0)]
Line defined by 2 points: [(0.0, 0.0), (0.0, -1.0)]
Line defined by 2 points: [(0.0, 0.0), (1.0, -1.0)]
Line defined by 2 points: [(0.0, 1.0), (-1.0, 1.0)]
Line defined by 2 points: [(0.0, 1.0), (0.0, 0.0)]
Line defined by 2 points: [(0.0, 1.0), (1.0, 0.0)]
Line defined by 2 points: [(1.0, -1.0), (0.0, -1.0)]
Line defined by 2 points: [(1.0, 0.0), (0.0, 0.0)]
Line defined by 2 points: [(1.0, 0.0), (1.0, -1.0)]
sage: sorted((line.options()['rgbcolor'], line.options()['thickness']) for line in p)
[('black', 2), ('black', 2), ('black', 2),
('black', 2), ('black', 2), ('black', 2),
('blue', 1), ('blue', 1), ('blue', 1),
('red', 1), ('red', 1), ('red', 1)]
Plot the bounding box.
INPUT:
This is mostly for testing purposes.
See also
EXAMPLES:
sage: L = RootSystem(["A",2,1]).ambient_space()
sage: L.plot_bounding_box()
Graphics object consisting of 1 graphics primitive
TESTS:
sage: list(L.plot_bounding_box())
[Polygon defined by 4 points]
Plot the (simple/classical) coroots of this root lattice.
INPUT:
See also
EXAMPLES:
sage: RootSystem(["B",3]).ambient_space().plot_coroots()
Graphics3d Object
TESTS:
sage: list(RootSystem(["B",2]).ambient_space().plot_coroots())
[Arrow from (0.0,0.0) to (1.0,-1.0),
Text '$\alpha^\vee_{1}$' at the point (1.05,-1.05),
Arrow from (0.0,0.0) to (0.0,2.0),
Text '$\alpha^\vee_{2}$' at the point (0.0,2.1)]
Plot the (classical) fundamental chamber.
INPUT:
See also
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
TESTS:
sage: L = RootSystem(["B",2,1]).ambient_space()
sage: print L.plot_fundamental_chamber().description()
Polygon defined by 3 points: [(0.5, 0.5), (1.0, 0.0), (0.0, 0.0)]
sage: print L.plot_fundamental_chamber(style="classical").description()
Polygon defined by 3 points: [(0.0, 0.0), (3.0, 3.0), (3.0, 0.0)]
Plot the fundamental weights of this root lattice.
INPUT:
See also
EXAMPLES:
sage: RootSystem(["B",3]).ambient_space().plot_fundamental_weights()
Graphics3d Object
TESTS:
sage: sorted(RootSystem(["A",2]).weight_lattice().plot_fundamental_weights(), key=str)
[Arrow from (0.0,0.0) to (0.0,1.0),
Arrow from (0.0,0.0) to (1.0,0.0),
Text '$\Lambda_{1}$' at the point (1.05,0.0),
Text '$\Lambda_{2}$' at the point (0.0,1.05)]
sage: sorted(RootSystem(["A",2]).ambient_lattice().plot_fundamental_weights(), key=str)
[Arrow from (0.0,0.0) to (-0.5,0.866024518389),
Arrow from (0.0,0.0) to (0.5,0.866024518389),
Text '$\Lambda_{1}$' at the point (0.525,0.909325744308),
Text '$\Lambda_{2}$' at the point (-0.525,0.909325744308)]
Plot the polyhedron whose vertices are given by the orbit
of .
In type , this is the usual permutohedron.
See also
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: polyhedrons of large dimension know how to project themselves nicely:
sage: RootSystem(["F",4]).ambient_space().plot_hedron() # long time
Graphics3d Object
TESTS:
sage: L = RootSystem(["B",2]).ambient_space()
sage: print L.plot_hedron().description()
Polygon defined by 8 points: [(1.5, 0.5), (0.5, 1.5), (-0.5, 1.5), (-1.5, 0.5), (-1.5, -0.5), (-0.5, -1.5), (0.5, -1.5), (1.5, -0.5)]
Line defined by 2 points: [(-0.5, -1.5), (0.5, -1.5)]
Line defined by 2 points: [(-0.5, 1.5), (0.5, 1.5)]
Line defined by 2 points: [(-1.5, -0.5), (-0.5, -1.5)]
Line defined by 2 points: [(-1.5, -0.5), (-1.5, 0.5)]
Line defined by 2 points: [(-1.5, 0.5), (-0.5, 1.5)]
Line defined by 2 points: [(0.5, -1.5), (1.5, -0.5)]
Line defined by 2 points: [(0.5, 1.5), (1.5, 0.5)]
Line defined by 2 points: [(1.5, -0.5), (1.5, 0.5)]
Point set defined by 8 point(s): [(-1.5, -0.5), (-1.5, 0.5), (-0.5, -1.5), (-0.5, 1.5), (0.5, -1.5), (0.5, 1.5), (1.5, -0.5), (1.5, 0.5)]
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 instance at ...>
See also
Plot the simple reflection hyperplanes.
INPUT:
See also
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
TESTS:
sage: L = RootSystem(["A",2]).ambient_space()
sage: print L.plot_reflection_hyperplanes().description()
Text '$H_{\alpha^\vee_{1}}$' at the point (-1.81...,3.15)
Text '$H_{\alpha^\vee_{2}}$' at the point (1.81...,3.15)
Line defined by 2 points: [(-1.73..., 3.0), (1.73..., -3.0)]
Line defined by 2 points: [(1.73..., 3.0), (-1.73..., -3.0)]
sage: print L.plot_reflection_hyperplanes("all").description()
Text '$H_{\alpha^\vee_{1} + \alpha^\vee_{2}}$' at the point (3.15,0.0)
Text '$H_{\alpha^\vee_{1}}$' at the point (-1.81...,3.15)
Text '$H_{\alpha^\vee_{2}}$' at the point (1.81...,3.15)
Line defined by 2 points: [(-1.73..., 3.0), (1.73..., -3.0)]
Line defined by 2 points: [(1.73..., 3.0), (-1.73..., -3.0)]
Line defined by 2 points: [(3.0, 0.0), (-3.0, 0.0)]
sage: L = RootSystem(["A",2,1]).ambient_space()
sage: print L.plot_reflection_hyperplanes().description()
Text '$H_{\alpha^\vee_{0}}$' at the point (3.15,0.90...)
Text '$H_{\alpha^\vee_{1}}$' at the point (-1.81...,3.15)
Text '$H_{\alpha^\vee_{2}}$' at the point (1.81...,3.15)
Line defined by 2 points: [(-1.73..., 3.0), (1.73..., -3.0)]
Line defined by 2 points: [(1.73..., 3.0), (-1.73..., -3.0)]
Line defined by 2 points: [(3.0, 0.86...), (-3.0, 0.86...)]
Todo
Provide an option for transparency?
Plot the (simple/classical) roots of this root lattice.
INPUT:
See also
EXAMPLES:
sage: RootSystem(["B",3]).ambient_space().plot_roots()
Graphics3d Object
sage: RootSystem(["B",3]).ambient_space().plot_roots("all")
Graphics3d Object
TESTS:
sage: list(RootSystem(["A",2]).root_lattice().plot_roots())
[Arrow from (0.0,0.0) to (1.0,0.0),
Text '$\alpha_{1}$' at the point (1.05,0.0),
Arrow from (0.0,0.0) to (0.0,1.0),
Text '$\alpha_{2}$' at the point (0.0,1.05)]
sage: list(RootSystem(["A",2]).weight_lattice().plot_roots(labels=False))
[Arrow from (0.0,0.0) to (2.0,-1.0),
Arrow from (0.0,0.0) to (-1.0,2.0)]
sage: list(RootSystem(["A",2]).ambient_lattice().plot_roots())
[Arrow from (0.0,0.0) to (1.5,0.86...),
Text '$\alpha_{1}$' at the point (1.575,0.90...),
Arrow from (0.0,0.0) to (-1.5,0.86...),
Text '$\alpha_{2}$' at the point (-1.575,0.90...)]
sage: list(RootSystem(["B",2]).ambient_space().plot_roots())
[Arrow from (0.0,0.0) to (1.0,-1.0),
Text '$\alpha_{1}$' at the point (1.05,-1.05),
Arrow from (0.0,0.0) to (0.0,1.0),
Text '$\alpha_{2}$' at the point (0.0,1.05)]
sage: list(RootSystem(["A",2]).root_lattice().plot_roots("all"))
[Arrow from (0.0,0.0) to (1.0,0.0),
Text '$\alpha_{1}$' at the point (1.05,0.0),
Arrow from (0.0,0.0) to (0.0,1.0),
Text '$\alpha_{2}$' at the point (0.0,1.05),
Arrow from (0.0,0.0) to (1.0,1.0),
Text '$\alpha_{1} + \alpha_{2}$' at the point (1.05,1.05),
Arrow from (0.0,0.0) to (-1.0,0.0),
Text '$-\alpha_{1}$' at the point (-1.05,0.0),
Arrow from (0.0,0.0) to (0.0,-1.0),
Text '$-\alpha_{2}$' at the point (0.0,-1.05),
Arrow from (0.0,0.0) to (-1.0,-1.0),
Text '$-\alpha_{1} - \alpha_{2}$' at the point (-1.05,-1.05)]
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[0] + alpha[1] + alpha[2] + alpha[3],
2*alpha[0] + 2*alpha[1] + 2*alpha[2] + 2*alpha[3],
3*alpha[0] + 3*alpha[1] + 3*alpha[2] + 3*alpha[3],
4*alpha[0] + 4*alpha[1] + 4*alpha[2] + 4*alpha[3],
5*alpha[0] + 5*alpha[1] + 5*alpha[2] + 5*alpha[3]]
Return the positive real roots of self.
EXAMPLES:
sage: L = RootSystem(['A',3]).root_lattice()
sage: sorted(L.positive_real_roots())
[alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3],
alpha[2], alpha[2] + alpha[3], alpha[3]]
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[1],
alpha[2],
alpha[3],
alpha[1] + alpha[2],
alpha[2] + alpha[3],
alpha[1] + alpha[2] + alpha[3],
alpha[0] + 2*alpha[1] + alpha[2] + alpha[3],
alpha[0] + alpha[1] + 2*alpha[2] + alpha[3],
alpha[0] + alpha[1] + alpha[2] + 2*alpha[3],
alpha[0] + 2*alpha[1] + 2*alpha[2] + alpha[3]]
sage: Q = RootSystem(['A',4,2]).root_lattice()
sage: PR = Q.positive_roots()
sage: [PR.unrank(i) for i in range(5)]
[alpha[1],
alpha[2],
2*alpha[1] + alpha[2],
alpha[1] + alpha[2],
alpha[0] + alpha[1] + alpha[2]]
sage: Q = RootSystem(['D',3,2]).root_lattice()
sage: PR = Q.positive_roots()
sage: [PR.unrank(i) for i in range(5)]
[alpha[1],
alpha[2],
alpha[1] + 2*alpha[2],
alpha[1] + alpha[2],
alpha[0] + alpha[1] + 2*alpha[2]]
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[1], alpha[1] + alpha[2],
alpha[1] + alpha[2] + alpha[3], alpha[2],
alpha[2] + alpha[3], alpha[3]]
sage: sorted(L.positive_roots((1,2)))
[alpha[1], alpha[1] + alpha[2], alpha[2]]
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[1],
alpha[2],
alpha[3],
alpha[1] + alpha[2],
alpha[2] + alpha[3],
alpha[1] + alpha[2] + alpha[3],
alpha[0] + 2*alpha[1] + alpha[2] + alpha[3],
alpha[0] + alpha[1] + 2*alpha[2] + alpha[3],
alpha[0] + alpha[1] + alpha[2] + 2*alpha[3],
alpha[0] + 2*alpha[1] + 2*alpha[2] + alpha[3]]
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[2], alpha[1], alpha[1] + alpha[2], 2*alpha[1] + alpha[2]]
sage: L.positive_roots_by_height(increasing = False)
[2*alpha[1] + alpha[2], alpha[1] + alpha[2], alpha[2], alpha[1]]
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
Returns the set of positive roots outside the parabolic subsystem with Dynkin node set index_set.
INPUT:
EXAMPLES:
sage: lattice = RootSystem(['A',3]).root_lattice()
sage: sorted(lattice.positive_roots_nonparabolic((1,3)), key=str)
[alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], alpha[2], alpha[2] + alpha[3]]
sage: sorted(lattice.positive_roots_nonparabolic((2,3)), key=str)
[alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3]]
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.
Returns the sum of positive roots outside the parabolic subsystem with Dynkin node set index_set.
INPUT:
EXAMPLES:
sage: lattice = RootSystem(['A',3]).root_lattice()
sage: lattice.positive_roots_nonparabolic_sum((1,3))
2*alpha[1] + 4*alpha[2] + 2*alpha[3]
sage: lattice.positive_roots_nonparabolic_sum((2,3))
3*alpha[1] + 2*alpha[2] + alpha[3]
sage: lattice.positive_roots_nonparabolic_sum(())
3*alpha[1] + 4*alpha[2] + 3*alpha[3]
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.
Return the set of positive roots for the parabolic subsystem with Dynkin node set index_set.
INPUT:
EXAMPLES:
sage: lattice = RootSystem(['A',3]).root_lattice()
sage: sorted(lattice.positive_roots_parabolic((1,3)), key=str)
[alpha[1], alpha[3]]
sage: sorted(lattice.positive_roots_parabolic((2,3)), key=str)
[alpha[2], alpha[2] + alpha[3], alpha[3]]
sage: sorted(lattice.positive_roots_parabolic(), key=str)
[alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], alpha[2], alpha[2] + alpha[3], alpha[3]]
Warning
This returns an error if the Cartan type is not finite.
Returns the projection along the root, and across the
hyperplane define by coroot, as a function from self to
self.
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()[1]
sage: y=space.simple_coroots()[1]
sage: pi = space.projection(x,y)
sage: x
2*Lambda[1] - Lambda[2]
sage: pi(x)
-2*Lambda[1] + Lambda[2]
sage: pi(-x)
-2*Lambda[1] + Lambda[2]
sage: pi = space.projection(x,y,False)
sage: pi(-x)
2*Lambda[1] - Lambda[2]
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()[1]
sage: y=space.simple_coroots()[1]
sage: s = space.reflection(x,y)
sage: x
2*Lambda[1] - Lambda[2]
sage: s(x)
-2*Lambda[1] + Lambda[2]
sage: s(-x)
2*Lambda[1] - Lambda[2]
Returns the (restricted) root poset associated to self.
The elements are given by the positive roots (resp. non-simple, positive roots), and
iff
is a non-negative linear combination of simple roots.
INPUT:
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[1], alpha[1] + alpha[2]], [alpha[2], alpha[1] + alpha[2]]]
sage: Phi = RootSystem(['A',3]).root_poset(restricted=True); Phi
Finite poset containing 3 elements
sage: sorted(Phi.cover_relations(), key=str)
[[alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3]], [alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[3]]]
sage: Phi = RootSystem(['B',2]).root_poset(); Phi
Finite poset containing 4 elements
sage: sorted(Phi.cover_relations(), key=str)
[[alpha[1] + alpha[2], alpha[1] + 2*alpha[2]],
[alpha[1], alpha[1] + alpha[2]],
[alpha[2], alpha[1] + alpha[2]]]
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.
Returns the family of the simple reflections
of this root system.
EXAMPLES:
sage: r = RootSystem(["A", 2]).root_lattice()
sage: s = r.simple_reflections()
sage: s[1]( r.simple_root(1) )
-alpha[1]
TEST:
sage: s
simple reflections
Return a list of the short roots of self.
EXAMPLES:
sage: L = RootSystem(['B',3]).root_lattice()
sage: sorted(L.short_roots())
[-alpha[1] - alpha[2] - alpha[3],
alpha[1] + alpha[2] + alpha[3],
-alpha[2] - alpha[3],
alpha[2] + alpha[3],
-alpha[3],
alpha[3]]
Returns the simple coroot.
EXAMPLES:
sage: RootSystem(['A',2]).root_lattice().simple_coroot(1)
alphacheck[1]
Returns the family of the simple coroots.
EXAMPLES:
sage: alphacheck = RootSystem(['A',3]).root_lattice().simple_coroots()
sage: [alphacheck[i] for i in [1, 2, 3]]
[alphacheck[1], alphacheck[2], alphacheck[3]]
Returns the projection along the simple root, and across the
hyperplane define by the
simple coroot, as a function from
self to self.
INPUT:
EXAMPLES:
sage: space = RootSystem(['A',2]).weight_lattice()
sage: x = space.simple_roots()[1]
sage: pi = space.simple_projection(1)
sage: x
2*Lambda[1] - Lambda[2]
sage: pi(x)
-2*Lambda[1] + Lambda[2]
sage: pi(-x)
-2*Lambda[1] + Lambda[2]
sage: pi = space.simple_projection(1,False)
sage: pi(-x)
2*Lambda[1] - Lambda[2]
Returns the family 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[1](x[2])
-Lambda[1] + 2*Lambda[2]
Returns the simple reflection, as a function from
self to self.
INPUT:
EXAMPLES:
sage: space = RootSystem(['A',2]).ambient_lattice()
sage: s = space.simple_reflection(1)
sage: x = space.simple_roots()[1]
sage: x
(1, -1, 0)
sage: s(x)
(-1, 1, 0)
Returns the family of the simple reflections
of this root system.
EXAMPLES:
sage: r = RootSystem(["A", 2]).root_lattice()
sage: s = r.simple_reflections()
sage: s[1]( r.simple_root(1) )
-alpha[1]
TEST:
sage: s
simple reflections
Returns the 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[1]
TESTS:
sage: super(sage.combinat.root_system.root_space.RootSpace, r).simple_root(1)
Traceback (most recent call last):
...
NotImplementedError: <abstract method simple_root at ...>
Returns the family of the simple roots.
EXAMPLES:
sage: alpha = RootSystem(["A",3]).root_lattice().simple_roots()
sage: [alpha[i] for i in [1,2,3]]
[alpha[1], alpha[2], alpha[3]]
Return the family of the simple roots.
INPUT:
The 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 for
not a special node, and that
EXAMPLES:
In simply laced cases, this is boring:
sage: RootSystem(["A",3, 1]).root_lattice().simple_roots_tilde()
Finite family {0: alpha[0], 1: alpha[1], 2: alpha[2], 3: alpha[3]}
This was checked by hand:
sage: RootSystem(["C",2,1]).coroot_lattice().simple_roots_tilde()
Finite family {0: alphacheck[0] - alphacheck[2], 1: alphacheck[1], 2: alphacheck[2]}
sage: RootSystem(["B",2,1]).coroot_lattice().simple_roots_tilde()
Finite family {0: alphacheck[0] - alphacheck[1], 1: alphacheck[1], 2: alphacheck[2]}
What about type BC?
Return some elements of this root lattice realization
EXAMPLES:
sage: L = RootSystem(["A",2]).weight_lattice()
sage: L.some_elements()
[2*Lambda[1] + 2*Lambda[2], 2*Lambda[1] - Lambda[2], -Lambda[1] + 2*Lambda[2], Lambda[1], Lambda[2]]
sage: L = RootSystem(["A",2]).root_lattice()
sage: L.some_elements()
[2*alpha[1] + 2*alpha[2], alpha[1], alpha[2]]
The operator on almost positive roots
Given a subset of non adjacent vertices of the Dynkin
diagram, this constructs the operator on the almost positive
roots which fixes the negative simple roots
for
not in
, and acts otherwise by:
See Equation (1.2) of [CFZ].
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 :
sage: tau(-alpha[2])
-alpha[2]
The action on a negative simple root in :
sage: tau(-alpha[1])
alpha[1]
The action on all almost positive roots:
sage: for root in L.almost_positive_roots():
... print 'tau({:<41}) ='.format(root), tau(root)
tau(-alpha[1] ) = alpha[1]
tau(alpha[1] ) = -alpha[1]
tau(alpha[1] + alpha[2] ) = alpha[2] + alpha[3]
tau(alpha[1] + alpha[2] + alpha[3] ) = alpha[2]
tau(alpha[1] + alpha[2] + alpha[3] + alpha[4]) = alpha[2] + alpha[3] + alpha[4]
tau(-alpha[2] ) = -alpha[2]
tau(alpha[2] ) = alpha[1] + alpha[2] + alpha[3]
tau(alpha[2] + alpha[3] ) = alpha[1] + alpha[2]
tau(alpha[2] + alpha[3] + alpha[4] ) = alpha[1] + alpha[2] + alpha[3] + alpha[4]
tau(-alpha[3] ) = alpha[3]
tau(alpha[3] ) = -alpha[3]
tau(alpha[3] + alpha[4] ) = alpha[4]
tau(-alpha[4] ) = -alpha[4]
tau(alpha[4] ) = alpha[3] + alpha[4]
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(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)
See also
REFERENCES:
[CFZ] Chapoton, Fomin, Zelevinsky - Polytopal realizations of generalized associahedra
Returns the and
piecewise linear operators on self
Those operators are induced by the bipartition of
the simple roots of self, and stabilize the almost
positive roots. Namely,
fixes the negative simple
roots
for
in
, and acts otherwise by:
acts analogously, with
and
interchanged.
Those operators are used to construct the associahedron, a polytopal realization of the cluster complex (see Associahedron).
EXAMPLES:
We explore the example of [CFZ1] 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 beta, ",", taup(beta), ",", taum(beta)
-alpha[1] , alpha[1] , -alpha[1]
alpha[1] , -alpha[1] , alpha[1] + alpha[2]
alpha[1] + alpha[2] , alpha[2] , alpha[1]
-alpha[2] , -alpha[2] , alpha[2]
alpha[2] , alpha[1] + alpha[2] , -alpha[2]
REFERENCES:
[CFZ1] Chapoton, Fomin, Zelevinsky - Polytopal realizations of generalized associahedra
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)
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]