Cartan matrices - Combinatorics

Skip to content
Back to top
View this page
Edit this page

# 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

  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

      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]

  Python

      >>> 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

      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]

  [Python]

      >>> 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

      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]

  Python

      >>> 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()

    Return the Cartan matrix of `self`.

    EXAMPLES:

    Sage

        sage: CartanMatrix(['C',3]).cartan_matrix()                                 # needs sage.graphs
        [ 2 -1  0]
        [-1  2 -2]
        [ 0 -1  2]

    Python

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

  cartan_type()

    Return the Cartan type of `self` or `self` if unknown.

    EXAMPLES:

    Sage

        sage: C = CartanMatrix(['A',4,1])                                           # needs sage.graphs
        sage: C.cartan_type()                                                       # needs sage.graphs
        ['A', 4, 1]

    Python

        >>> 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

        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]

    [Python]

        >>> 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)

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

    EXAMPLES:

    Sage

        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)]

    Python

        >>> 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()

    Construct the Coxeter diagram of `self`.

    See also

    `CartanType_abstract.coxeter_diagram()`

    EXAMPLES:

    Sage

        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

    Python

        >>> 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()

    Return the Coxeter matrix for `self`.

    See also

    `CartanType_abstract.coxeter_matrix()`

    EXAMPLES:

    Sage

        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

    Python

        >>> 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()

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

    EXAMPLES:

    Sage

        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

    Python

        >>> 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

        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

    [Python]

        >>> 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()

    Return the Dynkin diagram corresponding to `self`.

    EXAMPLES:

    Sage

        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

    Python

        >>> 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()

    Return a tuple of all indecomposable blocks of `self`.

    EXAMPLES:

    Sage

        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]
        )

    Python

        >>> 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()

    Return the index set of `self`.

    EXAMPLES:

    Sage

        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)

    Python

        >>> 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()

    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

        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

    Python

        >>> 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()

    Implement `CartanType_abstract.is_crystallographic()`.

    A Cartan matrix is crystallographic if it is symmetrizable.

    EXAMPLES:

    Sage

        sage: CartanMatrix(['F',4]).is_crystallographic()                           # needs sage.graphs
        True

    Python

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

  is_finite()

    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

        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

    Python

        >>> 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)

    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

        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

    Python

        >>> 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()

    Return if `self` is an indecomposable matrix or `False` otherwise.

    EXAMPLES:

    Sage

        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

    Python

        >>> 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()

    Return if `self` is an indefinite type or `False` otherwise.

    EXAMPLES:

    Sage

        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

    Python

        >>> 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()

    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

        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

    Python

        >>> 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()

    Implement `CartanType_abstract.is_simply_laced()`.

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

    EXAMPLES:

    Sage

        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

    Python

        >>> 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)

    Return a matrix space over the integers.

    INPUT:

    - `nrows` – number of rows

    - `ncols` – number of columns

    - `sparse` – boolean

    EXAMPLES:

    Sage

        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]

    Python

        >>> 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)

    Return a list of all principal submatrices of `self`.

    INPUT:

    - `proper` – if `True`, return only proper submatrices

    EXAMPLES:

    Sage

        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]]

    Python

        >>> 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()

    Return the rank of `self`.

    EXAMPLES:

    Sage

        sage: CartanMatrix(['C',3]).rank()                                          # needs sage.graphs
        3
        sage: CartanMatrix(["A2","B2","F4"]).rank()                                 # needs sage.graphs
        8

    Python

        >>> 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')

    Return the reflection group corresponding to `self`.

    EXAMPLES:

    Sage

        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)

    Python

        >>> 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)

    Return the relabelled Cartan matrix.

    EXAMPLES:

    Sage

        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]

    Python

        >>> 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()

    Return the root space corresponding to `self`.

    EXAMPLES:

    Sage

        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]

    Python

        >>> 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()

    Return the root system corresponding to `self`.

    EXAMPLES:

    Sage

        sage: C = CartanMatrix(['A',3])                                             # needs sage.graphs
        sage: C.root_system()                                                       # needs sage.graphs
        Root system of type ['A', 3]

    Python

        >>> 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)

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

    EXAMPLES:

    Sage

        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)]

    Python

        >>> 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)

    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

        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)

    Python

        >>> 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()

    Return the symmetrized matrix of `self` if symmetrizable.

    EXAMPLES:

    Sage

        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]

    Python

        >>> 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()

    Return the symmetrizer of `self`.

    EXAMPLES:

    Sage

        sage: cm = CartanMatrix([[2,-5],[-2,2]])                                    # needs sage.graphs
        sage: cm.symmetrizer()                                                      # needs sage.graphs
        Finite family {0: 2, 1: 5}

    Python

        >>> 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)

  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

      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)

  Python

      >>> 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)

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

  EXAMPLES:

  Sage

      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

  Python

      >>> 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)

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

  EXAMPLES:

  Sage

      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

  Python

      >>> 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

      sage: M = matrix([[2,-1,-2], [-1,2,-1], [-1,-1,2]])
      sage: is_generalized_cartan_matrix(M)
      True

  [Python]

      >>> 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