Cartan matrices

AUTHORS:

  • Travis Scrimshaw (2012-04-22): Nicolas M. Thiery moved matrix creation to CartanType to prepare cartan_matrix() for deprecation.

  • Christian Stump, Travis Scrimshaw (2013-04-13): Created CartanMatrix.

  • Ben Salisbury (2018-08-07): Added Borcherds-Cartan matrices.

class sage.combinat.root_system.cartan_matrix.CartanMatrix[source]

Bases: Matrix_integer_sparse, CartanType_abstract

A (generalized) Cartan matrix.

A matrix \(A = (a_{ij})_{i,j \in I}\) for some index set \(I\) is a generalized Cartan matrix if it satisfies the following properties:

  • \(a_{ii} = 2\) for all \(i\),

  • \(a_{ij} \leq 0\) for all \(i \neq j\),

  • \(a_{ij} = 0\) if and only if \(a_{ji} = 0\) for all \(i \neq j\).

Additionally some reference assume that a Cartan matrix is symmetrizable (see is_symmetrizable()). However following Kac, we do not make that assumption here.

An even, integral Borcherds–Cartan matrix is an integral matrix \(A = (a_{ij})_{i,j \in I}\) for some countable index set \(I\) which satisfies the following properties:

  • \(a_{ii} \in \{2\} \cup 2\ZZ_{<0}\) for all \(i\),

  • \(a_{ij} \leq 0\) for all \(i \neq j\),

  • \(a_{ij} = 0\) if and only if \(a_{ji} = 0\) for all \(i \neq j\).

INPUT:

Can be anything which is accepted by CartanType or a matrix.

If given a matrix, one can also use the keyword cartan_type when giving a matrix to explicitly state the type. Otherwise this will try to check the input matrix against possible standard types of Cartan matrices. To disable this check, use the keyword cartan_type_check = False.

If one wants to initialize a Borcherds-Cartan matrix using matrix data, use the keyword borcherds=True. To specify the diagonal entries of corresponding to a Cartan type (a Cartan matrix is treated as matrix data), use borcherds with a list of the diagonal entries.

EXAMPLES:

sage: # needs sage.graphs
sage: CartanMatrix(['A', 4])
[ 2 -1  0  0]
[-1  2 -1  0]
[ 0 -1  2 -1]
[ 0  0 -1  2]
sage: CartanMatrix(['B', 6])
[ 2 -1  0  0  0  0]
[-1  2 -1  0  0  0]
[ 0 -1  2 -1  0  0]
[ 0  0 -1  2 -1  0]
[ 0  0  0 -1  2 -1]
[ 0  0  0  0 -2  2]
sage: CartanMatrix(['C', 4])
[ 2 -1  0  0]
[-1  2 -1  0]
[ 0 -1  2 -2]
[ 0  0 -1  2]
sage: CartanMatrix(['D', 6])
[ 2 -1  0  0  0  0]
[-1  2 -1  0  0  0]
[ 0 -1  2 -1  0  0]
[ 0  0 -1  2 -1 -1]
[ 0  0  0 -1  2  0]
[ 0  0  0 -1  0  2]
sage: CartanMatrix(['E',6])
[ 2  0 -1  0  0  0]
[ 0  2  0 -1  0  0]
[-1  0  2 -1  0  0]
[ 0 -1 -1  2 -1  0]
[ 0  0  0 -1  2 -1]
[ 0  0  0  0 -1  2]
sage: CartanMatrix(['E',7])
[ 2  0 -1  0  0  0  0]
[ 0  2  0 -1  0  0  0]
[-1  0  2 -1  0  0  0]
[ 0 -1 -1  2 -1  0  0]
[ 0  0  0 -1  2 -1  0]
[ 0  0  0  0 -1  2 -1]
[ 0  0  0  0  0 -1  2]
sage: CartanMatrix(['E', 8])
[ 2  0 -1  0  0  0  0  0]
[ 0  2  0 -1  0  0  0  0]
[-1  0  2 -1  0  0  0  0]
[ 0 -1 -1  2 -1  0  0  0]
[ 0  0  0 -1  2 -1  0  0]
[ 0  0  0  0 -1  2 -1  0]
[ 0  0  0  0  0 -1  2 -1]
[ 0  0  0  0  0  0 -1  2]
sage: CartanMatrix(['F', 4])
[ 2 -1  0  0]
[-1  2 -1  0]
[ 0 -2  2 -1]
[ 0  0 -1  2]
>>> from sage.all import *
>>> # needs sage.graphs
>>> CartanMatrix(['A', Integer(4)])
[ 2 -1  0  0]
[-1  2 -1  0]
[ 0 -1  2 -1]
[ 0  0 -1  2]
>>> CartanMatrix(['B', Integer(6)])
[ 2 -1  0  0  0  0]
[-1  2 -1  0  0  0]
[ 0 -1  2 -1  0  0]
[ 0  0 -1  2 -1  0]
[ 0  0  0 -1  2 -1]
[ 0  0  0  0 -2  2]
>>> CartanMatrix(['C', Integer(4)])
[ 2 -1  0  0]
[-1  2 -1  0]
[ 0 -1  2 -2]
[ 0  0 -1  2]
>>> CartanMatrix(['D', Integer(6)])
[ 2 -1  0  0  0  0]
[-1  2 -1  0  0  0]
[ 0 -1  2 -1  0  0]
[ 0  0 -1  2 -1 -1]
[ 0  0  0 -1  2  0]
[ 0  0  0 -1  0  2]
>>> CartanMatrix(['E',Integer(6)])
[ 2  0 -1  0  0  0]
[ 0  2  0 -1  0  0]
[-1  0  2 -1  0  0]
[ 0 -1 -1  2 -1  0]
[ 0  0  0 -1  2 -1]
[ 0  0  0  0 -1  2]
>>> CartanMatrix(['E',Integer(7)])
[ 2  0 -1  0  0  0  0]
[ 0  2  0 -1  0  0  0]
[-1  0  2 -1  0  0  0]
[ 0 -1 -1  2 -1  0  0]
[ 0  0  0 -1  2 -1  0]
[ 0  0  0  0 -1  2 -1]
[ 0  0  0  0  0 -1  2]
>>> CartanMatrix(['E', Integer(8)])
[ 2  0 -1  0  0  0  0  0]
[ 0  2  0 -1  0  0  0  0]
[-1  0  2 -1  0  0  0  0]
[ 0 -1 -1  2 -1  0  0  0]
[ 0  0  0 -1  2 -1  0  0]
[ 0  0  0  0 -1  2 -1  0]
[ 0  0  0  0  0 -1  2 -1]
[ 0  0  0  0  0  0 -1  2]
>>> CartanMatrix(['F', Integer(4)])
[ 2 -1  0  0]
[-1  2 -1  0]
[ 0 -2  2 -1]
[ 0  0 -1  2]

