Cartan types#
Todo
Why does sphinx complain if I use sections here?
Introduction
Loosely speaking, Dynkin diagrams (or equivalently Cartan matrices) are graphs which are used to classify root systems, Coxeter and Weyl groups, Lie algebras, Lie groups, crystals, etc. up to an isomorphism. Cartan types are a standard set of names for those Dynkin diagrams (see Wikipedia article Dynkin_diagram).
Let us consider, for example, the Cartan type \(A_4\):
sage: T = CartanType(['A', 4]); T
['A', 4]
>>> from sage.all import *
>>> T = CartanType(['A', Integer(4)]); T
['A', 4]
It is the name of the following Dynkin diagram:
sage: DynkinDiagram(T) # needs sage.graphs
O---O---O---O
1 2 3 4
A4
>>> from sage.all import *
>>> DynkinDiagram(T) # needs sage.graphs
O---O---O---O
1 2 3 4
A4
Note
For convenience, the following shortcuts are available:
sage: DynkinDiagram(['A',4]) # needs sage.graphs
O---O---O---O
1 2 3 4
A4
sage: DynkinDiagram('A4') # needs sage.graphs
O---O---O---O
1 2 3 4
A4
sage: T.dynkin_diagram() # needs sage.graphs
O---O---O---O
1 2 3 4
A4
>>> from sage.all import *
>>> DynkinDiagram(['A',Integer(4)]) # needs sage.graphs
O---O---O---O
1 2 3 4
A4
>>> DynkinDiagram('A4') # needs sage.graphs
O---O---O---O
1 2 3 4
A4
>>> T.dynkin_diagram() # needs sage.graphs
O---O---O---O
1 2 3 4
A4
See DynkinDiagram
for how to further manipulate Dynkin diagrams.
From this data (the Cartan datum), one can construct the associated root system:
sage: RootSystem(T)
Root system of type ['A', 4]
>>> from sage.all import *
>>> RootSystem(T)
Root system of type ['A', 4]
The associated Weyl group of \(A_n\) is the symmetric group \(S_{n+1}\):
sage: W = WeylGroup(T); W # needs sage.libs.gap
Weyl Group of type ['A', 4] (as a matrix group acting on the ambient space)
sage: W.cardinality() # needs sage.libs.gap
120
>>> from sage.all import *
>>> W = WeylGroup(T); W # needs sage.libs.gap
Weyl Group of type ['A', 4] (as a matrix group acting on the ambient space)
>>> W.cardinality() # needs sage.libs.gap
120
while the Lie algebra is \(sl_{n+1}\), and the Lie group \(SL_{n+1}\) (TODO: illustrate this once this is implemented).
One may also construct crystals associated to various Dynkin diagrams. For example:
sage: C = crystals.Letters(T); C # needs sage.combinat
The crystal of letters for type ['A', 4]
sage: C.list() # needs sage.combinat
[1, 2, 3, 4, 5]
sage: C = crystals.Tableaux(T, shape=[2]); C # needs sage.combinat
The crystal of tableaux of type ['A', 4] and shape(s) [[2]]
sage: C.cardinality() # needs sage.combinat
15
>>> from sage.all import *
>>> C = crystals.Letters(T); C # needs sage.combinat
The crystal of letters for type ['A', 4]
>>> C.list() # needs sage.combinat
[1, 2, 3, 4, 5]
>>> C = crystals.Tableaux(T, shape=[Integer(2)]); C # needs sage.combinat
The crystal of tableaux of type ['A', 4] and shape(s) [[2]]
>>> C.cardinality() # needs sage.combinat
15
Here is a sample of all the finite irreducible crystallographic Cartan types:
sage: CartanType.samples(finite=True, crystallographic=True)
[['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5],
['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2]]
>>> from sage.all import *
>>> CartanType.samples(finite=True, crystallographic=True)
[['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5],
['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2]]
One can also get latex representations of the crystallographic Cartan types and their corresponding Dynkin diagrams:
sage: [latex(ct) for ct in CartanType.samples(crystallographic=True)]
[A_{1}, A_{5}, B_{1}, B_{5}, C_{1}, C_{5}, D_{2}, D_{3}, D_{5},
E_6, E_7, E_8, F_4, G_2,
A_{1}^{(1)}, A_{5}^{(1)}, B_{1}^{(1)}, B_{5}^{(1)},
C_{1}^{(1)}, C_{5}^{(1)}, D_{3}^{(1)}, D_{5}^{(1)},
E_6^{(1)}, E_7^{(1)}, E_8^{(1)}, F_4^{(1)}, G_2^{(1)},
BC_{1}^{(2)}, BC_{5}^{(2)},
B_{5}^{(1)\vee}, C_{4}^{(1)\vee}, F_4^{(1)\vee},
G_2^{(1)\vee}, BC_{1}^{(2)\vee}, BC_{5}^{(2)\vee}]
sage: view([DynkinDiagram(ct) for ct in CartanType.samples(crystallographic=True)]) # not tested
>>> from sage.all import *
>>> [latex(ct) for ct in CartanType.samples(crystallographic=True)]
[A_{1}, A_{5}, B_{1}, B_{5}, C_{1}, C_{5}, D_{2}, D_{3}, D_{5},
E_6, E_7, E_8, F_4, G_2,
A_{1}^{(1)}, A_{5}^{(1)}, B_{1}^{(1)}, B_{5}^{(1)},
C_{1}^{(1)}, C_{5}^{(1)}, D_{3}^{(1)}, D_{5}^{(1)},
E_6^{(1)}, E_7^{(1)}, E_8^{(1)}, F_4^{(1)}, G_2^{(1)},
BC_{1}^{(2)}, BC_{5}^{(2)},
B_{5}^{(1)\vee}, C_{4}^{(1)\vee}, F_4^{(1)\vee},
G_2^{(1)\vee}, BC_{1}^{(2)\vee}, BC_{5}^{(2)\vee}]
>>> view([DynkinDiagram(ct) for ct in CartanType.samples(crystallographic=True)]) # not tested
Non-crystallographic Cartan types are also partially supported:
sage: CartanType.samples(finite=True, crystallographic=False)
[['I', 5], ['H', 3], ['H', 4]]
>>> from sage.all import *
>>> CartanType.samples(finite=True, crystallographic=False)
[['I', 5], ['H', 3], ['H', 4]]
In Sage, a Cartan type is used as a database of type-specific
information and algorithms (see e.g. sage.combinat.root_system.type_A
).
This database includes how to construct the Dynkin diagram, the ambient space
for the root system (see Wikipedia article Root_system), and further
mathematical properties:
sage: T.is_finite(), T.is_simply_laced(), T.is_affine(), T.is_crystallographic()
(True, True, False, True)
>>> from sage.all import *
>>> T.is_finite(), T.is_simply_laced(), T.is_affine(), T.is_crystallographic()
(True, True, False, True)
In particular, a Sage Cartan type is endowed with a fixed choice of labels for the nodes of the Dynkin diagram. This choice follows the conventions of Nicolas Bourbaki, Lie Groups and Lie Algebras: Chapter 4-6, Elements of Mathematics, Springer (2002). ISBN 978-3540426509. For example:
sage: T = CartanType(['D', 4])
sage: DynkinDiagram(T) # needs sage.graphs
O 4
|
|
O---O---O
1 2 3
D4
sage: E6 = CartanType(['E',6])
sage: DynkinDiagram(E6) # needs sage.graphs
O 2
|
|
O---O---O---O---O
1 3 4 5 6
E6
>>> from sage.all import *
>>> T = CartanType(['D', Integer(4)])
>>> DynkinDiagram(T) # needs sage.graphs
O 4
|
|
O---O---O
1 2 3
D4
>>> E6 = CartanType(['E',Integer(6)])
>>> DynkinDiagram(E6) # needs sage.graphs
O 2
|
|
O---O---O---O---O
1 3 4 5 6
E6
Note
The direction of the arrows is the opposite (i.e. the transpose) of Bourbaki’s convention, but agrees with Kac’s.
For example, in type \(C_2\), we have:
sage: C2 = DynkinDiagram(['C',2]); C2 # needs sage.graphs
O=<=O
1 2
C2
sage: C2.cartan_matrix() # needs sage.graphs
[ 2 -2]
[-1 2]
>>> from sage.all import *
>>> C2 = DynkinDiagram(['C',Integer(2)]); C2 # needs sage.graphs
O=<=O
1 2
C2
>>> C2.cartan_matrix() # needs sage.graphs
[ 2 -2]
[-1 2]
However Bourbaki would have the Cartan matrix as:
If desired, other node labelling conventions can be achieved. For example the Kac labelling for type \(E_6\) can be obtained via:
sage: E6.relabel({1:1,2:6,3:2,4:3,5:4,6:5}).dynkin_diagram() # needs sage.graphs
O 6
|
|
O---O---O---O---O
1 2 3 4 5
E6 relabelled by {1: 1, 2: 6, 3: 2, 4: 3, 5: 4, 6: 5}
>>> from sage.all import *
>>> E6.relabel({Integer(1):Integer(1),Integer(2):Integer(6),Integer(3):Integer(2),Integer(4):Integer(3),Integer(5):Integer(4),Integer(6):Integer(5)}).dynkin_diagram() # needs sage.graphs
O 6
|
|
O---O---O---O---O
1 2 3 4 5
E6 relabelled by {1: 1, 2: 6, 3: 2, 4: 3, 5: 4, 6: 5}
Contributions implementing other conventions are very welcome.
Another option is to build from scratch a new Dynkin diagram. The architecture has been designed to make it fairly easy to add other labelling conventions. In particular, we strived at choosing type free algorithms whenever possible, so in principle most features should remain available even with custom Cartan types. This has not been used much yet, so some rough corners certainly remain.
Here, we construct the hyperbolic example of Exercise 4.9 p. 57 of Kac, Infinite Dimensional Lie Algebras. We start with an empty Dynkin diagram, and add a couple nodes:
sage: g = DynkinDiagram() # needs sage.graphs
sage: g.add_vertices([1,2,3]) # needs sage.graphs
>>> from sage.all import *
>>> g = DynkinDiagram() # needs sage.graphs
>>> g.add_vertices([Integer(1),Integer(2),Integer(3)]) # needs sage.graphs
Note that the diagonal of the Cartan matrix is already initialized:
sage: g.cartan_matrix() # needs sage.graphs
[2 0 0]
[0 2 0]
[0 0 2]
>>> from sage.all import *
>>> g.cartan_matrix() # needs sage.graphs
[2 0 0]
[0 2 0]
[0 0 2]
Then we add a couple edges:
sage: g.add_edge(1,2,2) # needs sage.graphs
sage: g.add_edge(1,3) # needs sage.graphs
sage: g.add_edge(2,3) # needs sage.graphs
>>> from sage.all import *
>>> g.add_edge(Integer(1),Integer(2),Integer(2)) # needs sage.graphs
>>> g.add_edge(Integer(1),Integer(3)) # needs sage.graphs
>>> g.add_edge(Integer(2),Integer(3)) # needs sage.graphs
and we get the desired Cartan matrix:
sage: g.cartan_matrix() # needs sage.graphs
[2 0 0]
[0 2 0]
[0 0 2]
>>> from sage.all import *
>>> g.cartan_matrix() # needs sage.graphs
[2 0 0]
[0 2 0]
[0 0 2]
Oops, the Cartan matrix did not change! This is because it is cached
for efficiency (see cached_method
). In general, a Dynkin
diagram should not be modified after having been used.
Warning
this is not checked currently
Todo
add a method set_mutable()
as, say, for matrices
Here, we can work around this by clearing the cache:
sage: delattr(g, 'cartan_matrix') # needs sage.graphs
>>> from sage.all import *
>>> delattr(g, 'cartan_matrix') # needs sage.graphs
Now we get the desired Cartan matrix:
sage: g.cartan_matrix() # needs sage.graphs
[ 2 -1 -1]
[-2 2 -1]
[-1 -1 2]
>>> from sage.all import *
>>> g.cartan_matrix() # needs sage.graphs
[ 2 -1 -1]
[-2 2 -1]
[-1 -1 2]
Note that backward edges have been automatically added:
sage: g.edges(sort=True) # needs sage.graphs
[(1, 2, 2), (1, 3, 1), (2, 1, 1), (2, 3, 1), (3, 1, 1), (3, 2, 1)]
>>> from sage.all import *
>>> g.edges(sort=True) # needs sage.graphs
[(1, 2, 2), (1, 3, 1), (2, 1, 1), (2, 3, 1), (3, 1, 1), (3, 2, 1)]
Reducible Cartan types
Reducible Cartan types can be specified by passing a sequence or list of irreducible Cartan types:
sage: CartanType(['A',2],['B',2])
A2xB2
sage: CartanType([['A',2],['B',2]])
A2xB2
sage: CartanType(['A',2],['B',2]).is_reducible()
True
>>> from sage.all import *
>>> CartanType(['A',Integer(2)],['B',Integer(2)])
A2xB2
>>> CartanType([['A',Integer(2)],['B',Integer(2)]])
A2xB2
>>> CartanType(['A',Integer(2)],['B',Integer(2)]).is_reducible()
True
or using the following short hand notation:
sage: CartanType("A2xB2")
A2xB2
sage: CartanType("A2","B2") == CartanType("A2xB2")
True
>>> from sage.all import *
>>> CartanType("A2xB2")
A2xB2
>>> CartanType("A2","B2") == CartanType("A2xB2")
True
Degenerate cases
When possible, type \(I_n\) is automatically converted to the isomorphic crystallographic Cartan types (any reason not to do so?):
sage: CartanType(["I",1])
A1xA1
sage: CartanType(["I",3])
['A', 2]
sage: CartanType(["I",4])
['C', 2]
sage: CartanType(["I",6])
['G', 2]
>>> from sage.all import *
>>> CartanType(["I",Integer(1)])
A1xA1
>>> CartanType(["I",Integer(3)])
['A', 2]
>>> CartanType(["I",Integer(4)])
['C', 2]
>>> CartanType(["I",Integer(6)])
['G', 2]
The Dynkin diagrams for types \(B_1\), \(C_1\), \(D_2\), and \(D_3\) are isomorphic to that for \(A_1\), \(A_1\), \(A_1 \times A_1\), and \(A_3\), respectively. However their natural ambient space realizations (stemming from the corresponding infinite families of Lie groups) are different. Therefore, the Cartan types are considered as distinct:
sage: CartanType(['B',1])
['B', 1]
sage: CartanType(['C',1])
['C', 1]
sage: CartanType(['D',2])
['D', 2]
sage: CartanType(['D',3])
['D', 3]
>>> from sage.all import *
>>> CartanType(['B',Integer(1)])
['B', 1]
>>> CartanType(['C',Integer(1)])
['C', 1]
>>> CartanType(['D',Integer(2)])
['D', 2]
>>> CartanType(['D',Integer(3)])
['D', 3]
Affine Cartan types
For affine types, we use the usual conventions for affine Coxeter groups: each affine type is either untwisted (that is arise from the natural affinisation of a finite Cartan type):
sage: CartanType(["A", 4, 1]).dynkin_diagram() # needs sage.graphs
0
O-----------+
| |
| |
O---O---O---O
1 2 3 4
A4~
sage: CartanType(["B", 4, 1]).dynkin_diagram() # needs sage.graphs
O 0
|
|
O---O---O=>=O
1 2 3 4
B4~
>>> from sage.all import *
>>> CartanType(["A", Integer(4), Integer(1)]).dynkin_diagram() # needs sage.graphs
0
O-----------+
| |
| |
O---O---O---O
1 2 3 4
A4~
>>> CartanType(["B", Integer(4), Integer(1)]).dynkin_diagram() # needs sage.graphs
O 0
|
|
O---O---O=>=O
1 2 3 4
B4~
or dual thereof:
sage: CartanType(["B", 4, 1]).dual().dynkin_diagram() # needs sage.graphs
O 0
|
|
O---O---O=<=O
1 2 3 4
B4~*
>>> from sage.all import *
>>> CartanType(["B", Integer(4), Integer(1)]).dual().dynkin_diagram() # needs sage.graphs
O 0
|
|
O---O---O=<=O
1 2 3 4
B4~*
or is of type \(\widetilde{BC}_n\) (which yields an irreducible, but nonreduced root system):
sage: CartanType(["BC", 4, 2]).dynkin_diagram() # needs sage.graphs
O=<=O---O---O=<=O
0 1 2 3 4
BC4~
>>> from sage.all import *
>>> CartanType(["BC", Integer(4), Integer(2)]).dynkin_diagram() # needs sage.graphs
O=<=O---O---O=<=O
0 1 2 3 4
BC4~
This includes the two degenerate cases:
sage: CartanType(["A", 1, 1]).dynkin_diagram() # needs sage.graphs
O<=>O
0 1
A1~
sage: CartanType(["BC", 1, 2]).dynkin_diagram() # needs sage.graphs
4
O=<=O
0 1
BC1~
>>> from sage.all import *
>>> CartanType(["A", Integer(1), Integer(1)]).dynkin_diagram() # needs sage.graphs
O<=>O
0 1
A1~
>>> CartanType(["BC", Integer(1), Integer(2)]).dynkin_diagram() # needs sage.graphs
4
O=<=O
0 1
BC1~
For the user convenience, Kac’s notations for twisted affine types are automatically translated into the previous ones:
sage: # needs sage.graphs
sage: CartanType(["A", 9, 2])
['B', 5, 1]^*
sage: CartanType(["A", 9, 2]).dynkin_diagram()
O 0
|
|
O---O---O---O=<=O
1 2 3 4 5
B5~*
sage: CartanType(["A", 10, 2]).dynkin_diagram()
O=<=O---O---O---O=<=O
0 1 2 3 4 5
BC5~
sage: CartanType(["D", 5, 2]).dynkin_diagram()
O=<=O---O---O=>=O
0 1 2 3 4
C4~*
sage: CartanType(["D", 4, 3]).dynkin_diagram()
3
O=>=O---O
2 1 0
G2~* relabelled by {0: 0, 1: 2, 2: 1}
sage: CartanType(["E", 6, 2]).dynkin_diagram()
O---O---O=<=O---O
0 1 2 3 4
F4~*
>>> from sage.all import *
>>> # needs sage.graphs
>>> CartanType(["A", Integer(9), Integer(2)])
['B', 5, 1]^*
>>> CartanType(["A", Integer(9), Integer(2)]).dynkin_diagram()
O 0
|
|
O---O---O---O=<=O
1 2 3 4 5
B5~*
>>> CartanType(["A", Integer(10), Integer(2)]).dynkin_diagram()
O=<=O---O---O---O=<=O
0 1 2 3 4 5
BC5~
>>> CartanType(["D", Integer(5), Integer(2)]).dynkin_diagram()
O=<=O---O---O=>=O
0 1 2 3 4
C4~*
>>> CartanType(["D", Integer(4), Integer(3)]).dynkin_diagram()
3
O=>=O---O
2 1 0
G2~* relabelled by {0: 0, 1: 2, 2: 1}
>>> CartanType(["E", Integer(6), Integer(2)]).dynkin_diagram()
O---O---O=<=O---O
0 1 2 3 4
F4~*
Additionally one can set the notation option to use Kac’s notation:
sage: # needs sage.graphs
sage: CartanType.options['notation'] = 'Kac'
sage: CartanType(["A", 9, 2])
['A', 9, 2]
sage: CartanType(["A", 9, 2]).dynkin_diagram()
O 0
|
|
O---O---O---O=<=O
1 2 3 4 5
A9^2
sage: CartanType(["A", 10, 2]).dynkin_diagram()
O=<=O---O---O---O=<=O
0 1 2 3 4 5
A10^2
sage: CartanType(["D", 5, 2]).dynkin_diagram()
O=<=O---O---O=>=O
0 1 2 3 4
D5^2
sage: CartanType(["D", 4, 3]).dynkin_diagram()
3
O=>=O---O
2 1 0
D4^3
sage: CartanType(["E", 6, 2]).dynkin_diagram()
O---O---O=<=O---O
0 1 2 3 4
E6^2
sage: CartanType.options['notation'] = 'BC'
>>> from sage.all import *
>>> # needs sage.graphs
>>> CartanType.options['notation'] = 'Kac'
>>> CartanType(["A", Integer(9), Integer(2)])
['A', 9, 2]
>>> CartanType(["A", Integer(9), Integer(2)]).dynkin_diagram()
O 0
|
|
O---O---O---O=<=O
1 2 3 4 5
A9^2
>>> CartanType(["A", Integer(10), Integer(2)]).dynkin_diagram()
O=<=O---O---O---O=<=O
0 1 2 3 4 5
A10^2
>>> CartanType(["D", Integer(5), Integer(2)]).dynkin_diagram()
O=<=O---O---O=>=O
0 1 2 3 4
D5^2
>>> CartanType(["D", Integer(4), Integer(3)]).dynkin_diagram()
3
O=>=O---O
2 1 0
D4^3
>>> CartanType(["E", Integer(6), Integer(2)]).dynkin_diagram()
O---O---O=<=O---O
0 1 2 3 4
E6^2
>>> CartanType.options['notation'] = 'BC'
Infinite Cartan types
There are minimal implementations of the Cartan types \(A_{\infty}\) and \(A_{+\infty}\). In sage \(oo\) is the same as \(+Infinity\), so \(NN\) and \(ZZ\) are used to differentiate between the \(A_{+\infty}\) and \(A_{\infty}\) root systems:
sage: CartanType(['A', NN])
['A', NN]
sage: print(CartanType(['A', NN]).ascii_art())
O---O---O---O---O---O---O---..
0 1 2 3 4 5 6
sage: CartanType(['A', ZZ])
['A', ZZ]
sage: print(CartanType(['A', ZZ]).ascii_art())
..---O---O---O---O---O---O---O---..
-3 -2 -1 0 1 2 3
>>> from sage.all import *
>>> CartanType(['A', NN])
['A', NN]
>>> print(CartanType(['A', NN]).ascii_art())
O---O---O---O---O---O---O---..
0 1 2 3 4 5 6
>>> CartanType(['A', ZZ])
['A', ZZ]
>>> print(CartanType(['A', ZZ]).ascii_art())
..---O---O---O---O---O---O---O---..
-3 -2 -1 0 1 2 3
There are also the following shorthands:
sage: CartanType("Aoo")
['A', ZZ]
sage: CartanType("A+oo")
['A', NN]
>>> from sage.all import *
>>> CartanType("Aoo")
['A', ZZ]
>>> CartanType("A+oo")
['A', NN]
Abstract classes for Cartan types
Concrete classes for Cartan types
Type specific data
The data essentially consists of a description of the Dynkin/Coxeter diagram and, when relevant, of the natural embedding of the root system in an Euclidean space. Everything else is reconstructed from this data.
Todo
Should those indexes come before the introduction?
- sage.combinat.root_system.cartan_type.CartanType(*args)[source]#
Cartan types
Todo
Why does sphinx complain if I use sections here?
Introduction
Loosely speaking, Dynkin diagrams (or equivalently Cartan matrices) are graphs which are used to classify root systems, Coxeter and Weyl groups, Lie algebras, Lie groups, crystals, etc. up to an isomorphism. Cartan types are a standard set of names for those Dynkin diagrams (see Wikipedia article Dynkin_diagram).
Let us consider, for example, the Cartan type \(A_4\):
sage: T = CartanType(['A', 4]); T ['A', 4]
>>> from sage.all import * >>> T = CartanType(['A', Integer(4)]); T ['A', 4]
It is the name of the following Dynkin diagram:
sage: DynkinDiagram(T) # needs sage.graphs O---O---O---O 1 2 3 4 A4
>>> from sage.all import * >>> DynkinDiagram(T) # needs sage.graphs O---O---O---O 1 2 3 4 A4
Note
For convenience, the following shortcuts are available:
sage: DynkinDiagram(['A',4]) # needs sage.graphs O---O---O---O 1 2 3 4 A4 sage: DynkinDiagram('A4') # needs sage.graphs O---O---O---O 1 2 3 4 A4 sage: T.dynkin_diagram() # needs sage.graphs O---O---O---O 1 2 3 4 A4
>>> from sage.all import * >>> DynkinDiagram(['A',Integer(4)]) # needs sage.graphs O---O---O---O 1 2 3 4 A4 >>> DynkinDiagram('A4') # needs sage.graphs O---O---O---O 1 2 3 4 A4 >>> T.dynkin_diagram() # needs sage.graphs O---O---O---O 1 2 3 4 A4
See
DynkinDiagram
for how to further manipulate Dynkin diagrams.From this data (the Cartan datum), one can construct the associated root system:
sage: RootSystem(T) Root system of type ['A', 4]
>>> from sage.all import * >>> RootSystem(T) Root system of type ['A', 4]
The associated Weyl group of \(A_n\) is the symmetric group \(S_{n+1}\):
sage: W = WeylGroup(T); W # needs sage.libs.gap Weyl Group of type ['A', 4] (as a matrix group acting on the ambient space) sage: W.cardinality() # needs sage.libs.gap 120
>>> from sage.all import * >>> W = WeylGroup(T); W # needs sage.libs.gap Weyl Group of type ['A', 4] (as a matrix group acting on the ambient space) >>> W.cardinality() # needs sage.libs.gap 120
while the Lie algebra is \(sl_{n+1}\), and the Lie group \(SL_{n+1}\) (TODO: illustrate this once this is implemented).
One may also construct crystals associated to various Dynkin diagrams. For example:
sage: C = crystals.Letters(T); C # needs sage.combinat The crystal of letters for type ['A', 4] sage: C.list() # needs sage.combinat [1, 2, 3, 4, 5] sage: C = crystals.Tableaux(T, shape=[2]); C # needs sage.combinat The crystal of tableaux of type ['A', 4] and shape(s) [[2]] sage: C.cardinality() # needs sage.combinat 15
>>> from sage.all import * >>> C = crystals.Letters(T); C # needs sage.combinat The crystal of letters for type ['A', 4] >>> C.list() # needs sage.combinat [1, 2, 3, 4, 5] >>> C = crystals.Tableaux(T, shape=[Integer(2)]); C # needs sage.combinat The crystal of tableaux of type ['A', 4] and shape(s) [[2]] >>> C.cardinality() # needs sage.combinat 15
Here is a sample of all the finite irreducible crystallographic Cartan types:
sage: CartanType.samples(finite=True, crystallographic=True) [['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2]]
>>> from sage.all import * >>> CartanType.samples(finite=True, crystallographic=True) [['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2]]
One can also get latex representations of the crystallographic Cartan types and their corresponding Dynkin diagrams:
sage: [latex(ct) for ct in CartanType.samples(crystallographic=True)] [A_{1}, A_{5}, B_{1}, B_{5}, C_{1}, C_{5}, D_{2}, D_{3}, D_{5}, E_6, E_7, E_8, F_4, G_2, A_{1}^{(1)}, A_{5}^{(1)}, B_{1}^{(1)}, B_{5}^{(1)}, C_{1}^{(1)}, C_{5}^{(1)}, D_{3}^{(1)}, D_{5}^{(1)}, E_6^{(1)}, E_7^{(1)}, E_8^{(1)}, F_4^{(1)}, G_2^{(1)}, BC_{1}^{(2)}, BC_{5}^{(2)}, B_{5}^{(1)\vee}, C_{4}^{(1)\vee}, F_4^{(1)\vee}, G_2^{(1)\vee}, BC_{1}^{(2)\vee}, BC_{5}^{(2)\vee}] sage: view([DynkinDiagram(ct) for ct in CartanType.samples(crystallographic=True)]) # not tested
>>> from sage.all import * >>> [latex(ct) for ct in CartanType.samples(crystallographic=True)] [A_{1}, A_{5}, B_{1}, B_{5}, C_{1}, C_{5}, D_{2}, D_{3}, D_{5}, E_6, E_7, E_8, F_4, G_2, A_{1}^{(1)}, A_{5}^{(1)}, B_{1}^{(1)}, B_{5}^{(1)}, C_{1}^{(1)}, C_{5}^{(1)}, D_{3}^{(1)}, D_{5}^{(1)}, E_6^{(1)}, E_7^{(1)}, E_8^{(1)}, F_4^{(1)}, G_2^{(1)}, BC_{1}^{(2)}, BC_{5}^{(2)}, B_{5}^{(1)\vee}, C_{4}^{(1)\vee}, F_4^{(1)\vee}, G_2^{(1)\vee}, BC_{1}^{(2)\vee}, BC_{5}^{(2)\vee}] >>> view([DynkinDiagram(ct) for ct in CartanType.samples(crystallographic=True)]) # not tested
Non-crystallographic Cartan types are also partially supported:
sage: CartanType.samples(finite=True, crystallographic=False) [['I', 5], ['H', 3], ['H', 4]]
>>> from sage.all import * >>> CartanType.samples(finite=True, crystallographic=False) [['I', 5], ['H', 3], ['H', 4]]
In Sage, a Cartan type is used as a database of type-specific information and algorithms (see e.g.
sage.combinat.root_system.type_A
). This database includes how to construct the Dynkin diagram, the ambient space for the root system (see Wikipedia article Root_system), and further mathematical properties:sage: T.is_finite(), T.is_simply_laced(), T.is_affine(), T.is_crystallographic() (True, True, False, True)
>>> from sage.all import * >>> T.is_finite(), T.is_simply_laced(), T.is_affine(), T.is_crystallographic() (True, True, False, True)
In particular, a Sage Cartan type is endowed with a fixed choice of labels for the nodes of the Dynkin diagram. This choice follows the conventions of Nicolas Bourbaki, Lie Groups and Lie Algebras: Chapter 4-6, Elements of Mathematics, Springer (2002). ISBN 978-3540426509. For example:
sage: T = CartanType(['D', 4]) sage: DynkinDiagram(T) # needs sage.graphs O 4 | | O---O---O 1 2 3 D4 sage: E6 = CartanType(['E',6]) sage: DynkinDiagram(E6) # needs sage.graphs O 2 | | O---O---O---O---O 1 3 4 5 6 E6
>>> from sage.all import * >>> T = CartanType(['D', Integer(4)]) >>> DynkinDiagram(T) # needs sage.graphs O 4 | | O---O---O 1 2 3 D4 >>> E6 = CartanType(['E',Integer(6)]) >>> DynkinDiagram(E6) # needs sage.graphs O 2 | | O---O---O---O---O 1 3 4 5 6 E6
Note
The direction of the arrows is the opposite (i.e. the transpose) of Bourbaki’s convention, but agrees with Kac’s.
For example, in type \(C_2\), we have:
sage: C2 = DynkinDiagram(['C',2]); C2 # needs sage.graphs O=<=O 1 2 C2 sage: C2.cartan_matrix() # needs sage.graphs [ 2 -2] [-1 2]
>>> from sage.all import * >>> C2 = DynkinDiagram(['C',Integer(2)]); C2 # needs sage.graphs O=<=O 1 2 C2 >>> C2.cartan_matrix() # needs sage.graphs [ 2 -2] [-1 2]
However Bourbaki would have the Cartan matrix as:
\[\begin{split}\begin{bmatrix} 2 & -1 \\ -2 & 2 \end{bmatrix}.\end{split}\]If desired, other node labelling conventions can be achieved. For example the Kac labelling for type \(E_6\) can be obtained via:
sage: E6.relabel({1:1,2:6,3:2,4:3,5:4,6:5}).dynkin_diagram() # needs sage.graphs O 6 | | O---O---O---O---O 1 2 3 4 5 E6 relabelled by {1: 1, 2: 6, 3: 2, 4: 3, 5: 4, 6: 5}
>>> from sage.all import * >>> E6.relabel({Integer(1):Integer(1),Integer(2):Integer(6),Integer(3):Integer(2),Integer(4):Integer(3),Integer(5):Integer(4),Integer(6):Integer(5)}).dynkin_diagram() # needs sage.graphs O 6 | | O---O---O---O---O 1 2 3 4 5 E6 relabelled by {1: 1, 2: 6, 3: 2, 4: 3, 5: 4, 6: 5}
Contributions implementing other conventions are very welcome.
Another option is to build from scratch a new Dynkin diagram. The architecture has been designed to make it fairly easy to add other labelling conventions. In particular, we strived at choosing type free algorithms whenever possible, so in principle most features should remain available even with custom Cartan types. This has not been used much yet, so some rough corners certainly remain.
Here, we construct the hyperbolic example of Exercise 4.9 p. 57 of Kac, Infinite Dimensional Lie Algebras. We start with an empty Dynkin diagram, and add a couple nodes:
sage: g = DynkinDiagram() # needs sage.graphs sage: g.add_vertices([1,2,3]) # needs sage.graphs
>>> from sage.all import * >>> g = DynkinDiagram() # needs sage.graphs >>> g.add_vertices([Integer(1),Integer(2),Integer(3)]) # needs sage.graphs
Note that the diagonal of the Cartan matrix is already initialized:
sage: g.cartan_matrix() # needs sage.graphs [2 0 0] [0 2 0] [0 0 2]
>>> from sage.all import * >>> g.cartan_matrix() # needs sage.graphs [2 0 0] [0 2 0] [0 0 2]
Then we add a couple edges:
sage: g.add_edge(1,2,2) # needs sage.graphs sage: g.add_edge(1,3) # needs sage.graphs sage: g.add_edge(2,3) # needs sage.graphs
>>> from sage.all import * >>> g.add_edge(Integer(1),Integer(2),Integer(2)) # needs sage.graphs >>> g.add_edge(Integer(1),Integer(3)) # needs sage.graphs >>> g.add_edge(Integer(2),Integer(3)) # needs sage.graphs
and we get the desired Cartan matrix:
sage: g.cartan_matrix() # needs sage.graphs [2 0 0] [0 2 0] [0 0 2]
>>> from sage.all import * >>> g.cartan_matrix() # needs sage.graphs [2 0 0] [0 2 0] [0 0 2]
Oops, the Cartan matrix did not change! This is because it is cached for efficiency (see
cached_method
). In general, a Dynkin diagram should not be modified after having been used.Warning
this is not checked currently
Todo
add a method
set_mutable()
as, say, for matricesHere, we can work around this by clearing the cache:
sage: delattr(g, 'cartan_matrix') # needs sage.graphs
>>> from sage.all import * >>> delattr(g, 'cartan_matrix') # needs sage.graphs
Now we get the desired Cartan matrix:
sage: g.cartan_matrix() # needs sage.graphs [ 2 -1 -1] [-2 2 -1] [-1 -1 2]
>>> from sage.all import * >>> g.cartan_matrix() # needs sage.graphs [ 2 -1 -1] [-2 2 -1] [-1 -1 2]
Note that backward edges have been automatically added:
sage: g.edges(sort=True) # needs sage.graphs [(1, 2, 2), (1, 3, 1), (2, 1, 1), (2, 3, 1), (3, 1, 1), (3, 2, 1)]
>>> from sage.all import * >>> g.edges(sort=True) # needs sage.graphs [(1, 2, 2), (1, 3, 1), (2, 1, 1), (2, 3, 1), (3, 1, 1), (3, 2, 1)]
Reducible Cartan types
Reducible Cartan types can be specified by passing a sequence or list of irreducible Cartan types:
sage: CartanType(['A',2],['B',2]) A2xB2 sage: CartanType([['A',2],['B',2]]) A2xB2 sage: CartanType(['A',2],['B',2]).is_reducible() True
>>> from sage.all import * >>> CartanType(['A',Integer(2)],['B',Integer(2)]) A2xB2 >>> CartanType([['A',Integer(2)],['B',Integer(2)]]) A2xB2 >>> CartanType(['A',Integer(2)],['B',Integer(2)]).is_reducible() True
or using the following short hand notation:
sage: CartanType("A2xB2") A2xB2 sage: CartanType("A2","B2") == CartanType("A2xB2") True
>>> from sage.all import * >>> CartanType("A2xB2") A2xB2 >>> CartanType("A2","B2") == CartanType("A2xB2") True
Degenerate cases
When possible, type \(I_n\) is automatically converted to the isomorphic crystallographic Cartan types (any reason not to do so?):
sage: CartanType(["I",1]) A1xA1 sage: CartanType(["I",3]) ['A', 2] sage: CartanType(["I",4]) ['C', 2] sage: CartanType(["I",6]) ['G', 2]
>>> from sage.all import * >>> CartanType(["I",Integer(1)]) A1xA1 >>> CartanType(["I",Integer(3)]) ['A', 2] >>> CartanType(["I",Integer(4)]) ['C', 2] >>> CartanType(["I",Integer(6)]) ['G', 2]
The Dynkin diagrams for types \(B_1\), \(C_1\), \(D_2\), and \(D_3\) are isomorphic to that for \(A_1\), \(A_1\), \(A_1 \times A_1\), and \(A_3\), respectively. However their natural ambient space realizations (stemming from the corresponding infinite families of Lie groups) are different. Therefore, the Cartan types are considered as distinct:
sage: CartanType(['B',1]) ['B', 1] sage: CartanType(['C',1]) ['C', 1] sage: CartanType(['D',2]) ['D', 2] sage: CartanType(['D',3]) ['D', 3]
>>> from sage.all import * >>> CartanType(['B',Integer(1)]) ['B', 1] >>> CartanType(['C',Integer(1)]) ['C', 1] >>> CartanType(['D',Integer(2)]) ['D', 2] >>> CartanType(['D',Integer(3)]) ['D', 3]
Affine Cartan types
For affine types, we use the usual conventions for affine Coxeter groups: each affine type is either untwisted (that is arise from the natural affinisation of a finite Cartan type):
sage: CartanType(["A", 4, 1]).dynkin_diagram() # needs sage.graphs 0 O-----------+ | | | | O---O---O---O 1 2 3 4 A4~ sage: CartanType(["B", 4, 1]).dynkin_diagram() # needs sage.graphs O 0 | | O---O---O=>=O 1 2 3 4 B4~
>>> from sage.all import * >>> CartanType(["A", Integer(4), Integer(1)]).dynkin_diagram() # needs sage.graphs 0 O-----------+ | | | | O---O---O---O 1 2 3 4 A4~ >>> CartanType(["B", Integer(4), Integer(1)]).dynkin_diagram() # needs sage.graphs O 0 | | O---O---O=>=O 1 2 3 4 B4~
or dual thereof:
sage: CartanType(["B", 4, 1]).dual().dynkin_diagram() # needs sage.graphs O 0 | | O---O---O=<=O 1 2 3 4 B4~*
>>> from sage.all import * >>> CartanType(["B", Integer(4), Integer(1)]).dual().dynkin_diagram() # needs sage.graphs O 0 | | O---O---O=<=O 1 2 3 4 B4~*
or is of type \(\widetilde{BC}_n\) (which yields an irreducible, but nonreduced root system):
sage: CartanType(["BC", 4, 2]).dynkin_diagram() # needs sage.graphs O=<=O---O---O=<=O 0 1 2 3 4 BC4~
>>> from sage.all import * >>> CartanType(["BC", Integer(4), Integer(2)]).dynkin_diagram() # needs sage.graphs O=<=O---O---O=<=O 0 1 2 3 4 BC4~
This includes the two degenerate cases:
sage: CartanType(["A", 1, 1]).dynkin_diagram() # needs sage.graphs O<=>O 0 1 A1~ sage: CartanType(["BC", 1, 2]).dynkin_diagram() # needs sage.graphs 4 O=<=O 0 1 BC1~
>>> from sage.all import * >>> CartanType(["A", Integer(1), Integer(1)]).dynkin_diagram() # needs sage.graphs O<=>O 0 1 A1~ >>> CartanType(["BC", Integer(1), Integer(2)]).dynkin_diagram() # needs sage.graphs 4 O=<=O 0 1 BC1~
For the user convenience, Kac’s notations for twisted affine types are automatically translated into the previous ones:
sage: # needs sage.graphs sage: CartanType(["A", 9, 2]) ['B', 5, 1]^* sage: CartanType(["A", 9, 2]).dynkin_diagram() O 0 | | O---O---O---O=<=O 1 2 3 4 5 B5~* sage: CartanType(["A", 10, 2]).dynkin_diagram() O=<=O---O---O---O=<=O 0 1 2 3 4 5 BC5~ sage: CartanType(["D", 5, 2]).dynkin_diagram() O=<=O---O---O=>=O 0 1 2 3 4 C4~* sage: CartanType(["D", 4, 3]).dynkin_diagram() 3 O=>=O---O 2 1 0 G2~* relabelled by {0: 0, 1: 2, 2: 1} sage: CartanType(["E", 6, 2]).dynkin_diagram() O---O---O=<=O---O 0 1 2 3 4 F4~*
>>> from sage.all import * >>> # needs sage.graphs >>> CartanType(["A", Integer(9), Integer(2)]) ['B', 5, 1]^* >>> CartanType(["A", Integer(9), Integer(2)]).dynkin_diagram() O 0 | | O---O---O---O=<=O 1 2 3 4 5 B5~* >>> CartanType(["A", Integer(10), Integer(2)]).dynkin_diagram() O=<=O---O---O---O=<=O 0 1 2 3 4 5 BC5~ >>> CartanType(["D", Integer(5), Integer(2)]).dynkin_diagram() O=<=O---O---O=>=O 0 1 2 3 4 C4~* >>> CartanType(["D", Integer(4), Integer(3)]).dynkin_diagram() 3 O=>=O---O 2 1 0 G2~* relabelled by {0: 0, 1: 2, 2: 1} >>> CartanType(["E", Integer(6), Integer(2)]).dynkin_diagram() O---O---O=<=O---O 0 1 2 3 4 F4~*
Additionally one can set the notation option to use Kac’s notation:
sage: # needs sage.graphs sage: CartanType.options['notation'] = 'Kac' sage: CartanType(["A", 9, 2]) ['A', 9, 2] sage: CartanType(["A", 9, 2]).dynkin_diagram() O 0 | | O---O---O---O=<=O 1 2 3 4 5 A9^2 sage: CartanType(["A", 10, 2]).dynkin_diagram() O=<=O---O---O---O=<=O 0 1 2 3 4 5 A10^2 sage: CartanType(["D", 5, 2]).dynkin_diagram() O=<=O---O---O=>=O 0 1 2 3 4 D5^2 sage: CartanType(["D", 4, 3]).dynkin_diagram() 3 O=>=O---O 2 1 0 D4^3 sage: CartanType(["E", 6, 2]).dynkin_diagram() O---O---O=<=O---O 0 1 2 3 4 E6^2 sage: CartanType.options['notation'] = 'BC'
>>> from sage.all import * >>> # needs sage.graphs >>> CartanType.options['notation'] = 'Kac' >>> CartanType(["A", Integer(9), Integer(2)]) ['A', 9, 2] >>> CartanType(["A", Integer(9), Integer(2)]).dynkin_diagram() O 0 | | O---O---O---O=<=O 1 2 3 4 5 A9^2 >>> CartanType(["A", Integer(10), Integer(2)]).dynkin_diagram() O=<=O---O---O---O=<=O 0 1 2 3 4 5 A10^2 >>> CartanType(["D", Integer(5), Integer(2)]).dynkin_diagram() O=<=O---O---O=>=O 0 1 2 3 4 D5^2 >>> CartanType(["D", Integer(4), Integer(3)]).dynkin_diagram() 3 O=>=O---O 2 1 0 D4^3 >>> CartanType(["E", Integer(6), Integer(2)]).dynkin_diagram() O---O---O=<=O---O 0 1 2 3 4 E6^2 >>> CartanType.options['notation'] = 'BC'
Infinite Cartan types
There are minimal implementations of the Cartan types \(A_{\infty}\) and \(A_{+\infty}\). In sage \(oo\) is the same as \(+Infinity\), so \(NN\) and \(ZZ\) are used to differentiate between the \(A_{+\infty}\) and \(A_{\infty}\) root systems:
sage: CartanType(['A', NN]) ['A', NN] sage: print(CartanType(['A', NN]).ascii_art()) O---O---O---O---O---O---O---.. 0 1 2 3 4 5 6 sage: CartanType(['A', ZZ]) ['A', ZZ] sage: print(CartanType(['A', ZZ]).ascii_art()) ..---O---O---O---O---O---O---O---.. -3 -2 -1 0 1 2 3
>>> from sage.all import * >>> CartanType(['A', NN]) ['A', NN] >>> print(CartanType(['A', NN]).ascii_art()) O---O---O---O---O---O---O---.. 0 1 2 3 4 5 6 >>> CartanType(['A', ZZ]) ['A', ZZ] >>> print(CartanType(['A', ZZ]).ascii_art()) ..---O---O---O---O---O---O---O---.. -3 -2 -1 0 1 2 3
There are also the following shorthands:
sage: CartanType("Aoo") ['A', ZZ] sage: CartanType("A+oo") ['A', NN]
>>> from sage.all import * >>> CartanType("Aoo") ['A', ZZ] >>> CartanType("A+oo") ['A', NN]
Abstract classes for Cartan types
Concrete classes for Cartan types
Type specific data
The data essentially consists of a description of the Dynkin/Coxeter diagram and, when relevant, of the natural embedding of the root system in an Euclidean space. Everything else is reconstructed from this data.
Todo
Should those indexes come before the introduction?
- class sage.combinat.root_system.cartan_type.CartanTypeFactory[source]#
Bases:
SageObject
- classmethod color(i)[source]#
Default color scheme for the vertices of a Dynkin diagram (and associated objects)
EXAMPLES:
sage: CartanType.color(1) 'blue' sage: CartanType.color(2) 'red' sage: CartanType.color(3) 'green'
>>> from sage.all import * >>> CartanType.color(Integer(1)) 'blue' >>> CartanType.color(Integer(2)) 'red' >>> CartanType.color(Integer(3)) 'green'
The default color is black:
sage: CartanType.color(0) 'black'
>>> from sage.all import * >>> CartanType.color(Integer(0)) 'black'
Negative indices get the same color as their positive counterparts:
sage: CartanType.color(-1) 'blue' sage: CartanType.color(-2) 'red' sage: CartanType.color(-3) 'green'
>>> from sage.all import * >>> CartanType.color(-Integer(1)) 'blue' >>> CartanType.color(-Integer(2)) 'red' >>> CartanType.color(-Integer(3)) 'green'
- options = Current options for CartanType - dual_latex: \vee - dual_str: * - latex_marked: True - latex_relabel: True - mark_special_node: none - marked_node_str: X - notation: Stembridge - special_node_str: @[source]#
- samples(finite=None, affine=None, crystallographic=None)[source]#
Return a sample of the available Cartan types.
INPUT:
finite
– a boolean orNone
(default:None
)affine
– a boolean orNone
(default:None
)crystallographic
– a boolean orNone
(default:None
)
The sample contains all the exceptional finite and affine Cartan types, as well as typical representatives of the infinite families.
EXAMPLES:
sage: CartanType.samples() [['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['I', 5], ['H', 3], ['H', 4], ['A', 1, 1], ['A', 5, 1], ['B', 1, 1], ['B', 5, 1], ['C', 1, 1], ['C', 5, 1], ['D', 3, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['BC', 1, 2], ['BC', 5, 2], ['B', 5, 1]^*, ['C', 4, 1]^*, ['F', 4, 1]^*, ['G', 2, 1]^*, ['BC', 1, 2]^*, ['BC', 5, 2]^*]
>>> from sage.all import * >>> CartanType.samples() [['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['I', 5], ['H', 3], ['H', 4], ['A', 1, 1], ['A', 5, 1], ['B', 1, 1], ['B', 5, 1], ['C', 1, 1], ['C', 5, 1], ['D', 3, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['BC', 1, 2], ['BC', 5, 2], ['B', 5, 1]^*, ['C', 4, 1]^*, ['F', 4, 1]^*, ['G', 2, 1]^*, ['BC', 1, 2]^*, ['BC', 5, 2]^*]
The finite, affine and crystallographic options allow respectively for restricting to (non) finite, (non) affine, and (non) crystallographic Cartan types:
sage: CartanType.samples(finite=True) [['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['I', 5], ['H', 3], ['H', 4]] sage: CartanType.samples(affine=True) [['A', 1, 1], ['A', 5, 1], ['B', 1, 1], ['B', 5, 1], ['C', 1, 1], ['C', 5, 1], ['D', 3, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['BC', 1, 2], ['BC', 5, 2], ['B', 5, 1]^*, ['C', 4, 1]^*, ['F', 4, 1]^*, ['G', 2, 1]^*, ['BC', 1, 2]^*, ['BC', 5, 2]^*] sage: CartanType.samples(crystallographic=True) [['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['A', 1, 1], ['A', 5, 1], ['B', 1, 1], ['B', 5, 1], ['C', 1, 1], ['C', 5, 1], ['D', 3, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['BC', 1, 2], ['BC', 5, 2], ['B', 5, 1]^*, ['C', 4, 1]^*, ['F', 4, 1]^*, ['G', 2, 1]^*, ['BC', 1, 2]^*, ['BC', 5, 2]^*] sage: CartanType.samples(crystallographic=False) [['I', 5], ['H', 3], ['H', 4]]
>>> from sage.all import * >>> CartanType.samples(finite=True) [['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['I', 5], ['H', 3], ['H', 4]] >>> CartanType.samples(affine=True) [['A', 1, 1], ['A', 5, 1], ['B', 1, 1], ['B', 5, 1], ['C', 1, 1], ['C', 5, 1], ['D', 3, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['BC', 1, 2], ['BC', 5, 2], ['B', 5, 1]^*, ['C', 4, 1]^*, ['F', 4, 1]^*, ['G', 2, 1]^*, ['BC', 1, 2]^*, ['BC', 5, 2]^*] >>> CartanType.samples(crystallographic=True) [['A', 1], ['A', 5], ['B', 1], ['B', 5], ['C', 1], ['C', 5], ['D', 2], ['D', 3], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['A', 1, 1], ['A', 5, 1], ['B', 1, 1], ['B', 5, 1], ['C', 1, 1], ['C', 5, 1], ['D', 3, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['BC', 1, 2], ['BC', 5, 2], ['B', 5, 1]^*, ['C', 4, 1]^*, ['F', 4, 1]^*, ['G', 2, 1]^*, ['BC', 1, 2]^*, ['BC', 5, 2]^*] >>> CartanType.samples(crystallographic=False) [['I', 5], ['H', 3], ['H', 4]]
Todo
add some reducible Cartan types (suggestions?)
- class sage.combinat.root_system.cartan_type.CartanType_abstract[source]#
Bases:
object
Abstract class for Cartan types
Subclasses should implement:
dynkin_diagram()
cartan_matrix()
- as_folding(folding_of=None, sigma=None)[source]#
Return
self
realized as a folded Cartan type.For finite and affine types, this is realized by the Dynkin diagram foldings:
\[\begin{split}\begin{array}{ccl} C_n^{(1)}, A_{2n}^{(2)}, A_{2n}^{(2)\dagger}, D_{n+1}^{(2)} & \hookrightarrow & A_{2n-1}^{(1)}, \\ A_{2n-1}^{(2)}, B_n^{(1)} & \hookrightarrow & D_{n+1}^{(1)}, \\ E_6^{(2)}, F_4^{(1)} & \hookrightarrow & E_6^{(1)}, \\ D_4^{(3)}, G_2^{(1)} & \hookrightarrow & D_4^{(1)}, \\ C_n & \hookrightarrow & A_{2n-1}, \\ B_n & \hookrightarrow & D_{n+1}, \\ F_4 & \hookrightarrow & E_6, \\ G_2 & \hookrightarrow & D_4. \end{array}\end{split}\]For general types, this returns
self
as a folded type ofself
with \(\sigma\) as the identity map.For more information on these foldings and folded Cartan types, see
sage.combinat.root_system.type_folded.CartanTypeFolded
.If the optional inputs
folding_of
andsigma
are specified, then this returns the folded Cartan type ofself
infolding_of
given by the automorphismsigma
.EXAMPLES:
sage: CartanType(['B', 3, 1]).as_folding() ['B', 3, 1] as a folding of ['D', 4, 1] sage: CartanType(['F', 4]).as_folding() ['F', 4] as a folding of ['E', 6] sage: CartanType(['BC', 3, 2]).as_folding() ['BC', 3, 2] as a folding of ['A', 5, 1] sage: CartanType(['D', 4, 3]).as_folding() ['G', 2, 1]^* relabelled by {0: 0, 1: 2, 2: 1} as a folding of ['D', 4, 1]
>>> from sage.all import * >>> CartanType(['B', Integer(3), Integer(1)]).as_folding() ['B', 3, 1] as a folding of ['D', 4, 1] >>> CartanType(['F', Integer(4)]).as_folding() ['F', 4] as a folding of ['E', 6] >>> CartanType(['BC', Integer(3), Integer(2)]).as_folding() ['BC', 3, 2] as a folding of ['A', 5, 1] >>> CartanType(['D', Integer(4), Integer(3)]).as_folding() ['G', 2, 1]^* relabelled by {0: 0, 1: 2, 2: 1} as a folding of ['D', 4, 1]
- coxeter_diagram()[source]#
Return the Coxeter diagram for
self
.EXAMPLES:
sage: # needs sage.graphs sage: CartanType(['B',3]).coxeter_diagram() Graph on 3 vertices sage: CartanType(['A',3]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 3)] sage: CartanType(['B',3]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 4)] sage: CartanType(['G',2]).coxeter_diagram().edges(sort=True) [(1, 2, 6)] sage: CartanType(['F',4]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 4), (3, 4, 3)]
>>> from sage.all import * >>> # needs sage.graphs >>> CartanType(['B',Integer(3)]).coxeter_diagram() Graph on 3 vertices >>> CartanType(['A',Integer(3)]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 3)] >>> CartanType(['B',Integer(3)]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 4)] >>> CartanType(['G',Integer(2)]).coxeter_diagram().edges(sort=True) [(1, 2, 6)] >>> CartanType(['F',Integer(4)]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 4), (3, 4, 3)]
- coxeter_matrix()[source]#
Return the Coxeter matrix for
self
.EXAMPLES:
sage: CartanType(['A', 4]).coxeter_matrix() # needs sage.graphs [1 3 2 2] [3 1 3 2] [2 3 1 3] [2 2 3 1]
>>> from sage.all import * >>> CartanType(['A', Integer(4)]).coxeter_matrix() # needs sage.graphs [1 3 2 2] [3 1 3 2] [2 3 1 3] [2 2 3 1]
- coxeter_type()[source]#
Return the Coxeter type for
self
.EXAMPLES:
sage: CartanType(['A', 4]).coxeter_type() Coxeter type of ['A', 4]
>>> from sage.all import * >>> CartanType(['A', Integer(4)]).coxeter_type() Coxeter type of ['A', 4]
- dual()[source]#
Return the dual Cartan type, possibly just as a formal dual.
EXAMPLES:
sage: CartanType(['A',3]).dual() ['A', 3] sage: CartanType(["B", 3]).dual() ['C', 3] sage: CartanType(['C',2]).dual() ['B', 2] sage: CartanType(['D',4]).dual() ['D', 4] sage: CartanType(['E',8]).dual() ['E', 8] sage: CartanType(['F',4]).dual() ['F', 4] relabelled by {1: 4, 2: 3, 3: 2, 4: 1}
>>> from sage.all import * >>> CartanType(['A',Integer(3)]).dual() ['A', 3] >>> CartanType(["B", Integer(3)]).dual() ['C', 3] >>> CartanType(['C',Integer(2)]).dual() ['B', 2] >>> CartanType(['D',Integer(4)]).dual() ['D', 4] >>> CartanType(['E',Integer(8)]).dual() ['E', 8] >>> CartanType(['F',Integer(4)]).dual() ['F', 4] relabelled by {1: 4, 2: 3, 3: 2, 4: 1}
- index_set()[source]#
Return the index set for
self
.This is the list of the nodes of the associated Coxeter or Dynkin diagram.
EXAMPLES:
sage: CartanType(['A', 3, 1]).index_set() (0, 1, 2, 3) sage: CartanType(['D', 4]).index_set() (1, 2, 3, 4) sage: CartanType(['A', 7, 2]).index_set() (0, 1, 2, 3, 4) sage: CartanType(['A', 7, 2]).index_set() (0, 1, 2, 3, 4) sage: CartanType(['A', 6, 2]).index_set() (0, 1, 2, 3) sage: CartanType(['D', 6, 2]).index_set() (0, 1, 2, 3, 4, 5) sage: CartanType(['E', 6, 1]).index_set() (0, 1, 2, 3, 4, 5, 6) sage: CartanType(['E', 6, 2]).index_set() (0, 1, 2, 3, 4) sage: CartanType(['A', 2, 2]).index_set() (0, 1) sage: CartanType(['G', 2, 1]).index_set() (0, 1, 2) sage: CartanType(['F', 4, 1]).index_set() (0, 1, 2, 3, 4)
>>> from sage.all import * >>> CartanType(['A', Integer(3), Integer(1)]).index_set() (0, 1, 2, 3) >>> CartanType(['D', Integer(4)]).index_set() (1, 2, 3, 4) >>> CartanType(['A', Integer(7), Integer(2)]).index_set() (0, 1, 2, 3, 4) >>> CartanType(['A', Integer(7), Integer(2)]).index_set() (0, 1, 2, 3, 4) >>> CartanType(['A', Integer(6), Integer(2)]).index_set() (0, 1, 2, 3) >>> CartanType(['D', Integer(6), Integer(2)]).index_set() (0, 1, 2, 3, 4, 5) >>> CartanType(['E', Integer(6), Integer(1)]).index_set() (0, 1, 2, 3, 4, 5, 6) >>> CartanType(['E', Integer(6), Integer(2)]).index_set() (0, 1, 2, 3, 4) >>> CartanType(['A', Integer(2), Integer(2)]).index_set() (0, 1) >>> CartanType(['G', Integer(2), Integer(1)]).index_set() (0, 1, 2) >>> CartanType(['F', Integer(4), Integer(1)]).index_set() (0, 1, 2, 3, 4)
- is_affine()[source]#
Return whether
self
is affine.EXAMPLES:
sage: CartanType(['A', 3]).is_affine() False sage: CartanType(['A', 3, 1]).is_affine() True
>>> from sage.all import * >>> CartanType(['A', Integer(3)]).is_affine() False >>> CartanType(['A', Integer(3), Integer(1)]).is_affine() True
- is_atomic()[source]#
This method is usually equivalent to
is_reducible()
, except for the Cartan type \(D_2\).\(D_2\) is not a standard Cartan type. It is equivalent to type \(A_1 \times A_1\) which is reducible; however the isomorphism from its ambient space (for the orthogonal group of degree 4) to that of \(A_1 \times A_1\) is non trivial, and it is useful to have it.
From a programming point of view its implementation is more similar to the irreducible types, and so the method
is_atomic()
is supplied.EXAMPLES:
sage: CartanType("D2").is_atomic() True sage: CartanType("D2").is_irreducible() False
>>> from sage.all import * >>> CartanType("D2").is_atomic() True >>> CartanType("D2").is_irreducible() False
- is_compound()[source]#
A short hand for not
is_atomic()
.
- is_crystallographic()[source]#
Return whether this Cartan type is crystallographic.
This returns
False
by default. Derived class should override this appropriately.EXAMPLES:
sage: [ [t, t.is_crystallographic() ] for t in CartanType.samples(finite=True) ] [[['A', 1], True], [['A', 5], True], [['B', 1], True], [['B', 5], True], [['C', 1], True], [['C', 5], True], [['D', 2], True], [['D', 3], True], [['D', 5], True], [['E', 6], True], [['E', 7], True], [['E', 8], True], [['F', 4], True], [['G', 2], True], [['I', 5], False], [['H', 3], False], [['H', 4], False]]
>>> from sage.all import * >>> [ [t, t.is_crystallographic() ] for t in CartanType.samples(finite=True) ] [[['A', 1], True], [['A', 5], True], [['B', 1], True], [['B', 5], True], [['C', 1], True], [['C', 5], True], [['D', 2], True], [['D', 3], True], [['D', 5], True], [['E', 6], True], [['E', 7], True], [['E', 8], True], [['F', 4], True], [['G', 2], True], [['I', 5], False], [['H', 3], False], [['H', 4], False]]
- is_finite()[source]#
Return whether this Cartan type is finite.
EXAMPLES:
sage: from sage.combinat.root_system.cartan_type import CartanType_abstract sage: C = CartanType_abstract() sage: C.is_finite() Traceback (most recent call last): ... NotImplementedError: <abstract method is_finite at ...>
>>> from sage.all import * >>> from sage.combinat.root_system.cartan_type import CartanType_abstract >>> C = CartanType_abstract() >>> C.is_finite() Traceback (most recent call last): ... NotImplementedError: <abstract method is_finite at ...>
sage: CartanType(['A',4]).is_finite() True sage: CartanType(['A',4, 1]).is_finite() False
>>> from sage.all import * >>> CartanType(['A',Integer(4)]).is_finite() True >>> CartanType(['A',Integer(4), Integer(1)]).is_finite() False
- is_implemented()[source]#
Check whether the Cartan datum for
self
is actually implemented.EXAMPLES:
sage: CartanType(["A",4,1]).is_implemented() # needs sage.graphs True sage: CartanType(['H',3]).is_implemented() True
>>> from sage.all import * >>> CartanType(["A",Integer(4),Integer(1)]).is_implemented() # needs sage.graphs True >>> CartanType(['H',Integer(3)]).is_implemented() True
- is_irreducible()[source]#
Report whether this Cartan type is irreducible (i.e. simple). This should be overridden in any subclass.
This returns
False
by default. Derived class should override this appropriately.EXAMPLES:
sage: from sage.combinat.root_system.cartan_type import CartanType_abstract sage: C = CartanType_abstract() sage: C.is_irreducible() False
>>> from sage.all import * >>> from sage.combinat.root_system.cartan_type import CartanType_abstract >>> C = CartanType_abstract() >>> C.is_irreducible() False
- is_reducible()[source]#
Report whether the root system is reducible (i.e. not simple), that is whether it can be factored as a product of root systems.
EXAMPLES:
sage: CartanType("A2xB3").is_reducible() True sage: CartanType(['A',2]).is_reducible() False
>>> from sage.all import * >>> CartanType("A2xB3").is_reducible() True >>> CartanType(['A',Integer(2)]).is_reducible() False
- is_simply_laced()[source]#
Return whether this Cartan type is simply laced.
This returns
False
by default. Derived class should override this appropriately.EXAMPLES:
sage: [ [t, t.is_simply_laced() ] for t in CartanType.samples() ] [[['A', 1], True], [['A', 5], True], [['B', 1], True], [['B', 5], False], [['C', 1], True], [['C', 5], False], [['D', 2], True], [['D', 3], True], [['D', 5], True], [['E', 6], True], [['E', 7], True], [['E', 8], True], [['F', 4], False], [['G', 2], False], [['I', 5], False], [['H', 3], False], [['H', 4], False], [['A', 1, 1], False], [['A', 5, 1], True], [['B', 1, 1], False], [['B', 5, 1], False], [['C', 1, 1], False], [['C', 5, 1], False], [['D', 3, 1], True], [['D', 5, 1], True], [['E', 6, 1], True], [['E', 7, 1], True], [['E', 8, 1], True], [['F', 4, 1], False], [['G', 2, 1], False], [['BC', 1, 2], False], [['BC', 5, 2], False], [['B', 5, 1]^*, False], [['C', 4, 1]^*, False], [['F', 4, 1]^*, False], [['G', 2, 1]^*, False], [['BC', 1, 2]^*, False], [['BC', 5, 2]^*, False]]
>>> from sage.all import * >>> [ [t, t.is_simply_laced() ] for t in CartanType.samples() ] [[['A', 1], True], [['A', 5], True], [['B', 1], True], [['B', 5], False], [['C', 1], True], [['C', 5], False], [['D', 2], True], [['D', 3], True], [['D', 5], True], [['E', 6], True], [['E', 7], True], [['E', 8], True], [['F', 4], False], [['G', 2], False], [['I', 5], False], [['H', 3], False], [['H', 4], False], [['A', 1, 1], False], [['A', 5, 1], True], [['B', 1, 1], False], [['B', 5, 1], False], [['C', 1, 1], False], [['C', 5, 1], False], [['D', 3, 1], True], [['D', 5, 1], True], [['E', 6, 1], True], [['E', 7, 1], True], [['E', 8, 1], True], [['F', 4, 1], False], [['G', 2, 1], False], [['BC', 1, 2], False], [['BC', 5, 2], False], [['B', 5, 1]^*, False], [['C', 4, 1]^*, False], [['F', 4, 1]^*, False], [['G', 2, 1]^*, False], [['BC', 1, 2]^*, False], [['BC', 5, 2]^*, False]]
- marked_nodes(marked_nodes)[source]#
Return a Cartan type with the nodes
marked_nodes
marked.INPUT:
marked_nodes
– a list of nodes to mark
EXAMPLES:
sage: CartanType(['F',4]).marked_nodes([1, 3]).dynkin_diagram() # needs sage.graphs X---O=>=X---O 1 2 3 4 F4 with nodes (1, 3) marked
>>> from sage.all import * >>> CartanType(['F',Integer(4)]).marked_nodes([Integer(1), Integer(3)]).dynkin_diagram() # needs sage.graphs X---O=>=X---O 1 2 3 4 F4 with nodes (1, 3) marked
- options = Current options for CartanType - dual_latex: \vee - dual_str: * - latex_marked: True - latex_relabel: True - mark_special_node: none - marked_node_str: X - notation: Stembridge - special_node_str: @[source]#
- rank()[source]#
Return the rank of
self
.This is the number of nodes of the associated Coxeter or Dynkin diagram.
EXAMPLES:
sage: CartanType(['A', 4]).rank() 4 sage: CartanType(['A', 7, 2]).rank() 5 sage: CartanType(['I', 8]).rank() 2
>>> from sage.all import * >>> CartanType(['A', Integer(4)]).rank() 4 >>> CartanType(['A', Integer(7), Integer(2)]).rank() 5 >>> CartanType(['I', Integer(8)]).rank() 2
- relabel(relabelling)[source]#
Return a relabelled copy of this Cartan type.
INPUT:
relabelling
– a function (or a list or dictionary)
OUTPUT:
an isomorphic Cartan type obtained by relabelling the nodes of the Dynkin diagram. Namely, the node with label
i
is relabelledf(i)
(or, byf[i]
iff
is a list or dictionary).EXAMPLES:
sage: CartanType(['F',4]).relabel({ 1:4, 2:3, 3:2, 4:1 }).dynkin_diagram() # needs sage.graphs O---O=>=O---O 4 3 2 1 F4 relabelled by {1: 4, 2: 3, 3: 2, 4: 1}
>>> from sage.all import * >>> CartanType(['F',Integer(4)]).relabel({ Integer(1):Integer(4), Integer(2):Integer(3), Integer(3):Integer(2), Integer(4):Integer(1) }).dynkin_diagram() # needs sage.graphs O---O=>=O---O 4 3 2 1 F4 relabelled by {1: 4, 2: 3, 3: 2, 4: 1}
- root_system()[source]#
Return the root system associated to
self
.EXAMPLES:
sage: CartanType(['A',4]).root_system() Root system of type ['A', 4]
>>> from sage.all import * >>> CartanType(['A',Integer(4)]).root_system() Root system of type ['A', 4]
- subtype(index_set)[source]#
Return a subtype of
self
given byindex_set
.A subtype can be considered the Dynkin diagram induced from the Dynkin diagram of
self
byindex_set
.EXAMPLES:
sage: ct = CartanType(['A',6,2]) sage: ct.dynkin_diagram() # needs sage.graphs O=<=O---O=<=O 0 1 2 3 BC3~ sage: ct.subtype([1,2,3]) # needs sage.graphs ['C', 3]
>>> from sage.all import * >>> ct = CartanType(['A',Integer(6),Integer(2)]) >>> ct.dynkin_diagram() # needs sage.graphs O=<=O---O=<=O 0 1 2 3 BC3~ >>> ct.subtype([Integer(1),Integer(2),Integer(3)]) # needs sage.graphs ['C', 3]
- type()[source]#
Return the type of
self
, orNone
if unknown.This method should be overridden in any subclass.
EXAMPLES:
sage: from sage.combinat.root_system.cartan_type import CartanType_abstract sage: C = CartanType_abstract() sage: C.type() is None True
>>> from sage.all import * >>> from sage.combinat.root_system.cartan_type import CartanType_abstract >>> C = CartanType_abstract() >>> C.type() is None True
- class sage.combinat.root_system.cartan_type.CartanType_affine[source]#
Bases:
CartanType_simple
,CartanType_crystallographic
An abstract class for simple affine Cartan types
- AmbientSpace[source]#
alias of
AmbientSpace
- a()[source]#
Return the unique minimal non trivial annihilating linear combination of \(\alpha^\vee_0, \alpha^\vee, \ldots, \alpha^\vee\) with nonnegative coefficients (or alternatively, the unique minimal non trivial annihilating linear combination of the columns of the Cartan matrix with non-negative coefficients).
Throw an error if the existence or uniqueness does not hold
FIXME: the current implementation assumes that the Cartan matrix is indexed by \([0,1,...]\), in the same order as the index set.
EXAMPLES:
sage: # needs sage.graphs sage: RootSystem(['C',2,1]).cartan_type().a() Finite family {0: 1, 1: 2, 2: 1} sage: RootSystem(['D',4,1]).cartan_type().a() Finite family {0: 1, 1: 1, 2: 2, 3: 1, 4: 1} sage: RootSystem(['F',4,1]).cartan_type().a() Finite family {0: 1, 1: 2, 2: 3, 3: 4, 4: 2} sage: RootSystem(['BC',4,2]).cartan_type().a() Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
>>> from sage.all import * >>> # needs sage.graphs >>> RootSystem(['C',Integer(2),Integer(1)]).cartan_type().a() Finite family {0: 1, 1: 2, 2: 1} >>> RootSystem(['D',Integer(4),Integer(1)]).cartan_type().a() Finite family {0: 1, 1: 1, 2: 2, 3: 1, 4: 1} >>> RootSystem(['F',Integer(4),Integer(1)]).cartan_type().a() Finite family {0: 1, 1: 2, 2: 3, 3: 4, 4: 2} >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().a() Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
a
is a shortcut for col_annihilator:sage: RootSystem(['BC',4,2]).cartan_type().col_annihilator() # needs sage.graphs Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
>>> from sage.all import * >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().col_annihilator() # needs sage.graphs Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
- acheck(m=None)[source]#
Return the unique minimal non trivial annihilating linear combination of \(\alpha_0, \alpha_1, \ldots, \alpha_n\) with nonnegative coefficients (or alternatively, the unique minimal non trivial annihilating linear combination of the rows of the Cartan matrix with non-negative coefficients).
Throw an error if the existence of uniqueness does not hold
The optional argument
m
is for internal use only.EXAMPLES:
sage: # needs sage.graphs sage: RootSystem(['C',2,1]).cartan_type().acheck() Finite family {0: 1, 1: 1, 2: 1} sage: RootSystem(['D',4,1]).cartan_type().acheck() Finite family {0: 1, 1: 1, 2: 2, 3: 1, 4: 1} sage: RootSystem(['F',4,1]).cartan_type().acheck() Finite family {0: 1, 1: 2, 2: 3, 3: 2, 4: 1} sage: RootSystem(['BC',4,2]).cartan_type().acheck() Finite family {0: 1, 1: 2, 2: 2, 3: 2, 4: 2}
>>> from sage.all import * >>> # needs sage.graphs >>> RootSystem(['C',Integer(2),Integer(1)]).cartan_type().acheck() Finite family {0: 1, 1: 1, 2: 1} >>> RootSystem(['D',Integer(4),Integer(1)]).cartan_type().acheck() Finite family {0: 1, 1: 1, 2: 2, 3: 1, 4: 1} >>> RootSystem(['F',Integer(4),Integer(1)]).cartan_type().acheck() Finite family {0: 1, 1: 2, 2: 3, 3: 2, 4: 1} >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().acheck() Finite family {0: 1, 1: 2, 2: 2, 3: 2, 4: 2}
acheck
is a shortcut for row_annihilator:sage: RootSystem(['BC',4,2]).cartan_type().row_annihilator() # needs sage.graphs Finite family {0: 1, 1: 2, 2: 2, 3: 2, 4: 2}
>>> from sage.all import * >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().row_annihilator() # needs sage.graphs Finite family {0: 1, 1: 2, 2: 2, 3: 2, 4: 2}
FIXME:
The current implementation assumes that the Cartan matrix is indexed by \([0,1,...]\), in the same order as the index set.
This really should be a method of
CartanMatrix
.
- basic_untwisted()[source]#
Return the basic untwisted Cartan type associated with this affine Cartan type.
Given an affine type \(X_n^{(r)}\), the basic untwisted type is \(X_n\). In other words, it is the classical Cartan type that is twisted to obtain
self
.EXAMPLES:
sage: CartanType(['A', 1, 1]).basic_untwisted() ['A', 1] sage: CartanType(['A', 3, 1]).basic_untwisted() ['A', 3] sage: CartanType(['B', 3, 1]).basic_untwisted() ['B', 3] sage: CartanType(['E', 6, 1]).basic_untwisted() ['E', 6] sage: CartanType(['G', 2, 1]).basic_untwisted() ['G', 2] sage: CartanType(['A', 2, 2]).basic_untwisted() ['A', 2] sage: CartanType(['A', 4, 2]).basic_untwisted() ['A', 4] sage: CartanType(['A', 11, 2]).basic_untwisted() ['A', 11] sage: CartanType(['D', 5, 2]).basic_untwisted() ['D', 5] sage: CartanType(['E', 6, 2]).basic_untwisted() ['E', 6] sage: CartanType(['D', 4, 3]).basic_untwisted() ['D', 4]
>>> from sage.all import * >>> CartanType(['A', Integer(1), Integer(1)]).basic_untwisted() ['A', 1] >>> CartanType(['A', Integer(3), Integer(1)]).basic_untwisted() ['A', 3] >>> CartanType(['B', Integer(3), Integer(1)]).basic_untwisted() ['B', 3] >>> CartanType(['E', Integer(6), Integer(1)]).basic_untwisted() ['E', 6] >>> CartanType(['G', Integer(2), Integer(1)]).basic_untwisted() ['G', 2] >>> CartanType(['A', Integer(2), Integer(2)]).basic_untwisted() ['A', 2] >>> CartanType(['A', Integer(4), Integer(2)]).basic_untwisted() ['A', 4] >>> CartanType(['A', Integer(11), Integer(2)]).basic_untwisted() ['A', 11] >>> CartanType(['D', Integer(5), Integer(2)]).basic_untwisted() ['D', 5] >>> CartanType(['E', Integer(6), Integer(2)]).basic_untwisted() ['E', 6] >>> CartanType(['D', Integer(4), Integer(3)]).basic_untwisted() ['D', 4]
- c()[source]#
Returns the family (c_i)_i of integer coefficients defined by \(c_i=max(1, a_i/a^vee_i)\) (see e.g. [FSS07] p. 3)
FIXME: the current implementation assumes that the Cartan matrix is indexed by \([0,1,...]\), in the same order as the index set.
EXAMPLES:
sage: # needs sage.graphs sage: RootSystem(['C',2,1]).cartan_type().c() Finite family {0: 1, 1: 2, 2: 1} sage: RootSystem(['D',4,1]).cartan_type().c() Finite family {0: 1, 1: 1, 2: 1, 3: 1, 4: 1} sage: RootSystem(['F',4,1]).cartan_type().c() Finite family {0: 1, 1: 1, 2: 1, 3: 2, 4: 2} sage: RootSystem(['BC',4,2]).cartan_type().c() Finite family {0: 2, 1: 1, 2: 1, 3: 1, 4: 1}
>>> from sage.all import * >>> # needs sage.graphs >>> RootSystem(['C',Integer(2),Integer(1)]).cartan_type().c() Finite family {0: 1, 1: 2, 2: 1} >>> RootSystem(['D',Integer(4),Integer(1)]).cartan_type().c() Finite family {0: 1, 1: 1, 2: 1, 3: 1, 4: 1} >>> RootSystem(['F',Integer(4),Integer(1)]).cartan_type().c() Finite family {0: 1, 1: 1, 2: 1, 3: 2, 4: 2} >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().c() Finite family {0: 2, 1: 1, 2: 1, 3: 1, 4: 1}
REFERENCES:
[FSS07]G. Fourier, A. Schilling, and M. Shimozono, Demazure structure inside Kirillov-Reshetikhin crystals, J. Algebra, Vol. 309, (2007), p. 386-404 arXiv math/0605451
- classical()[source]#
Return the classical Cartan type associated with this affine Cartan type.
EXAMPLES:
sage: CartanType(['A', 1, 1]).classical() ['A', 1] sage: CartanType(['A', 3, 1]).classical() ['A', 3] sage: CartanType(['B', 3, 1]).classical() ['B', 3] sage: CartanType(['A', 2, 2]).classical() ['C', 1] sage: CartanType(['BC', 1, 2]).classical() ['C', 1] sage: CartanType(['A', 4, 2]).classical() ['C', 2] sage: CartanType(['BC', 2, 2]).classical() ['C', 2] sage: CartanType(['A', 10, 2]).classical() ['C', 5] sage: CartanType(['BC', 5, 2]).classical() ['C', 5] sage: CartanType(['D', 5, 2]).classical() ['B', 4] sage: CartanType(['E', 6, 1]).classical() ['E', 6] sage: CartanType(['G', 2, 1]).classical() ['G', 2] sage: CartanType(['E', 6, 2]).classical() ['F', 4] relabelled by {1: 4, 2: 3, 3: 2, 4: 1} sage: CartanType(['D', 4, 3]).classical() ['G', 2]
>>> from sage.all import * >>> CartanType(['A', Integer(1), Integer(1)]).classical() ['A', 1] >>> CartanType(['A', Integer(3), Integer(1)]).classical() ['A', 3] >>> CartanType(['B', Integer(3), Integer(1)]).classical() ['B', 3] >>> CartanType(['A', Integer(2), Integer(2)]).classical() ['C', 1] >>> CartanType(['BC', Integer(1), Integer(2)]).classical() ['C', 1] >>> CartanType(['A', Integer(4), Integer(2)]).classical() ['C', 2] >>> CartanType(['BC', Integer(2), Integer(2)]).classical() ['C', 2] >>> CartanType(['A', Integer(10), Integer(2)]).classical() ['C', 5] >>> CartanType(['BC', Integer(5), Integer(2)]).classical() ['C', 5] >>> CartanType(['D', Integer(5), Integer(2)]).classical() ['B', 4] >>> CartanType(['E', Integer(6), Integer(1)]).classical() ['E', 6] >>> CartanType(['G', Integer(2), Integer(1)]).classical() ['G', 2] >>> CartanType(['E', Integer(6), Integer(2)]).classical() ['F', 4] relabelled by {1: 4, 2: 3, 3: 2, 4: 1} >>> CartanType(['D', Integer(4), Integer(3)]).classical() ['G', 2]
We check that
classical()
,sage.combinat.root_system.cartan_type.CartanType_crystallographic.dynkin_diagram()
, andspecial_node()
are consistent:sage: for ct in CartanType.samples(affine=True): # needs sage.graphs ....: g1 = ct.classical().dynkin_diagram() ....: g2 = ct.dynkin_diagram() ....: g2.delete_vertex(ct.special_node()) ....: assert g1.vertices(sort=True) == g2.vertices(sort=True) ....: assert g1.edges(sort=True) == g2.edges(sort=True)
>>> from sage.all import * >>> for ct in CartanType.samples(affine=True): # needs sage.graphs ... g1 = ct.classical().dynkin_diagram() ... g2 = ct.dynkin_diagram() ... g2.delete_vertex(ct.special_node()) ... assert g1.vertices(sort=True) == g2.vertices(sort=True) ... assert g1.edges(sort=True) == g2.edges(sort=True)
- col_annihilator()[source]#
Return the unique minimal non trivial annihilating linear combination of \(\alpha^\vee_0, \alpha^\vee, \ldots, \alpha^\vee\) with nonnegative coefficients (or alternatively, the unique minimal non trivial annihilating linear combination of the columns of the Cartan matrix with non-negative coefficients).
Throw an error if the existence or uniqueness does not hold
FIXME: the current implementation assumes that the Cartan matrix is indexed by \([0,1,...]\), in the same order as the index set.
EXAMPLES:
sage: # needs sage.graphs sage: RootSystem(['C',2,1]).cartan_type().a() Finite family {0: 1, 1: 2, 2: 1} sage: RootSystem(['D',4,1]).cartan_type().a() Finite family {0: 1, 1: 1, 2: 2, 3: 1, 4: 1} sage: RootSystem(['F',4,1]).cartan_type().a() Finite family {0: 1, 1: 2, 2: 3, 3: 4, 4: 2} sage: RootSystem(['BC',4,2]).cartan_type().a() Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
>>> from sage.all import * >>> # needs sage.graphs >>> RootSystem(['C',Integer(2),Integer(1)]).cartan_type().a() Finite family {0: 1, 1: 2, 2: 1} >>> RootSystem(['D',Integer(4),Integer(1)]).cartan_type().a() Finite family {0: 1, 1: 1, 2: 2, 3: 1, 4: 1} >>> RootSystem(['F',Integer(4),Integer(1)]).cartan_type().a() Finite family {0: 1, 1: 2, 2: 3, 3: 4, 4: 2} >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().a() Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
a
is a shortcut for col_annihilator:sage: RootSystem(['BC',4,2]).cartan_type().col_annihilator() # needs sage.graphs Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
>>> from sage.all import * >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().col_annihilator() # needs sage.graphs Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1}
- is_affine()[source]#
EXAMPLES:
sage: CartanType(['A', 3, 1]).is_affine() True
>>> from sage.all import * >>> CartanType(['A', Integer(3), Integer(1)]).is_affine() True
- is_finite()[source]#
EXAMPLES:
sage: CartanType(['A', 3, 1]).is_finite() False
>>> from sage.all import * >>> CartanType(['A', Integer(3), Integer(1)]).is_finite() False
- is_untwisted_affine()[source]#
Return whether
self
is untwisted affineA Cartan type is untwisted affine if it is the canonical affine extension of some finite type. Every affine type is either untwisted affine, dual thereof, or of type
BC
.EXAMPLES:
sage: CartanType(['A', 3, 1]).is_untwisted_affine() True sage: CartanType(['A', 3, 1]).dual().is_untwisted_affine() # this one is self dual! True sage: CartanType(['B', 3, 1]).dual().is_untwisted_affine() False sage: CartanType(['BC', 3, 2]).is_untwisted_affine() False
>>> from sage.all import * >>> CartanType(['A', Integer(3), Integer(1)]).is_untwisted_affine() True >>> CartanType(['A', Integer(3), Integer(1)]).dual().is_untwisted_affine() # this one is self dual! True >>> CartanType(['B', Integer(3), Integer(1)]).dual().is_untwisted_affine() False >>> CartanType(['BC', Integer(3), Integer(2)]).is_untwisted_affine() False
- other_affinization()[source]#
Return the other affinization of the same classical type.
EXAMPLES:
sage: CartanType(["A", 3, 1]).other_affinization() ['A', 3, 1] sage: CartanType(["B", 3, 1]).other_affinization() ['C', 3, 1]^* sage: CartanType(["C", 3, 1]).dual().other_affinization() ['B', 3, 1]
>>> from sage.all import * >>> CartanType(["A", Integer(3), Integer(1)]).other_affinization() ['A', 3, 1] >>> CartanType(["B", Integer(3), Integer(1)]).other_affinization() ['C', 3, 1]^* >>> CartanType(["C", Integer(3), Integer(1)]).dual().other_affinization() ['B', 3, 1]
Is this what we want?:
sage: CartanType(["BC", 3, 2]).dual().other_affinization() ['B', 3, 1]
>>> from sage.all import * >>> CartanType(["BC", Integer(3), Integer(2)]).dual().other_affinization() ['B', 3, 1]
- row_annihilator(m=None)[source]#
Return the unique minimal non trivial annihilating linear combination of \(\alpha_0, \alpha_1, \ldots, \alpha_n\) with nonnegative coefficients (or alternatively, the unique minimal non trivial annihilating linear combination of the rows of the Cartan matrix with non-negative coefficients).
Throw an error if the existence of uniqueness does not hold
The optional argument
m
is for internal use only.EXAMPLES:
sage: # needs sage.graphs sage: RootSystem(['C',2,1]).cartan_type().acheck() Finite family {0: 1, 1: 1, 2: 1} sage: RootSystem(['D',4,1]).cartan_type().acheck() Finite family {0: 1, 1: 1, 2: 2, 3: 1, 4: 1} sage: RootSystem(['F',4,1]).cartan_type().acheck() Finite family {0: 1, 1: 2, 2: 3, 3: 2, 4: 1} sage: RootSystem(['BC',4,2]).cartan_type().acheck() Finite family {0: 1, 1: 2, 2: 2, 3: 2, 4: 2}
>>> from sage.all import * >>> # needs sage.graphs >>> RootSystem(['C',Integer(2),Integer(1)]).cartan_type().acheck() Finite family {0: 1, 1: 1, 2: 1} >>> RootSystem(['D',Integer(4),Integer(1)]).cartan_type().acheck() Finite family {0: 1, 1: 1, 2: 2, 3: 1, 4: 1} >>> RootSystem(['F',Integer(4),Integer(1)]).cartan_type().acheck() Finite family {0: 1, 1: 2, 2: 3, 3: 2, 4: 1} >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().acheck() Finite family {0: 1, 1: 2, 2: 2, 3: 2, 4: 2}
acheck
is a shortcut for row_annihilator:sage: RootSystem(['BC',4,2]).cartan_type().row_annihilator() # needs sage.graphs Finite family {0: 1, 1: 2, 2: 2, 3: 2, 4: 2}
>>> from sage.all import * >>> RootSystem(['BC',Integer(4),Integer(2)]).cartan_type().row_annihilator() # needs sage.graphs Finite family {0: 1, 1: 2, 2: 2, 3: 2, 4: 2}
FIXME:
The current implementation assumes that the Cartan matrix is indexed by \([0,1,...]\), in the same order as the index set.
This really should be a method of
CartanMatrix
.
- special_node()[source]#
Return a special node of the Dynkin diagram.
A special node is a node of the Dynkin diagram such that pruning it yields a Dynkin diagram for the associated classical type (see
classical()
).This method returns the label of some special node. This is usually \(0\) in the standard conventions.
EXAMPLES:
sage: CartanType(['A', 3, 1]).special_node() 0
>>> from sage.all import * >>> CartanType(['A', Integer(3), Integer(1)]).special_node() 0
The choice is guaranteed to be consistent with the indexing of the nodes of the classical Dynkin diagram:
sage: CartanType(['A', 3, 1]).index_set() (0, 1, 2, 3) sage: CartanType(['A', 3, 1]).classical().index_set() (1, 2, 3)
>>> from sage.all import * >>> CartanType(['A', Integer(3), Integer(1)]).index_set() (0, 1, 2, 3) >>> CartanType(['A', Integer(3), Integer(1)]).classical().index_set() (1, 2, 3)
- special_nodes()[source]#
Return the set of special nodes of the affine Dynkin diagram.
EXAMPLES:
sage: # needs sage.graphs sage.groups sage: CartanType(['A',3,1]).special_nodes() (0, 1, 2, 3) sage: CartanType(['C',2,1]).special_nodes() (0, 2) sage: CartanType(['D',4,1]).special_nodes() (0, 1, 3, 4) sage: CartanType(['E',6,1]).special_nodes() (0, 1, 6) sage: CartanType(['D',3,2]).special_nodes() (0, 2) sage: CartanType(['A',4,2]).special_nodes() (0,)
>>> from sage.all import * >>> # needs sage.graphs sage.groups >>> CartanType(['A',Integer(3),Integer(1)]).special_nodes() (0, 1, 2, 3) >>> CartanType(['C',Integer(2),Integer(1)]).special_nodes() (0, 2) >>> CartanType(['D',Integer(4),Integer(1)]).special_nodes() (0, 1, 3, 4) >>> CartanType(['E',Integer(6),Integer(1)]).special_nodes() (0, 1, 6) >>> CartanType(['D',Integer(3),Integer(2)]).special_nodes() (0, 2) >>> CartanType(['A',Integer(4),Integer(2)]).special_nodes() (0,)
- translation_factors()[source]#
Return the translation factors for
self
.Those are the smallest factors \(t_i\) such that the translation by \(t_i \alpha_i\) maps the fundamental polygon to another polygon in the alcove picture.
OUTPUT:
a dictionary from
self.index_set()
to \(\ZZ\) (or \(\QQ\) for affine type \(BC\))Those coefficients are all \(1\) for dual untwisted, and in particular for simply laced. They coincide with the usual \(c_i\) coefficients (see
c()
) for untwisted and dual thereof. See the discussion below for affine type \(BC\).Note
One usually realizes the alcove picture in the coweight lattice, with translations by coroots; in that case, one will use the translation factors for the dual Cartan type.
FIXME: the current implementation assumes that the Cartan matrix is indexed by \([0,1,...]\), in the same order as the index set.
EXAMPLES:
sage: # needs sage.graphs sage: CartanType(['C',2,1]).translation_factors() Finite family {0: 1, 1: 2, 2: 1} sage: CartanType(['C',2,1]).dual().translation_factors() Finite family {0: 1, 1: 1, 2: 1} sage: CartanType(['D',4,1]).translation_factors() Finite family {0: 1, 1: 1, 2: 1, 3: 1, 4: 1} sage: CartanType(['F',4,1]).translation_factors() Finite family {0: 1, 1: 1, 2: 1, 3: 2, 4: 2} sage: CartanType(['BC',4,2]).translation_factors() Finite family {0: 1, 1: 1, 2: 1, 3: 1, 4: 1/2}
>>> from sage.all import * >>> # needs sage.graphs >>> CartanType(['C',Integer(2),Integer(1)]).translation_factors() Finite family {0: 1, 1: 2, 2: 1} >>> CartanType(['C',Integer(2),Integer(1)]).dual().translation_factors() Finite family {0: 1, 1: 1, 2: 1} >>> CartanType(['D',Integer(4),Integer(1)]).translation_factors() Finite family {0: 1, 1: 1, 2: 1, 3: 1, 4: 1} >>> CartanType(['F',Integer(4),Integer(1)]).translation_factors() Finite family {0: 1, 1: 1, 2: 1, 3: 2, 4: 2} >>> CartanType(['BC',Integer(4),Integer(2)]).translation_factors() Finite family {0: 1, 1: 1, 2: 1, 3: 1, 4: 1/2}
We proceed with systematic tests taken from MuPAD-Combinat’s testsuite:
sage: # needs sage.graphs sage: list(CartanType(["A", 1, 1]).translation_factors()) [1, 1] sage: list(CartanType(["A", 5, 1]).translation_factors()) [1, 1, 1, 1, 1, 1] sage: list(CartanType(["B", 5, 1]).translation_factors()) [1, 1, 1, 1, 1, 2] sage: list(CartanType(["C", 5, 1]).translation_factors()) [1, 2, 2, 2, 2, 1] sage: list(CartanType(["D", 5, 1]).translation_factors()) [1, 1, 1, 1, 1, 1] sage: list(CartanType(["E", 6, 1]).translation_factors()) [1, 1, 1, 1, 1, 1, 1] sage: list(CartanType(["E", 7, 1]).translation_factors()) [1, 1, 1, 1, 1, 1, 1, 1] sage: list(CartanType(["E", 8, 1]).translation_factors()) [1, 1, 1, 1, 1, 1, 1, 1, 1] sage: list(CartanType(["F", 4, 1]).translation_factors()) [1, 1, 1, 2, 2] sage: list(CartanType(["G", 2, 1]).translation_factors()) [1, 3, 1] sage: list(CartanType(["A", 2, 2]).translation_factors()) [1, 1/2] sage: list(CartanType(["A", 2, 2]).dual().translation_factors()) [1/2, 1] sage: list(CartanType(["A", 10, 2]).translation_factors()) [1, 1, 1, 1, 1, 1/2] sage: list(CartanType(["A", 10, 2]).dual().translation_factors()) [1/2, 1, 1, 1, 1, 1] sage: list(CartanType(["A", 9, 2]).translation_factors()) [1, 1, 1, 1, 1, 1] sage: list(CartanType(["D", 5, 2]).translation_factors()) [1, 1, 1, 1, 1] sage: list(CartanType(["D", 4, 3]).translation_factors()) [1, 1, 1] sage: list(CartanType(["E", 6, 2]).translation_factors()) [1, 1, 1, 1, 1]
>>> from sage.all import * >>> # needs sage.graphs >>> list(CartanType(["A", Integer(1), Integer(1)]).translation_factors()) [1, 1] >>> list(CartanType(["A", Integer(5), Integer(1)]).translation_factors()) [1, 1, 1, 1, 1, 1] >>> list(CartanType(["B", Integer(5), Integer(1)]).translation_factors()) [1, 1, 1, 1, 1, 2] >>> list(CartanType(["C", Integer(5), Integer(1)]).translation_factors()) [1, 2, 2, 2, 2, 1] >>> list(CartanType(["D", Integer(5), Integer(1)]).translation_factors()) [1, 1, 1, 1, 1, 1] >>> list(CartanType(["E", Integer(6), Integer(1)]).translation_factors()) [1, 1, 1, 1, 1, 1, 1] >>> list(CartanType(["E", Integer(7), Integer(1)]).translation_factors()) [1, 1, 1, 1, 1, 1, 1, 1] >>> list(CartanType(["E", Integer(8), Integer(1)]).translation_factors()) [1, 1, 1, 1, 1, 1, 1, 1, 1] >>> list(CartanType(["F", Integer(4), Integer(1)]).translation_factors()) [1, 1, 1, 2, 2] >>> list(CartanType(["G", Integer(2), Integer(1)]).translation_factors()) [1, 3, 1] >>> list(CartanType(["A", Integer(2), Integer(2)]).translation_factors()) [1, 1/2] >>> list(CartanType(["A", Integer(2), Integer(2)]).dual().translation_factors()) [1/2, 1] >>> list(CartanType(["A", Integer(10), Integer(2)]).translation_factors()) [1, 1, 1, 1, 1, 1/2] >>> list(CartanType(["A", Integer(10), Integer(2)]).dual().translation_factors()) [1/2, 1, 1, 1, 1, 1] >>> list(CartanType(["A", Integer(9), Integer(2)]).translation_factors()) [1, 1, 1, 1, 1, 1] >>> list(CartanType(["D", Integer(5), Integer(2)]).translation_factors()) [1, 1, 1, 1, 1] >>> list(CartanType(["D", Integer(4), Integer(3)]).translation_factors()) [1, 1, 1] >>> list(CartanType(["E", Integer(6), Integer(2)]).translation_factors()) [1, 1, 1, 1, 1]
We conclude with a discussion of the appropriate value for affine type \(BC\). Let us consider the alcove picture realized in the weight lattice. It is obtained by taking the level-\(1\) affine hyperplane in the weight lattice, and projecting it along \(\Lambda_0\):
sage: R = RootSystem(["BC",2,2]) sage: alpha = R.weight_space().simple_roots() # needs sage.graphs sage: alphacheck = R.coroot_space().simple_roots() sage: Lambda = R.weight_space().fundamental_weights()
>>> from sage.all import * >>> R = RootSystem(["BC",Integer(2),Integer(2)]) >>> alpha = R.weight_space().simple_roots() # needs sage.graphs >>> alphacheck = R.coroot_space().simple_roots() >>> Lambda = R.weight_space().fundamental_weights()
Here are the levels of the fundamental weights:
sage: Lambda[0].level(), Lambda[1].level(), Lambda[2].level() # needs sage.graphs (1, 2, 2)
>>> from sage.all import * >>> Lambda[Integer(0)].level(), Lambda[Integer(1)].level(), Lambda[Integer(2)].level() # needs sage.graphs (1, 2, 2)
So the “center” of the fundamental polygon at level \(1\) is:
sage: O = Lambda[0] sage: O.level() # needs sage.graphs 1
>>> from sage.all import * >>> O = Lambda[Integer(0)] >>> O.level() # needs sage.graphs 1
We take the projection \(\omega_1\) at level \(0\) of \(\Lambda_1\) as unit vector on the \(x\)-axis, and the projection \(\omega_2\) at level 0 of \(\Lambda_2\) as unit vector of the \(y\)-axis:
sage: omega1 = Lambda[1] - 2*Lambda[0] sage: omega2 = Lambda[2] - 2*Lambda[0] sage: omega1.level(), omega2.level() # needs sage.graphs (0, 0)
>>> from sage.all import * >>> omega1 = Lambda[Integer(1)] - Integer(2)*Lambda[Integer(0)] >>> omega2 = Lambda[Integer(2)] - Integer(2)*Lambda[Integer(0)] >>> omega1.level(), omega2.level() # needs sage.graphs (0, 0)
The projections of the simple roots can be read off:
sage: alpha[0] # needs sage.graphs 2*Lambda[0] - Lambda[1] sage: alpha[1] # needs sage.graphs -2*Lambda[0] + 2*Lambda[1] - Lambda[2] sage: alpha[2] # needs sage.graphs -2*Lambda[1] + 2*Lambda[2]
>>> from sage.all import * >>> alpha[Integer(0)] # needs sage.graphs 2*Lambda[0] - Lambda[1] >>> alpha[Integer(1)] # needs sage.graphs -2*Lambda[0] + 2*Lambda[1] - Lambda[2] >>> alpha[Integer(2)] # needs sage.graphs -2*Lambda[1] + 2*Lambda[2]
Namely \(\alpha_0 = -\omega_1\), \(\alpha_1 = 2\omega_1 - \omega_2\) and \(\alpha_2 = -2 \omega_1 + 2 \omega_2\).
The reflection hyperplane defined by \(\alpha_0^\vee\) goes through the points \(O+1/2 \omega_1\) and \(O+1/2 \omega_2\):
sage: (O+(1/2)*omega1).scalar(alphacheck[0]) 0 sage: (O+(1/2)*omega2).scalar(alphacheck[0]) 0
>>> from sage.all import * >>> (O+(Integer(1)/Integer(2))*omega1).scalar(alphacheck[Integer(0)]) 0 >>> (O+(Integer(1)/Integer(2))*omega2).scalar(alphacheck[Integer(0)]) 0
Hence, the fundamental alcove is the triangle \((O, O+1/2 \omega_1, O+1/2 \omega_2)\). By successive reflections, one can tile the full plane. This induces a tiling of the full plane by translates of the fundamental polygon.
Todo
Add the picture here, once root system plots in the weight lattice will be implemented. In the mean time, the reader may look up the dual picture on Figure 2 of [HST09] which was produced by MuPAD-Combinat.
From this picture, one can read that translations by \(\alpha_0\), \(\alpha_1\), and \(1/2\alpha_2\) map the fundamental polygon to translates of it in the alcove picture, and are smallest with this property. Hence, the translation factors for affine type \(BC\) are \(t_0=1, t_1=1, t_2=1/2\):
sage: CartanType(['BC',2,2]).translation_factors() # needs sage.graphs Finite family {0: 1, 1: 1, 2: 1/2}
>>> from sage.all import * >>> CartanType(['BC',Integer(2),Integer(2)]).translation_factors() # needs sage.graphs Finite family {0: 1, 1: 1, 2: 1/2}
REFERENCES:
[HST09]F. Hivert, A. Schilling, and N. M. Thiery, Hecke group algebras as quotients of affine Hecke algebras at level 0, JCT A, Vol. 116, (2009) p. 844-863 arXiv 0804.3781
- class sage.combinat.root_system.cartan_type.CartanType_crystallographic[source]#
Bases:
CartanType_abstract
An abstract class for crystallographic Cartan types.
- ascii_art(label='lambda x: x', node=None)[source]#
Return an ascii art representation of the Dynkin diagram.
INPUT:
label
– (default: the identity) a relabeling function for the nodesnode
– (optional) a function which returns the character for a node
EXAMPLES:
sage: cartan_type = CartanType(['B',5,1]) sage: print(cartan_type.ascii_art()) O 0 | | O---O---O---O=>=O 1 2 3 4 5
>>> from sage.all import * >>> cartan_type = CartanType(['B',Integer(5),Integer(1)]) >>> print(cartan_type.ascii_art()) O 0 | | O---O---O---O=>=O 1 2 3 4 5
The label option is useful to visualize various statistics on the nodes of the Dynkin diagram:
sage: a = cartan_type.col_annihilator(); a # needs sage.graphs Finite family {0: 1, 1: 1, 2: 2, 3: 2, 4: 2, 5: 2} sage: print(CartanType(['B',5,1]).ascii_art(label=a.__getitem__)) # needs sage.graphs O 1 | | O---O---O---O=>=O 1 2 2 2 2
>>> from sage.all import * >>> a = cartan_type.col_annihilator(); a # needs sage.graphs Finite family {0: 1, 1: 1, 2: 2, 3: 2, 4: 2, 5: 2} >>> print(CartanType(['B',Integer(5),Integer(1)]).ascii_art(label=a.__getitem__)) # needs sage.graphs O 1 | | O---O---O---O=>=O 1 2 2 2 2
- cartan_matrix()[source]#
Return the Cartan matrix associated with
self
.EXAMPLES:
sage: CartanType(['A',4]).cartan_matrix() # needs sage.graphs [ 2 -1 0 0] [-1 2 -1 0] [ 0 -1 2 -1] [ 0 0 -1 2]
>>> from sage.all import * >>> CartanType(['A',Integer(4)]).cartan_matrix() # needs sage.graphs [ 2 -1 0 0] [-1 2 -1 0] [ 0 -1 2 -1] [ 0 0 -1 2]
- coxeter_diagram()[source]#
Return the Coxeter diagram for
self
.This implementation constructs it from the Dynkin diagram.
EXAMPLES:
sage: # needs sage.graphs sage: CartanType(['A',3]).coxeter_diagram() Graph on 3 vertices sage: CartanType(['A',3]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 3)] sage: CartanType(['B',3]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 4)] sage: CartanType(['G',2]).coxeter_diagram().edges(sort=True) [(1, 2, 6)] sage: CartanType(['F',4]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 4), (3, 4, 3)] sage: CartanType(['A',2,2]).coxeter_diagram().edges(sort=True) [(0, 1, +Infinity)]
>>> from sage.all import * >>> # needs sage.graphs >>> CartanType(['A',Integer(3)]).coxeter_diagram() Graph on 3 vertices >>> CartanType(['A',Integer(3)]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 3)] >>> CartanType(['B',Integer(3)]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 4)] >>> CartanType(['G',Integer(2)]).coxeter_diagram().edges(sort=True) [(1, 2, 6)] >>> CartanType(['F',Integer(4)]).coxeter_diagram().edges(sort=True) [(1, 2, 3), (2, 3, 4), (3, 4, 3)] >>> CartanType(['A',Integer(2),Integer(2)]).coxeter_diagram().edges(sort=True) [(0, 1, +Infinity)]
- dynkin_diagram()[source]#
Return the Dynkin diagram associated with
self
.EXAMPLES:
sage: CartanType(['A',4]).dynkin_diagram() # needs sage.graphs O---O---O---O 1 2 3 4 A4
>>> from sage.all import * >>> CartanType(['A',Integer(4)]).dynkin_diagram() # needs sage.graphs O---O---O---O 1 2 3 4 A4
Note
Derived subclasses should typically implement this as a cached method.
- index_set_bipartition()[source]#
Return a bipartition \(\{L,R\}\) of the vertices of the Dynkin diagram.
For \(i\) and \(j\) both in \(L\) (or both in \(R\)), the simple reflections \(s_i\) and \(s_j\) commute.
Of course, the Dynkin diagram should be bipartite. This is always the case for all finite types.
EXAMPLES:
sage: CartanType(['A',5]).index_set_bipartition() # needs sage.graphs ({1, 3, 5}, {2, 4}) sage: CartanType(['A',2,1]).index_set_bipartition() # needs sage.graphs Traceback (most recent call last): ... ValueError: the Dynkin diagram must be bipartite
>>> from sage.all import * >>> CartanType(['A',Integer(5)]).index_set_bipartition() # needs sage.graphs ({1, 3, 5}, {2, 4}) >>> CartanType(['A',Integer(2),Integer(1)]).index_set_bipartition() # needs sage.graphs Traceback (most recent call last): ... ValueError: the Dynkin diagram must be bipartite
- is_crystallographic()[source]#
Implements
CartanType_abstract.is_crystallographic()
by returningTrue
.EXAMPLES:
sage: CartanType(['A', 3, 1]).is_crystallographic() True
>>> from sage.all import * >>> CartanType(['A', Integer(3), Integer(1)]).is_crystallographic() True
- symmetrizer()[source]#
Return the symmetrizer of the Cartan matrix of
self
.A Cartan matrix \(M\) is symmetrizable if there exists a non trivial diagonal matrix \(D\) such that \(DM\) is a symmetric matrix, that is \(DM = M^tD\). In that case, \(D\) is unique, up to a scalar factor for each connected component of the Dynkin diagram.
This method computes the unique minimal such \(D\) with positive integral coefficients. If \(D\) exists, it is returned as a family. Otherwise
None
is returned.The coefficients are coerced to
base_ring
.EXAMPLES:
sage: CartanType(["B",5]).symmetrizer() # needs sage.graphs Finite family {1: 2, 2: 2, 3: 2, 4: 2, 5: 1}
>>> from sage.all import * >>> CartanType(["B",Integer(5)]).symmetrizer() # needs sage.graphs Finite family {1: 2, 2: 2, 3: 2, 4: 2, 5: 1}
Here is a neat trick to visualize it better:
sage: T = CartanType(["B",5]) sage: print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O---O---O---O=>=O 2 2 2 2 1 sage: T = CartanType(["BC",5, 2]) sage: print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O=<=O---O---O---O=<=O 1 2 2 2 2 4
>>> from sage.all import * >>> T = CartanType(["B",Integer(5)]) >>> print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O---O---O---O=>=O 2 2 2 2 1 >>> T = CartanType(["BC",Integer(5), Integer(2)]) >>> print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O=<=O---O---O---O=<=O 1 2 2 2 2 4
Here is the symmetrizer of some reducible Cartan types:
sage: T = CartanType(["D", 2]) sage: print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O O 1 1 sage: T = CartanType(["B",5],["BC",5, 2]) sage: print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O---O---O---O=>=O 2 2 2 2 1 O=<=O---O---O---O=<=O 1 2 2 2 2 4
>>> from sage.all import * >>> T = CartanType(["D", Integer(2)]) >>> print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O O 1 1 >>> T = CartanType(["B",Integer(5)],["BC",Integer(5), Integer(2)]) >>> print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O---O---O---O=>=O 2 2 2 2 1 O=<=O---O---O---O=<=O 1 2 2 2 2 4
Property: up to an overall scalar factor, this gives the norm of the simple roots in the ambient space:
sage: T = CartanType(["C",5]) sage: print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O---O---O---O=<=O 1 1 1 1 2 sage: alpha = RootSystem(T).ambient_space().simple_roots() sage: print(T.ascii_art(lambda i: alpha[i].scalar(alpha[i]))) O---O---O---O=<=O 2 2 2 2 4
>>> from sage.all import * >>> T = CartanType(["C",Integer(5)]) >>> print(T.ascii_art(T.symmetrizer().__getitem__)) # needs sage.graphs O---O---O---O=<=O 1 1 1 1 2 >>> alpha = RootSystem(T).ambient_space().simple_roots() >>> print(T.ascii_art(lambda i: alpha[i].scalar(alpha[i]))) O---O---O---O=<=O 2 2 2 2 4
- class sage.combinat.root_system.cartan_type.CartanType_decorator(ct)[source]#
Bases:
UniqueRepresentation
,SageObject
,CartanType_abstract
Concrete base class for Cartan types that decorate another Cartan type.
- index_set()[source]#
EXAMPLES:
sage: ct = CartanType(['F', 4, 1]).dual() sage: ct.index_set() (0, 1, 2, 3, 4)
>>> from sage.all import * >>> ct = CartanType(['F', Integer(4), Integer(1)]).dual() >>> ct.index_set() (0, 1, 2, 3, 4)
- is_affine()[source]#
EXAMPLES:
sage: ct = CartanType(['G', 2]).relabel({1:2,2:1}) sage: ct.is_affine() False
>>> from sage.all import * >>> ct = CartanType(['G', Integer(2)]).relabel({Integer(1):Integer(2),Integer(2):Integer(1)}) >>> ct.is_affine() False
- is_crystallographic()[source]#
EXAMPLES:
sage: ct = CartanType(['G', 2]).relabel({1:2,2:1}) sage: ct.is_crystallographic() True
>>> from sage.all import * >>> ct = CartanType(['G', Integer(2)]).relabel({Integer(1):Integer(2),Integer(2):Integer(1)}) >>> ct.is_crystallographic() True
- is_finite()[source]#
EXAMPLES:
sage: ct = CartanType(['G', 2]).relabel({1:2,2:1}) sage: ct.is_finite() True
>>> from sage.all import * >>> ct = CartanType(['G', Integer(2)]).relabel({Integer(1):Integer(2),Integer(2):Integer(1)}) >>> ct.is_finite() True
- class sage.combinat.root_system.cartan_type.CartanType_finite[source]#
Bases:
CartanType_abstract
An abstract class for simple affine Cartan types.
- class sage.combinat.root_system.cartan_type.CartanType_simple[source]#
Bases:
CartanType_abstract
An abstract class for simple Cartan types.
- class sage.combinat.root_system.cartan_type.CartanType_simply_laced[source]#
Bases:
CartanType_crystallographic
An abstract class for simply laced Cartan types.
- dual()[source]#
Simply laced Cartan types are self-dual, so return
self
.EXAMPLES:
sage: CartanType(["A", 3]).dual() ['A', 3] sage: CartanType(["A", 3, 1]).dual() ['A', 3, 1] sage: CartanType(["D", 3]).dual() ['D', 3] sage: CartanType(["D", 4, 1]).dual() ['D', 4, 1] sage: CartanType(["E", 6]).dual() ['E', 6] sage: CartanType(["E", 6, 1]).dual() ['E', 6, 1]
>>> from sage.all import * >>> CartanType(["A", Integer(3)]).dual() ['A', 3] >>> CartanType(["A", Integer(3), Integer(1)]).dual() ['A', 3, 1] >>> CartanType(["D", Integer(3)]).dual() ['D', 3] >>> CartanType(["D", Integer(4), Integer(1)]).dual() ['D', 4, 1] >>> CartanType(["E", Integer(6)]).dual() ['E', 6] >>> CartanType(["E", Integer(6), Integer(1)]).dual() ['E', 6, 1]
- is_simply_laced()[source]#
Return whether
self
is simply laced, which isTrue
.EXAMPLES:
sage: CartanType(['A',3,1]).is_simply_laced() True sage: CartanType(['A',2]).is_simply_laced() True
>>> from sage.all import * >>> CartanType(['A',Integer(3),Integer(1)]).is_simply_laced() True >>> CartanType(['A',Integer(2)]).is_simply_laced() True
- class sage.combinat.root_system.cartan_type.CartanType_standard[source]#
Bases:
UniqueRepresentation
,SageObject
- class sage.combinat.root_system.cartan_type.CartanType_standard_affine(letter, n, affine=1)[source]#
Bases:
CartanType_standard
,CartanType_affine
A concrete class for affine simple Cartan types.
- index_set()[source]#
Implements
CartanType_abstract.index_set()
.The index set for all standard affine Cartan types is of the form \(\{0, \ldots, n\}\).
EXAMPLES:
sage: CartanType(['A', 5, 1]).index_set() (0, 1, 2, 3, 4, 5)
>>> from sage.all import * >>> CartanType(['A', Integer(5), Integer(1)]).index_set() (0, 1, 2, 3, 4, 5)
- rank()[source]#
Return the rank of
self
which for type \(X_n^{(1)}\) is \(n + 1\).EXAMPLES:
sage: CartanType(['A', 4, 1]).rank() 5 sage: CartanType(['B', 4, 1]).rank() 5 sage: CartanType(['C', 3, 1]).rank() 4 sage: CartanType(['D', 4, 1]).rank() 5 sage: CartanType(['E', 6, 1]).rank() 7 sage: CartanType(['E', 7, 1]).rank() 8 sage: CartanType(['F', 4, 1]).rank() 5 sage: CartanType(['G', 2, 1]).rank() 3 sage: CartanType(['A', 2, 2]).rank() 2 sage: CartanType(['A', 6, 2]).rank() 4 sage: CartanType(['A', 7, 2]).rank() 5 sage: CartanType(['D', 5, 2]).rank() 5 sage: CartanType(['E', 6, 2]).rank() 5 sage: CartanType(['D', 4, 3]).rank() 3
>>> from sage.all import * >>> CartanType(['A', Integer(4), Integer(1)]).rank() 5 >>> CartanType(['B', Integer(4), Integer(1)]).rank() 5 >>> CartanType(['C', Integer(3), Integer(1)]).rank() 4 >>> CartanType(['D', Integer(4), Integer(1)]).rank() 5 >>> CartanType(['E', Integer(6), Integer(1)]).rank() 7 >>> CartanType(['E', Integer(7), Integer(1)]).rank() 8 >>> CartanType(['F', Integer(4), Integer(1)]).rank() 5 >>> CartanType(['G', Integer(2), Integer(1)]).rank() 3 >>> CartanType(['A', Integer(2), Integer(2)]).rank() 2 >>> CartanType(['A', Integer(6), Integer(2)]).rank() 4 >>> CartanType(['A', Integer(7), Integer(2)]).rank() 5 >>> CartanType(['D', Integer(5), Integer(2)]).rank() 5 >>> CartanType(['E', Integer(6), Integer(2)]).rank() 5 >>> CartanType(['D', Integer(4), Integer(3)]).rank() 3
- class sage.combinat.root_system.cartan_type.CartanType_standard_finite(letter, n)[source]#
Bases:
CartanType_standard
,CartanType_finite
A concrete base class for the finite standard Cartan types.
This includes for example \(A_3\), \(D_4\), or \(E_8\).
- affine()[source]#
Return the corresponding untwisted affine Cartan type.
EXAMPLES:
sage: CartanType(['A',3]).affine() ['A', 3, 1]
>>> from sage.all import * >>> CartanType(['A',Integer(3)]).affine() ['A', 3, 1]
- coxeter_number()[source]#
Return the Coxeter number associated with
self
.The Coxeter number is the order of a Coxeter element of the corresponding Weyl group.
See Bourbaki, Lie Groups and Lie Algebras V.6.1 or Wikipedia article Coxeter_element for more information.
EXAMPLES:
sage: CartanType(['A',4]).coxeter_number() 5 sage: CartanType(['B',4]).coxeter_number() 8 sage: CartanType(['C',4]).coxeter_number() 8
>>> from sage.all import * >>> CartanType(['A',Integer(4)]).coxeter_number() 5 >>> CartanType(['B',Integer(4)]).coxeter_number() 8 >>> CartanType(['C',Integer(4)]).coxeter_number() 8
- dual_coxeter_number()[source]#
Return the Coxeter number associated with
self
.EXAMPLES:
sage: CartanType(['A',4]).dual_coxeter_number() 5 sage: CartanType(['B',4]).dual_coxeter_number() 7 sage: CartanType(['C',4]).dual_coxeter_number() 5
>>> from sage.all import * >>> CartanType(['A',Integer(4)]).dual_coxeter_number() 5 >>> CartanType(['B',Integer(4)]).dual_coxeter_number() 7 >>> CartanType(['C',Integer(4)]).dual_coxeter_number() 5
- index_set()[source]#
Implements
CartanType_abstract.index_set()
.The index set for all standard finite Cartan types is of the form \(\{1, \ldots, n\}\). (See
type_I
for a slight abuse of this).EXAMPLES:
sage: CartanType(['A', 5]).index_set() (1, 2, 3, 4, 5)
>>> from sage.all import * >>> CartanType(['A', Integer(5)]).index_set() (1, 2, 3, 4, 5)
- opposition_automorphism()[source]#
Return the opposition automorphism
The opposition automorphism is the automorphism \(i \mapsto i^*\) of the vertices Dynkin diagram such that, for \(w_0\) the longest element of the Weyl group, and any simple root \(\alpha_i\), one has \(\alpha_{i^*} = -w_0(\alpha_i)\).
The automorphism is returned as a
Family
.EXAMPLES:
sage: ct = CartanType(['A', 5]) sage: ct.opposition_automorphism() # needs sage.libs.gap Finite family {1: 5, 2: 4, 3: 3, 4: 2, 5: 1} sage: ct = CartanType(['D', 4]) sage: ct.opposition_automorphism() # needs sage.libs.gap Finite family {1: 1, 2: 2, 3: 3, 4: 4} sage: ct = CartanType(['D', 5]) sage: ct.opposition_automorphism() # needs sage.libs.gap Finite family {1: 1, 2: 2, 3: 3, 4: 5, 5: 4} sage: ct = CartanType(['C', 4]) sage: ct.opposition_automorphism() # needs sage.libs.gap Finite family {1: 1, 2: 2, 3: 3, 4: 4}
>>> from sage.all import * >>> ct = CartanType(['A', Integer(5)]) >>> ct.opposition_automorphism() # needs sage.libs.gap Finite family {1: 5, 2: 4, 3: 3, 4: 2, 5: 1} >>> ct = CartanType(['D', Integer(4)]) >>> ct.opposition_automorphism() # needs sage.libs.gap Finite family {1: 1, 2: 2, 3: 3, 4: 4} >>> ct = CartanType(['D', Integer(5)]) >>> ct.opposition_automorphism() # needs sage.libs.gap Finite family {1: 1, 2: 2, 3: 3, 4: 5, 5: 4} >>> ct = CartanType(['C', Integer(4)]) >>> ct.opposition_automorphism() # needs sage.libs.gap Finite family {1: 1, 2: 2, 3: 3, 4: 4}
- rank()[source]#
Return the rank of
self
which for type \(X_n\) is \(n\).EXAMPLES:
sage: CartanType(['A', 3]).rank() 3 sage: CartanType(['B', 3]).rank() 3 sage: CartanType(['C', 3]).rank() 3 sage: CartanType(['D', 4]).rank() 4 sage: CartanType(['E', 6]).rank() 6
>>> from sage.all import * >>> CartanType(['A', Integer(3)]).rank() 3 >>> CartanType(['B', Integer(3)]).rank() 3 >>> CartanType(['C', Integer(3)]).rank() 3 >>> CartanType(['D', Integer(4)]).rank() 4 >>> CartanType(['E', Integer(6)]).rank() 6
- class sage.combinat.root_system.cartan_type.CartanType_standard_untwisted_affine(letter, n, affine=1)[source]#
Bases:
CartanType_standard_affine
A concrete class for the standard untwisted affine Cartan types.
- basic_untwisted()[source]#
Return the basic_untwisted Cartan type associated with this affine Cartan type.
Given an affine type \(X_n^{(r)}\), the basic_untwisted type is \(X_n\). In other words, it is the classical Cartan type that is twisted to obtain
self
.EXAMPLES:
sage: CartanType(['A', 1, 1]).basic_untwisted() ['A', 1] sage: CartanType(['A', 3, 1]).basic_untwisted() ['A', 3] sage: CartanType(['B', 3, 1]).basic_untwisted() ['B', 3] sage: CartanType(['E', 6, 1]).basic_untwisted() ['E', 6] sage: CartanType(['G', 2, 1]).basic_untwisted() ['G', 2]
>>> from sage.all import * >>> CartanType(['A', Integer(1), Integer(1)]).basic_untwisted() ['A', 1] >>> CartanType(['A', Integer(3), Integer(1)]).basic_untwisted() ['A', 3] >>> CartanType(['B', Integer(3), Integer(1)]).basic_untwisted() ['B', 3] >>> CartanType(['E', Integer(6), Integer(1)]).basic_untwisted() ['E', 6] >>> CartanType(['G', Integer(2), Integer(1)]).basic_untwisted() ['G', 2]
- classical()[source]#
Return the classical Cartan type associated with
self
.EXAMPLES:
sage: CartanType(['A', 3, 1]).classical() ['A', 3] sage: CartanType(['B', 3, 1]).classical() ['B', 3] sage: CartanType(['C', 3, 1]).classical() ['C', 3] sage: CartanType(['D', 4, 1]).classical() ['D', 4] sage: CartanType(['E', 6, 1]).classical() ['E', 6] sage: CartanType(['F', 4, 1]).classical() ['F', 4] sage: CartanType(['G', 2, 1]).classical() ['G', 2]
>>> from sage.all import * >>> CartanType(['A', Integer(3), Integer(1)]).classical() ['A', 3] >>> CartanType(['B', Integer(3), Integer(1)]).classical() ['B', 3] >>> CartanType(['C', Integer(3), Integer(1)]).classical() ['C', 3] >>> CartanType(['D', Integer(4), Integer(1)]).classical() ['D', 4] >>> CartanType(['E', Integer(6), Integer(1)]).classical() ['E', 6] >>> CartanType(['F', Integer(4), Integer(1)]).classical() ['F', 4] >>> CartanType(['G', Integer(2), Integer(1)]).classical() ['G', 2]
- is_untwisted_affine()[source]#
Implement
CartanType_affine.is_untwisted_affine()
by returningTrue
.EXAMPLES:
sage: CartanType(['B', 3, 1]).is_untwisted_affine() True
>>> from sage.all import * >>> CartanType(['B', Integer(3), Integer(1)]).is_untwisted_affine() True
- class sage.combinat.root_system.cartan_type.SuperCartanType_standard[source]#
Bases:
UniqueRepresentation
,SageObject