This is different from MuPAD-Combinat, due to different node convention?

sage: # needs sage.graphs
sage: CartanMatrix(['G', 2])
[ 2 -3]
[-1  2]
sage: CartanMatrix(['A',1,1])
[ 2 -2]
[-2  2]
sage: CartanMatrix(['A', 3, 1])
[ 2 -1  0 -1]
[-1  2 -1  0]
[ 0 -1  2 -1]
[-1  0 -1  2]
sage: CartanMatrix(['B', 3, 1])
[ 2  0 -1  0]
[ 0  2 -1  0]
[-1 -1  2 -1]
[ 0  0 -2  2]
sage: CartanMatrix(['C', 3, 1])
[ 2 -1  0  0]
[-2  2 -1  0]
[ 0 -1  2 -2]
[ 0  0 -1  2]
sage: CartanMatrix(['D', 4, 1])
[ 2  0 -1  0  0]
[ 0  2 -1  0  0]
[-1 -1  2 -1 -1]
[ 0  0 -1  2  0]
[ 0  0 -1  0  2]
sage: CartanMatrix(['E', 6, 1])
[ 2  0 -1  0  0  0  0]
[ 0  2  0 -1  0  0  0]
[-1  0  2  0 -1  0  0]
[ 0 -1  0  2 -1  0  0]
[ 0  0 -1 -1  2 -1  0]
[ 0  0  0  0 -1  2 -1]
[ 0  0  0  0  0 -1  2]
sage: CartanMatrix(['E', 7, 1])
[ 2 -1  0  0  0  0  0  0]
[-1  2  0 -1  0  0  0  0]
[ 0  0  2  0 -1  0  0  0]
[ 0 -1  0  2 -1  0  0  0]
[ 0  0 -1 -1  2 -1  0  0]
[ 0  0  0  0 -1  2 -1  0]
[ 0  0  0  0  0 -1  2 -1]
[ 0  0  0  0  0  0 -1  2]
sage: CartanMatrix(['E', 8, 1])
[ 2  0  0  0  0  0  0  0 -1]
[ 0  2  0 -1  0  0  0  0  0]
[ 0  0  2  0 -1  0  0  0  0]
[ 0 -1  0  2 -1  0  0  0  0]
[ 0  0 -1 -1  2 -1  0  0  0]
[ 0  0  0  0 -1  2 -1  0  0]
[ 0  0  0  0  0 -1  2 -1  0]
[ 0  0  0  0  0  0 -1  2 -1]
[-1  0  0  0  0  0  0 -1  2]
sage: CartanMatrix(['F', 4, 1])
[ 2 -1  0  0  0]
[-1  2 -1  0  0]
[ 0 -1  2 -1  0]
[ 0  0 -2  2 -1]
[ 0  0  0 -1  2]
sage: CartanMatrix(['G', 2, 1])
[ 2  0 -1]
[ 0  2 -3]
[-1 -1  2]
>>> from sage.all import *
>>> # needs sage.graphs
>>> CartanMatrix(['G', Integer(2)])
[ 2 -3]
[-1  2]
>>> CartanMatrix(['A',Integer(1),Integer(1)])
[ 2 -2]
[-2  2]
>>> CartanMatrix(['A', Integer(3), Integer(1)])
[ 2 -1  0 -1]
[-1  2 -1  0]
[ 0 -1  2 -1]
[-1  0 -1  2]
>>> CartanMatrix(['B', Integer(3), Integer(1)])
[ 2  0 -1  0]
[ 0  2 -1  0]
[-1 -1  2 -1]
[ 0  0 -2  2]
>>> CartanMatrix(['C', Integer(3), Integer(1)])
[ 2 -1  0  0]
[-2  2 -1  0]
[ 0 -1  2 -2]
[ 0  0 -1  2]
>>> CartanMatrix(['D', Integer(4), Integer(1)])
[ 2  0 -1  0  0]
[ 0  2 -1  0  0]
[-1 -1  2 -1 -1]
[ 0  0 -1  2  0]
[ 0  0 -1  0  2]
>>> CartanMatrix(['E', Integer(6), Integer(1)])
[ 2  0 -1  0  0  0  0]
[ 0  2  0 -1  0  0  0]
[-1  0  2  0 -1  0  0]
[ 0 -1  0  2 -1  0  0]
[ 0  0 -1 -1  2 -1  0]
[ 0  0  0  0 -1  2 -1]
[ 0  0  0  0  0 -1  2]
>>> CartanMatrix(['E', Integer(7), Integer(1)])
[ 2 -1  0  0  0  0  0  0]
[-1  2  0 -1  0  0  0  0]
[ 0  0  2  0 -1  0  0  0]
[ 0 -1  0  2 -1  0  0  0]
[ 0  0 -1 -1  2 -1  0  0]
[ 0  0  0  0 -1  2 -1  0]
[ 0  0  0  0  0 -1  2 -1]
[ 0  0  0  0  0  0 -1  2]
>>> CartanMatrix(['E', Integer(8), Integer(1)])
[ 2  0  0  0  0  0  0  0 -1]
[ 0  2  0 -1  0  0  0  0  0]
[ 0  0  2  0 -1  0  0  0  0]
[ 0 -1  0  2 -1  0  0  0  0]
[ 0  0 -1 -1  2 -1  0  0  0]
[ 0  0  0  0 -1  2 -1  0  0]
[ 0  0  0  0  0 -1  2 -1  0]
[ 0  0  0  0  0  0 -1  2 -1]
[-1  0  0  0  0  0  0 -1  2]
>>> CartanMatrix(['F', Integer(4), Integer(1)])
[ 2 -1  0  0  0]
[-1  2 -1  0  0]
[ 0 -1  2 -1  0]
[ 0  0 -2  2 -1]
[ 0  0  0 -1  2]
>>> CartanMatrix(['G', Integer(2), Integer(1)])
[ 2  0 -1]
[ 0  2 -3]
[-1 -1  2]

Examples of Borcherds-Cartan matrices:

sage: CartanMatrix([[2,-1],[-1,-2]], borcherds=True)                            # needs sage.graphs
[ 2 -1]
[-1 -2]
sage: CartanMatrix('B3', borcherds=[-4,-6,2])                                   # needs sage.graphs
[-4 -1  0]
[-1 -6 -1]
[ 0 -2  2]
>>> from sage.all import *
>>> CartanMatrix([[Integer(2),-Integer(1)],[-Integer(1),-Integer(2)]], borcherds=True)                            # needs sage.graphs
[ 2 -1]
[-1 -2]
>>> CartanMatrix('B3', borcherds=[-Integer(4),-Integer(6),Integer(2)])                                   # needs sage.graphs
[-4 -1  0]
[-1 -6 -1]
[ 0 -2  2]

Note

Since this is a matrix, row() and column() will return the standard row and column respectively. To get the row with the indices as in Dynkin diagrams/Cartan types, use row_with_indices() and column_with_indices() respectively.

cartan_matrix()[source]

Return the Cartan matrix of self.

EXAMPLES:

sage: CartanMatrix(['C',3]).cartan_matrix()                                 # needs sage.graphs
[ 2 -1  0]
[-1  2 -2]
[ 0 -1  2]
>>> from sage.all import *
>>> CartanMatrix(['C',Integer(3)]).cartan_matrix()                                 # needs sage.graphs
[ 2 -1  0]
[-1  2 -2]
[ 0 -1  2]
cartan_type()[source]

Return the Cartan type of self or self if unknown.

EXAMPLES:

sage: C = CartanMatrix(['A',4,1])                                           # needs sage.graphs
sage: C.cartan_type()                                                       # needs sage.graphs
['A', 4, 1]
>>> from sage.all import *
>>> C = CartanMatrix(['A',Integer(4),Integer(1)])                                           # needs sage.graphs
>>> C.cartan_type()                                                       # needs sage.graphs
['A', 4, 1]

If the Cartan type is unknown:

sage: C = CartanMatrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])                   # needs sage.graphs
sage: C.cartan_type()                                                       # needs sage.graphs
[ 2 -1 -2]
[-1  2 -1]
[-2 -1  2]
>>> from sage.all import *
>>> C = CartanMatrix([[Integer(2),-Integer(1),-Integer(2)], [-Integer(1),Integer(2),-Integer(1)], [-Integer(2),-Integer(1),Integer(2)]])                   # needs sage.graphs
>>> C.cartan_type()                                                       # needs sage.graphs
[ 2 -1 -2]
[-1  2 -1]
[-2 -1  2]
column_with_indices(j)[source]

Return the \(j\)-th column \((a_{i,j})_i\) of self as a container (or iterator) of tuples \((i, a_{i,j})\)

EXAMPLES:

sage: M = CartanMatrix(['B',4])                                             # needs sage.graphs
sage: [ (i,a) for (i,a) in M.column_with_indices(3) ]                       # needs sage.graphs
[(3, 2), (2, -1), (4, -2)]
>>> from sage.all import *
>>> M = CartanMatrix(['B',Integer(4)])                                             # needs sage.graphs
>>> [ (i,a) for (i,a) in M.column_with_indices(Integer(3)) ]                       # needs sage.graphs
[(3, 2), (2, -1), (4, -2)]
coxeter_diagram()[source]

Construct the Coxeter diagram of self.

EXAMPLES:

sage: # needs sage.graphs
sage: cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]])
sage: G = cm.coxeter_diagram(); G
Graph on 3 vertices
sage: G.edges(sort=True)
[(0, 1, +Infinity), (1, 2, 3)]
sage: ct = CartanType([['A',2,2], ['B',3]])
sage: ct.coxeter_diagram()
Graph on 5 vertices
sage: ct.cartan_matrix().coxeter_diagram() == ct.coxeter_diagram()
True
>>> from sage.all import *
>>> # needs sage.graphs
>>> cm = CartanMatrix([[Integer(2),-Integer(5),Integer(0)],[-Integer(2),Integer(2),-Integer(1)],[Integer(0),-Integer(1),Integer(2)]])
>>> G = cm.coxeter_diagram(); G
Graph on 3 vertices
>>> G.edges(sort=True)
[(0, 1, +Infinity), (1, 2, 3)]
>>> ct = CartanType([['A',Integer(2),Integer(2)], ['B',Integer(3)]])
>>> ct.coxeter_diagram()
Graph on 5 vertices
>>> ct.cartan_matrix().coxeter_diagram() == ct.coxeter_diagram()
True
coxeter_matrix()[source]

Return the Coxeter matrix for self.

EXAMPLES:

sage: # needs sage.graphs
sage: cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]])
sage: cm.coxeter_matrix()
[ 1 -1  2]
[-1  1  3]
[ 2  3  1]
sage: ct = CartanType([['A',2,2], ['B',3]])
sage: ct.coxeter_matrix()
[ 1 -1  2  2  2]
[-1  1  2  2  2]
[ 2  2  1  3  2]
[ 2  2  3  1  4]
[ 2  2  2  4  1]
sage: ct.cartan_matrix().coxeter_matrix() == ct.coxeter_matrix()
True
>>> from sage.all import *
>>> # needs sage.graphs
>>> cm = CartanMatrix([[Integer(2),-Integer(5),Integer(0)],[-Integer(2),Integer(2),-Integer(1)],[Integer(0),-Integer(1),Integer(2)]])
>>> cm.coxeter_matrix()
[ 1 -1  2]
[-1  1  3]
[ 2  3  1]
>>> ct = CartanType([['A',Integer(2),Integer(2)], ['B',Integer(3)]])
>>> ct.coxeter_matrix()
[ 1 -1  2  2  2]
[-1  1  2  2  2]
[ 2  2  1  3  2]
[ 2  2  3  1  4]
[ 2  2  2  4  1]
>>> ct.cartan_matrix().coxeter_matrix() == ct.coxeter_matrix()
True
dual()[source]

Return the dual Cartan matrix of self, which is obtained by taking the transpose.

EXAMPLES:

sage: # needs sage.graphs
sage: ct = CartanType(['C',3])
sage: M = CartanMatrix(ct); M
[ 2 -1  0]
[-1  2 -2]
[ 0 -1  2]
sage: M.dual()
[ 2 -1  0]
[-1  2 -1]
[ 0 -2  2]
sage: M.dual() == CartanMatrix(ct.dual())
True
sage: M.dual().cartan_type() == ct.dual()
True
>>> from sage.all import *
>>> # needs sage.graphs
>>> ct = CartanType(['C',Integer(3)])
>>> M = CartanMatrix(ct); M
[ 2 -1  0]
[-1  2 -2]
[ 0 -1  2]
>>> M.dual()
[ 2 -1  0]
[-1  2 -1]
[ 0 -2  2]
>>> M.dual() == CartanMatrix(ct.dual())
True
>>> M.dual().cartan_type() == ct.dual()
True

An example with arbitrary Cartan matrices:

sage: # needs sage.graphs
sage: cm = CartanMatrix([[2,-5], [-2, 2]]); cm
[ 2 -5]
[-2  2]
sage: cm.dual()
[ 2 -2]
[-5  2]
sage: cm.dual() == CartanMatrix(cm.transpose())
True
sage: cm.dual().dual() == cm
True
>>> from sage.all import *
>>> # needs sage.graphs
>>> cm = CartanMatrix([[Integer(2),-Integer(5)], [-Integer(2), Integer(2)]]); cm
[ 2 -5]
[-2  2]
>>> cm.dual()
[ 2 -2]
[-5  2]
>>> cm.dual() == CartanMatrix(cm.transpose())
True
>>> cm.dual().dual() == cm
True
dynkin_diagram()[source]

Return the Dynkin diagram corresponding to self.

EXAMPLES:

sage: # needs sage.graphs
sage: C = CartanMatrix(['A',2])
sage: C.dynkin_diagram()
O---O
1   2
A2
sage: C = CartanMatrix(['F',4,1])
sage: C.dynkin_diagram()
O---O---O=>=O---O
0   1   2   3   4
F4~
sage: C = CartanMatrix([[2,-4],[-4,2]])
sage: C.dynkin_diagram()
Dynkin diagram of rank 2
>>> from sage.all import *
>>> # needs sage.graphs
>>> C = CartanMatrix(['A',Integer(2)])
>>> C.dynkin_diagram()
O---O
1   2
A2
>>> C = CartanMatrix(['F',Integer(4),Integer(1)])
>>> C.dynkin_diagram()
O---O---O=>=O---O
0   1   2   3   4
F4~
>>> C = CartanMatrix([[Integer(2),-Integer(4)],[-Integer(4),Integer(2)]])
>>> C.dynkin_diagram()
Dynkin diagram of rank 2
indecomposable_blocks()[source]

Return a tuple of all indecomposable blocks of self.

EXAMPLES:

sage: # needs sage.graphs
sage: M = CartanMatrix(['A',2])
sage: M.indecomposable_blocks()
(
[ 2 -1]
[-1  2]
)
sage: M = CartanMatrix([['A',2,1],['A',3,1]])
sage: M.indecomposable_blocks()
(
[ 2 -1  0 -1]
[-1  2 -1  0]  [ 2 -1 -1]
[ 0 -1  2 -1]  [-1  2 -1]
[-1  0 -1  2], [-1 -1  2]
)
>>> from sage.all import *
>>> # needs sage.graphs
>>> M = CartanMatrix(['A',Integer(2)])
>>> M.indecomposable_blocks()
(
[ 2 -1]
[-1  2]
)
>>> M = CartanMatrix([['A',Integer(2),Integer(1)],['A',Integer(3),Integer(1)]])
>>> M.indecomposable_blocks()
(
[ 2 -1  0 -1]
[-1  2 -1  0]  [ 2 -1 -1]
[ 0 -1  2 -1]  [-1  2 -1]
[-1  0 -1  2], [-1 -1  2]
)
index_set()[source]

Return the index set of self.

EXAMPLES:

sage: # needs sage.graphs
sage: C = CartanMatrix(['A',1,1])
sage: C.index_set()
(0, 1)
sage: C = CartanMatrix(['E',6])
sage: C.index_set()
(1, 2, 3, 4, 5, 6)
>>> from sage.all import *
>>> # needs sage.graphs
>>> C = CartanMatrix(['A',Integer(1),Integer(1)])
>>> C.index_set()
(0, 1)
>>> C = CartanMatrix(['E',Integer(6)])
>>> C.index_set()
(1, 2, 3, 4, 5, 6)
is_affine()[source]

Return True if self is an affine type or False otherwise.

A generalized Cartan matrix is affine if all of its indecomposable blocks are either finite (see is_finite()) or have zero determinant with all proper principal minors positive.

EXAMPLES:

sage: # needs sage.graphs
sage: M = CartanMatrix(['C',4])
sage: M.is_affine()
False
sage: M = CartanMatrix(['D',4,1])
sage: M.is_affine()
True
sage: M = CartanMatrix([[2, -4], [-3, 2]])
sage: M.is_affine()
False
>>> from sage.all import *
>>> # needs sage.graphs
>>> M = CartanMatrix(['C',Integer(4)])
>>> M.is_affine()
False
>>> M = CartanMatrix(['D',Integer(4),Integer(1)])
>>> M.is_affine()
True
>>> M = CartanMatrix([[Integer(2), -Integer(4)], [-Integer(3), Integer(2)]])
>>> M.is_affine()
False
is_crystallographic()[source]

Implement CartanType_abstract.is_crystallographic().

A Cartan matrix is crystallographic if it is symmetrizable.

EXAMPLES:

sage: CartanMatrix(['F',4]).is_crystallographic()                           # needs sage.graphs
True
>>> from sage.all import *
>>> CartanMatrix(['F',Integer(4)]).is_crystallographic()                           # needs sage.graphs
True
is_finite()[source]

Return True if self is a finite type or False otherwise.

A generalized Cartan matrix is finite if the determinant of all its principal submatrices (see principal_submatrices()) is positive. Such matrices have a positive definite symmetrized matrix. Note that a finite matrix may consist of multiple blocks of Cartan matrices each having finite Cartan type.

EXAMPLES:

sage: # needs sage.graphs
sage: M = CartanMatrix(['C',4])
sage: M.is_finite()
True
sage: M = CartanMatrix(['D',4,1])
sage: M.is_finite()
False
sage: M = CartanMatrix([[2, -4], [-3, 2]])
sage: M.is_finite()
False
>>> from sage.all import *
>>> # needs sage.graphs
>>> M = CartanMatrix(['C',Integer(4)])
>>> M.is_finite()
True
>>> M = CartanMatrix(['D',Integer(4),Integer(1)])
>>> M.is_finite()
False
>>> M = CartanMatrix([[Integer(2), -Integer(4)], [-Integer(3), Integer(2)]])
>>> M.is_finite()
False
is_hyperbolic(compact=False)[source]

Return if True if self is a (compact) hyperbolic type or False otherwise.

An indecomposable generalized Cartan matrix is hyperbolic if it has negative determinant and if any proper connected subdiagram of its Dynkin diagram is of finite or affine type. It is compact hyperbolic if any proper connected subdiagram has finite type.

INPUT:

  • compact – if True, check if matrix is compact hyperbolic

EXAMPLES:

sage: # needs sage.graphs
sage: M = CartanMatrix([[2,-2,0],[-2,2,-1],[0,-1,2]])
sage: M.is_hyperbolic()
True
sage: M.is_hyperbolic(compact=True)
False
sage: M = CartanMatrix([[2,-3],[-3,2]])
sage: M.is_hyperbolic()
True
sage: M = CartanMatrix(['C',4])
sage: M.is_hyperbolic()
False
>>> from sage.all import *
>>> # needs sage.graphs
>>> M = CartanMatrix([[Integer(2),-Integer(2),Integer(0)],[-Integer(2),Integer(2),-Integer(1)],[Integer(0),-Integer(1),Integer(2)]])
>>> M.is_hyperbolic()
True
>>> M.is_hyperbolic(compact=True)
False
>>> M = CartanMatrix([[Integer(2),-Integer(3)],[-Integer(3),Integer(2)]])
>>> M.is_hyperbolic()
True
>>> M = CartanMatrix(['C',Integer(4)])
>>> M.is_hyperbolic()
False
is_indecomposable()[source]

Return if self is an indecomposable matrix or False otherwise.

EXAMPLES:

sage: # needs sage.graphs
sage: M = CartanMatrix(['A',5])
sage: M.is_indecomposable()
True
sage: M = CartanMatrix([[2,-1,0],[-1,2,0],[0,0,2]])
sage: M.is_indecomposable()
False
>>> from sage.all import *
>>> # needs sage.graphs
>>> M = CartanMatrix(['A',Integer(5)])
>>> M.is_indecomposable()
True
>>> M = CartanMatrix([[Integer(2),-Integer(1),Integer(0)],[-Integer(1),Integer(2),Integer(0)],[Integer(0),Integer(0),Integer(2)]])
>>> M.is_indecomposable()
False
is_indefinite()[source]

Return if self is an indefinite type or False otherwise.

EXAMPLES:

sage: # needs sage.graphs
sage: M = CartanMatrix([[2,-3],[-3,2]])
sage: M.is_indefinite()
True
sage: M = CartanMatrix("A2")
sage: M.is_indefinite()
False
>>> from sage.all import *
>>> # needs sage.graphs
>>> M = CartanMatrix([[Integer(2),-Integer(3)],[-Integer(3),Integer(2)]])
>>> M.is_indefinite()
True
>>> M = CartanMatrix("A2")
>>> M.is_indefinite()
False
is_lorentzian()[source]

Return True if self is a Lorentzian type or False otherwise.

A generalized Cartan matrix is Lorentzian if it has negative determinant and exactly one negative eigenvalue.

EXAMPLES:

sage: # needs sage.graphs
sage: M = CartanMatrix([[2,-3],[-3,2]])
sage: M.is_lorentzian()
True
sage: M = CartanMatrix([[2,-1],[-1,2]])
sage: M.is_lorentzian()
False
>>> from sage.all import *
>>> # needs sage.graphs
>>> M = CartanMatrix([[Integer(2),-Integer(3)],[-Integer(3),Integer(2)]])
>>> M.is_lorentzian()
True
>>> M = CartanMatrix([[Integer(2),-Integer(1)],[-Integer(1),Integer(2)]])
>>> M.is_lorentzian()
False
is_simply_laced()[source]

Implement CartanType_abstract.is_simply_laced().

A Cartan matrix is simply-laced if all non diagonal entries are \(0\) or \(-1\).

EXAMPLES:

sage: cm = CartanMatrix([[2, -1, -1, -1], [-1, 2, -1, -1],                  # needs sage.graphs
....:                    [-1, -1, 2, -1], [-1, -1, -1, 2]])
sage: cm.is_simply_laced()                                                  # needs sage.graphs
True
>>> from sage.all import *
>>> cm = CartanMatrix([[Integer(2), -Integer(1), -Integer(1), -Integer(1)], [-Integer(1), Integer(2), -Integer(1), -Integer(1)],                  # needs sage.graphs
...                    [-Integer(1), -Integer(1), Integer(2), -Integer(1)], [-Integer(1), -Integer(1), -Integer(1), Integer(2)]])
>>> cm.is_simply_laced()                                                  # needs sage.graphs
True
matrix_space(nrows=None, ncols=None, sparse=None)[source]

Return a matrix space over the integers.

INPUT:

  • nrows – number of rows

  • ncols – number of columns

  • sparse – boolean

EXAMPLES:

sage: # needs sage.graphs
sage: cm = CartanMatrix(['A', 3])
sage: cm.matrix_space()
Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring
sage: cm.matrix_space(2, 2)
Full MatrixSpace of 2 by 2 sparse matrices over Integer Ring
sage: cm[:2,1:]   # indirect doctest
[-1  0]
[ 2 -1]
>>> from sage.all import *
>>> # needs sage.graphs
>>> cm = CartanMatrix(['A', Integer(3)])
>>> cm.matrix_space()
Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring
>>> cm.matrix_space(Integer(2), Integer(2))
Full MatrixSpace of 2 by 2 sparse matrices over Integer Ring
>>> cm[:Integer(2),Integer(1):]   # indirect doctest
[-1  0]
[ 2 -1]
principal_submatrices(proper=False)[source]

Return a list of all principal submatrices of self.

INPUT:

  • proper – if True, return only proper submatrices

EXAMPLES:

sage: M = CartanMatrix(['A',2])                                             # needs sage.graphs
sage: M.principal_submatrices()                                             # needs sage.graphs
[
              [ 2 -1]
[], [2], [2], [-1  2]
]
sage: M.principal_submatrices(proper=True)                                  # needs sage.graphs
[[], [2], [2]]
>>> from sage.all import *
>>> M = CartanMatrix(['A',Integer(2)])                                             # needs sage.graphs
>>> M.principal_submatrices()                                             # needs sage.graphs
[
              [ 2 -1]
[], [2], [2], [-1  2]
]
>>> M.principal_submatrices(proper=True)                                  # needs sage.graphs
[[], [2], [2]]
rank()[source]

Return the rank of self.

EXAMPLES:

sage: CartanMatrix(['C',3]).rank()                                          # needs sage.graphs
3
sage: CartanMatrix(["A2","B2","F4"]).rank()                                 # needs sage.graphs
8
>>> from sage.all import *
>>> CartanMatrix(['C',Integer(3)]).rank()                                          # needs sage.graphs
3
>>> CartanMatrix(["A2","B2","F4"]).rank()                                 # needs sage.graphs
8
reflection_group(type='matrix')[source]

Return the reflection group corresponding to self.

EXAMPLES:

sage: C = CartanMatrix(['A',3])                                             # needs sage.graphs
sage: C.reflection_group()                                                  # needs sage.graphs sage.libs.gap
Weyl Group of type ['A', 3] (as a matrix group acting on the root space)
>>> from sage.all import *
>>> C = CartanMatrix(['A',Integer(3)])                                             # needs sage.graphs
>>> C.reflection_group()                                                  # needs sage.graphs sage.libs.gap
Weyl Group of type ['A', 3] (as a matrix group acting on the root space)
relabel(relabelling)[source]

Return the relabelled Cartan matrix.

EXAMPLES:

sage: # needs sage.graphs
sage: CM = CartanMatrix(['C',3])
sage: R = CM.relabel({1:0, 2:4, 3:1}); R
[ 2  0 -1]
[ 0  2 -1]
[-1 -2  2]
sage: R.index_set()
(0, 1, 4)
sage: CM
[ 2 -1  0]
[-1  2 -2]
[ 0 -1  2]
>>> from sage.all import *
>>> # needs sage.graphs
>>> CM = CartanMatrix(['C',Integer(3)])
>>> R = CM.relabel({Integer(1):Integer(0), Integer(2):Integer(4), Integer(3):Integer(1)}); R
[ 2  0 -1]
[ 0  2 -1]
[-1 -2  2]
>>> R.index_set()
(0, 1, 4)
>>> CM
[ 2 -1  0]
[-1  2 -2]
[ 0 -1  2]
root_space()[source]

Return the root space corresponding to self.

EXAMPLES:

sage: C = CartanMatrix(['A',3])                                             # needs sage.graphs
sage: C.root_space()                                                        # needs sage.graphs
Root space over the Rational Field of the Root system of type ['A', 3]
>>> from sage.all import *
>>> C = CartanMatrix(['A',Integer(3)])                                             # needs sage.graphs
>>> C.root_space()                                                        # needs sage.graphs
Root space over the Rational Field of the Root system of type ['A', 3]
root_system()[source]

Return the root system corresponding to self.

EXAMPLES:

sage: C = CartanMatrix(['A',3])                                             # needs sage.graphs
sage: C.root_system()                                                       # needs sage.graphs
Root system of type ['A', 3]
>>> from sage.all import *
>>> C = CartanMatrix(['A',Integer(3)])                                             # needs sage.graphs
>>> C.root_system()                                                       # needs sage.graphs
Root system of type ['A', 3]
row_with_indices(i)[source]

Return the \(i\)-th row \((a_{i,j})_j\) of self as a container (or iterator) of tuples \((j, a_{i,j})\)

EXAMPLES:

sage: M = CartanMatrix(['C',4])                                             # needs sage.graphs
sage: [ (i,a) for (i,a) in M.row_with_indices(3) ]                          # needs sage.graphs
[(3, 2), (2, -1), (4, -2)]
>>> from sage.all import *
>>> M = CartanMatrix(['C',Integer(4)])                                             # needs sage.graphs
>>> [ (i,a) for (i,a) in M.row_with_indices(Integer(3)) ]                          # needs sage.graphs
[(3, 2), (2, -1), (4, -2)]
subtype(index_set)[source]

Return a subtype of self given by index_set.

A subtype can be considered the Dynkin diagram induced from the Dynkin diagram of self by index_set.

EXAMPLES:

sage: # needs sage.graphs
sage: C = CartanMatrix(['F',4])
sage: S = C.subtype([1,2,3])
sage: S
[ 2 -1  0]
[-1  2 -1]
[ 0 -2  2]
sage: S.index_set()
(1, 2, 3)
>>> from sage.all import *
>>> # needs sage.graphs
>>> C = CartanMatrix(['F',Integer(4)])
>>> S = C.subtype([Integer(1),Integer(2),Integer(3)])
>>> S
[ 2 -1  0]
[-1  2 -1]
[ 0 -2  2]
>>> S.index_set()
(1, 2, 3)
symmetrized_matrix()[source]

Return the symmetrized matrix of self if symmetrizable.

EXAMPLES:

sage: cm = CartanMatrix(['B',4,1])                                          # needs sage.graphs
sage: cm.symmetrized_matrix()                                               # needs sage.graphs
[ 4  0 -2  0  0]
[ 0  4 -2  0  0]
[-2 -2  4 -2  0]
[ 0  0 -2  4 -2]
[ 0  0  0 -2  2]
>>> from sage.all import *
>>> cm = CartanMatrix(['B',Integer(4),Integer(1)])                                          # needs sage.graphs
>>> cm.symmetrized_matrix()                                               # needs sage.graphs
[ 4  0 -2  0  0]
[ 0  4 -2  0  0]
[-2 -2  4 -2  0]
[ 0  0 -2  4 -2]
[ 0  0  0 -2  2]
symmetrizer()[source]

Return the symmetrizer of self.

EXAMPLES:

sage: cm = CartanMatrix([[2,-5],[-2,2]])                                    # needs sage.graphs
sage: cm.symmetrizer()                                                      # needs sage.graphs
Finite family {0: 2, 1: 5}
>>> from sage.all import *
>>> cm = CartanMatrix([[Integer(2),-Integer(5)],[-Integer(2),Integer(2)]])                                    # needs sage.graphs
>>> cm.symmetrizer()                                                      # needs sage.graphs
Finite family {0: 2, 1: 5}
sage.combinat.root_system.cartan_matrix.find_cartan_type_from_matrix(CM)[source]

Find a Cartan type by direct comparison of Dynkin diagrams given from the generalized Cartan matrix CM and return None if not found.

INPUT:

  • CM – a generalized Cartan matrix

EXAMPLES:

sage: # needs sage.graphs
sage: from sage.combinat.root_system.cartan_matrix import find_cartan_type_from_matrix
sage: CM = CartanMatrix([[2,-1,-1], [-1,2,-1], [-1,-1,2]])
sage: find_cartan_type_from_matrix(CM)
['A', 2, 1]
sage: CM = CartanMatrix([[2,-1,0], [-1,2,-2], [0,-1,2]])
sage: find_cartan_type_from_matrix(CM)
['C', 3] relabelled by {1: 0, 2: 1, 3: 2}
sage: CM = CartanMatrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
sage: find_cartan_type_from_matrix(CM)
>>> from sage.all import *
>>> # needs sage.graphs
>>> from sage.combinat.root_system.cartan_matrix import find_cartan_type_from_matrix
>>> CM = CartanMatrix([[Integer(2),-Integer(1),-Integer(1)], [-Integer(1),Integer(2),-Integer(1)], [-Integer(1),-Integer(1),Integer(2)]])
>>> find_cartan_type_from_matrix(CM)
['A', 2, 1]
>>> CM = CartanMatrix([[Integer(2),-Integer(1),Integer(0)], [-Integer(1),Integer(2),-Integer(2)], [Integer(0),-Integer(1),Integer(2)]])
>>> find_cartan_type_from_matrix(CM)
['C', 3] relabelled by {1: 0, 2: 1, 3: 2}
>>> CM = CartanMatrix([[Integer(2),-Integer(1),-Integer(2)], [-Integer(1),Integer(2),-Integer(1)], [-Integer(2),-Integer(1),Integer(2)]])
>>> find_cartan_type_from_matrix(CM)
sage.combinat.root_system.cartan_matrix.is_borcherds_cartan_matrix(M)[source]

Return True if M is an even, integral Borcherds-Cartan matrix. For a definition of such a matrix, see CartanMatrix.

EXAMPLES:

sage: from sage.combinat.root_system.cartan_matrix import is_borcherds_cartan_matrix
sage: M = Matrix([[2,-1],[-1,2]])
sage: is_borcherds_cartan_matrix(M)
True
sage: N = Matrix([[2,-1],[-1,0]])
sage: is_borcherds_cartan_matrix(N)
False
sage: O = Matrix([[2,-1],[-1,-2]])
sage: is_borcherds_cartan_matrix(O)
True
sage: O = Matrix([[2,-1],[-1,-3]])
sage: is_borcherds_cartan_matrix(O)
False
>>> from sage.all import *
>>> from sage.combinat.root_system.cartan_matrix import is_borcherds_cartan_matrix
>>> M = Matrix([[Integer(2),-Integer(1)],[-Integer(1),Integer(2)]])
>>> is_borcherds_cartan_matrix(M)
True
>>> N = Matrix([[Integer(2),-Integer(1)],[-Integer(1),Integer(0)]])
>>> is_borcherds_cartan_matrix(N)
False
>>> O = Matrix([[Integer(2),-Integer(1)],[-Integer(1),-Integer(2)]])
>>> is_borcherds_cartan_matrix(O)
True
>>> O = Matrix([[Integer(2),-Integer(1)],[-Integer(1),-Integer(3)]])
>>> is_borcherds_cartan_matrix(O)
False
sage.combinat.root_system.cartan_matrix.is_generalized_cartan_matrix(M)[source]

Return True if M is a generalized Cartan matrix. For a definition of a generalized Cartan matrix, see CartanMatrix.

EXAMPLES:

sage: from sage.combinat.root_system.cartan_matrix import is_generalized_cartan_matrix
sage: M = matrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
sage: is_generalized_cartan_matrix(M)
True
sage: M = matrix([[2,-1,-2], [-1,2,-1], [0,-1,2]])
sage: is_generalized_cartan_matrix(M)
False
sage: M = matrix([[1,-1,-2], [-1,2,-1], [-2,-1,2]])
sage: is_generalized_cartan_matrix(M)
False
>>> from sage.all import *
>>> from sage.combinat.root_system.cartan_matrix import is_generalized_cartan_matrix
>>> M = matrix([[Integer(2),-Integer(1),-Integer(2)], [-Integer(1),Integer(2),-Integer(1)], [-Integer(2),-Integer(1),Integer(2)]])
>>> is_generalized_cartan_matrix(M)
True
>>> M = matrix([[Integer(2),-Integer(1),-Integer(2)], [-Integer(1),Integer(2),-Integer(1)], [Integer(0),-Integer(1),Integer(2)]])
>>> is_generalized_cartan_matrix(M)
False
>>> M = matrix([[Integer(1),-Integer(1),-Integer(2)], [-Integer(1),Integer(2),-Integer(1)], [-Integer(2),-Integer(1),Integer(2)]])
>>> is_generalized_cartan_matrix(M)
False

A non-symmetrizable example:

sage: M = matrix([[2,-1,-2], [-1,2,-1], [-1,-1,2]])
sage: is_generalized_cartan_matrix(M)
True
>>> from sage.all import *
>>> M = matrix([[Integer(2),-Integer(1),-Integer(2)], [-Integer(1),Integer(2),-Integer(1)], [-Integer(1),-Integer(1),Integer(2)]])
>>> is_generalized_cartan_matrix(M)
True