Ticket #14137: trac_14137-cartan_matrix_class-ts.patch

File trac_14137-cartan_matrix_class-ts.patch, 26.2 KB (added by tscrim, 6 years ago)
  • sage/combinat/root_system/all.py

    # HG changeset patch
    # User Travis Scrimshaw <tscrim@ucdavis.edu>
    # Date 1365541717 25200
    # Node ID b5d5678edcd6d706b16f155f1fe469ac4a3e31ef
    # Parent 6094630db105d60e3d50437521b05949951ac8b4
    #14137: Implement Cartan matrix class.
    
    diff --git a/sage/combinat/root_system/all.py b/sage/combinat/root_system/all.py
    a b lazy_import('sage.combinat.root_system.a 
    33
    44from cartan_type import CartanType
    55from dynkin_diagram import DynkinDiagram, dynkin_diagram
    6 from cartan_matrix import cartan_matrix
     6from cartan_matrix import CartanMatrix, cartan_matrix
    77from coxeter_matrix import coxeter_matrix
    88from root_system import RootSystem, WeylDim
    99from weyl_group import WeylGroup, WeylGroupElement
  • sage/combinat/root_system/cartan_matrix.py

    diff --git a/sage/combinat/root_system/cartan_matrix.py b/sage/combinat/root_system/cartan_matrix.py
    a b AUTHORS: 
    55
    66- Travis Scrimshaw (2012-04-22): Nicolas M. Thiery moved matrix creation to
    77  :class:`CartanType` to prepare :func:`cartan_matrix()` for deprecation.
     8- Christian Stump, Travis Scrimshaw (2013-04-13): Created :class:`CartanMatrix`.
    89"""
    910#*****************************************************************************
    10 #       Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
     11#       Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
     12#       Copyright (C) 2012,2013 Travis Scrimshaw <tscrim at ucdavis.edu>,
     13#       Copyright (C) 2013 Chrisitan Stump,
    1114#
    1215#  Distributed under the terms of the GNU General Public License (GPL)
    1316#
    AUTHORS: 
    2023#
    2124#                  http://www.gnu.org/licenses/
    2225#*****************************************************************************
    23 from cartan_type import CartanType
     26from sage.misc.cachefunc import cached_method
     27from sage.matrix.constructor import matrix
     28from sage.matrix.matrix import is_Matrix
     29from sage.matrix.matrix_space import MatrixSpace
     30from sage.misc.classcall_metaclass import ClasscallMetaclass, typecall
     31from sage.matrix.matrix_integer_sparse import Matrix_integer_sparse
     32from sage.rings.all import ZZ
     33from sage.combinat.root_system.cartan_type import CartanType, CartanType_abstract
     34from sage.combinat.root_system.root_system import RootSystem
    2435
    25 def cartan_matrix(t):
    26     """
    27     Returns the Cartan matrix corresponding to type t.
    28    
     36class CartanMatrix(Matrix_integer_sparse, CartanType_abstract):
     37    r"""
     38    A (generalized) Cartan matrix.
     39
     40    A matrix `A = (a_{ij})_{i,j \in I}` for some index set `I` is a
     41    generalized Cartan matrix if it satisfies the following properties:
     42
     43    - `a_{ii} = 2` for all `i`,
     44    - `a_{ij} \leq 0` for all `i \neq j`,
     45    - `a_{ij} = 0` if and only if `a_{ji} = 0` for all `i \neq j`.
     46
     47    Additionally some reference assume that a Cartan matrix is
     48    *symmetrizable* (see :meth:`is_symmetrizable`). However following Kac, we
     49    do not make that assumption here.
     50
     51    INPUT:
     52
     53    Can be anything which is accepted by ``CartanType`` or a matrix.
     54
     55    If given a matrix, one can also use the keyword ``cartan_type`` when giving
     56    a matrix to explicitly state the type. Otherwise this will try to check the
     57    input matrix against possible standard types of Cartan matrices. To disable
     58    this check, use the keyword ``cartan_type_check = False``.
     59
    2960    EXAMPLES::
    30    
    31         sage: cartan_matrix(['A', 4])
     61
     62        sage: CartanMatrix(['A', 4])
    3263        [ 2 -1  0  0]
    3364        [-1  2 -1  0]
    3465        [ 0 -1  2 -1]
    3566        [ 0  0 -1  2]
    36         sage: cartan_matrix(['B', 6])
     67        sage: CartanMatrix(['B', 6])
    3768        [ 2 -1  0  0  0  0]
    3869        [-1  2 -1  0  0  0]
    3970        [ 0 -1  2 -1  0  0]
    4071        [ 0  0 -1  2 -1  0]
    4172        [ 0  0  0 -1  2 -1]
    4273        [ 0  0  0  0 -2  2]
    43         sage: cartan_matrix(['C', 4])
     74        sage: CartanMatrix(['C', 4])
    4475        [ 2 -1  0  0]
    4576        [-1  2 -1  0]
    4677        [ 0 -1  2 -2]
    4778        [ 0  0 -1  2]
    48         sage: cartan_matrix(['D', 6])
     79        sage: CartanMatrix(['D', 6])
    4980        [ 2 -1  0  0  0  0]
    5081        [-1  2 -1  0  0  0]
    5182        [ 0 -1  2 -1  0  0]
    5283        [ 0  0 -1  2 -1 -1]
    5384        [ 0  0  0 -1  2  0]
    5485        [ 0  0  0 -1  0  2]
    55         sage: cartan_matrix(['E',6])
     86        sage: CartanMatrix(['E',6])
    5687        [ 2  0 -1  0  0  0]
    5788        [ 0  2  0 -1  0  0]
    5889        [-1  0  2 -1  0  0]
    5990        [ 0 -1 -1  2 -1  0]
    6091        [ 0  0  0 -1  2 -1]
    6192        [ 0  0  0  0 -1  2]
    62         sage: cartan_matrix(['E',7])
     93        sage: CartanMatrix(['E',7])
    6394        [ 2  0 -1  0  0  0  0]
    6495        [ 0  2  0 -1  0  0  0]
    6596        [-1  0  2 -1  0  0  0]
    def cartan_matrix(t): 
    6798        [ 0  0  0 -1  2 -1  0]
    6899        [ 0  0  0  0 -1  2 -1]
    69100        [ 0  0  0  0  0 -1  2]
    70         sage: cartan_matrix(['E', 8])
     101        sage: CartanMatrix(['E', 8])
    71102        [ 2  0 -1  0  0  0  0  0]
    72103        [ 0  2  0 -1  0  0  0  0]
    73104        [-1  0  2 -1  0  0  0  0]
    def cartan_matrix(t): 
    76107        [ 0  0  0  0 -1  2 -1  0]
    77108        [ 0  0  0  0  0 -1  2 -1]
    78109        [ 0  0  0  0  0  0 -1  2]
    79         sage: cartan_matrix(['F', 4])
     110        sage: CartanMatrix(['F', 4])
    80111        [ 2 -1  0  0]
    81112        [-1  2 -1  0]
    82113        [ 0 -2  2 -1]
    83114        [ 0  0 -1  2]
    84    
     115
    85116    This is different from MuPAD-Combinat, due to different node
    86117    convention?
    87    
     118
    88119    ::
    89    
    90         sage: cartan_matrix(['G', 2])
     120
     121        sage: CartanMatrix(['G', 2])
    91122        [ 2 -3]
    92123        [-1  2]
    93         sage: cartan_matrix(['A',1,1])
     124        sage: CartanMatrix(['A',1,1])
    94125        [ 2 -2]
    95126        [-2  2]
    96         sage: cartan_matrix(['A', 3, 1])
     127        sage: CartanMatrix(['A', 3, 1])
    97128        [ 2 -1  0 -1]
    98129        [-1  2 -1  0]
    99130        [ 0 -1  2 -1]
    100131        [-1  0 -1  2]
    101         sage: cartan_matrix(['B', 3, 1])
     132        sage: CartanMatrix(['B', 3, 1])
    102133        [ 2  0 -1  0]
    103134        [ 0  2 -1  0]
    104135        [-1 -1  2 -1]
    105136        [ 0  0 -2  2]
    106         sage: cartan_matrix(['C', 3, 1])
     137        sage: CartanMatrix(['C', 3, 1])
    107138        [ 2 -1  0  0]
    108139        [-2  2 -1  0]
    109140        [ 0 -1  2 -2]
    110141        [ 0  0 -1  2]
    111         sage: cartan_matrix(['D', 4, 1])
     142        sage: CartanMatrix(['D', 4, 1])
    112143        [ 2  0 -1  0  0]
    113144        [ 0  2 -1  0  0]
    114145        [-1 -1  2 -1 -1]
    115146        [ 0  0 -1  2  0]
    116147        [ 0  0 -1  0  2]
    117         sage: cartan_matrix(['E', 6, 1])
     148        sage: CartanMatrix(['E', 6, 1])
    118149        [ 2  0 -1  0  0  0  0]
    119150        [ 0  2  0 -1  0  0  0]
    120151        [-1  0  2  0 -1  0  0]
    def cartan_matrix(t): 
    122153        [ 0  0 -1 -1  2 -1  0]
    123154        [ 0  0  0  0 -1  2 -1]
    124155        [ 0  0  0  0  0 -1  2]
    125         sage: cartan_matrix(['E', 7, 1])
     156        sage: CartanMatrix(['E', 7, 1])
    126157        [ 2 -1  0  0  0  0  0  0]
    127158        [-1  2  0 -1  0  0  0  0]
    128159        [ 0  0  2  0 -1  0  0  0]
    def cartan_matrix(t): 
    131162        [ 0  0  0  0 -1  2 -1  0]
    132163        [ 0  0  0  0  0 -1  2 -1]
    133164        [ 0  0  0  0  0  0 -1  2]
    134         sage: cartan_matrix(['E', 8, 1])
     165        sage: CartanMatrix(['E', 8, 1])
    135166        [ 2  0  0  0  0  0  0  0 -1]
    136167        [ 0  2  0 -1  0  0  0  0  0]
    137168        [ 0  0  2  0 -1  0  0  0  0]
    def cartan_matrix(t): 
    141172        [ 0  0  0  0  0 -1  2 -1  0]
    142173        [ 0  0  0  0  0  0 -1  2 -1]
    143174        [-1  0  0  0  0  0  0 -1  2]
    144         sage: cartan_matrix(['F', 4, 1])
     175        sage: CartanMatrix(['F', 4, 1])
    145176        [ 2 -1  0  0  0]
    146177        [-1  2 -1  0  0]
    147178        [ 0 -1  2 -1  0]
    148179        [ 0  0 -2  2 -1]
    149180        [ 0  0  0 -1  2]
    150         sage: cartan_matrix(['G', 2, 1])
     181        sage: CartanMatrix(['G', 2, 1])
    151182        [ 2  0 -1]
    152183        [ 0  2 -3]
    153184        [-1 -1  2]
    154185
    155     .. note::
     186    .. NOTE::
    156187
    157         This function is likely to be deprecated in favor of
    158         ``CartanType(...).cartan_matrix()``, to avoid polluting the
     188        Since this is a matrix, :meth:`row()` and :meth:`column()` will return
     189        the standard row and column respectively. To get the row with the
     190        indices as in Dynkin diagrams/Cartan types, use
     191        :meth:`row_with_indices()` and :meth:`column_with_indices()`
     192        respectively.
     193    """
     194    __metaclass__ = ClasscallMetaclass
     195
     196    @staticmethod
     197    def __classcall_private__(cls, *args, **kwds):
     198        """
     199        Normalize input so we can inherit from spare integer matrix.
     200
     201        .. NOTE::
     202
     203            To disable the Cartan type check, use the optional argument
     204            ``cartan_type_check = False``.
     205
     206        EXAMPLES::
     207
     208            sage: C = CartanMatrix(['A',1,1])
     209            sage: C2 = CartanMatrix([[2, -2], [-2, 2]])
     210            sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1])
     211            sage: C == C2 and C == C3
     212            True
     213        """
     214        # Special case with 0 args and kwds has cartan type
     215        if "cartan_type" in kwds and len(args) == 0:
     216            args = (CartanType(kwds["cartan_type"]),)
     217        if len(args) == 0:
     218            data = []
     219            n = 0
     220            index_set = tuple()
     221            cartan_type = None
     222            subdivisions = None
     223        elif len(args) == 4 and isinstance(args[0], MatrixSpace): # For pickling
     224            return typecall(cls, args[0], args[1], args[2], args[3])
     225        elif isinstance(args[0], CartanMatrix):
     226            return args[0]
     227        else:
     228            cartan_type = None
     229            dynkin_diagram = None
     230            subdivisions = None
     231            try:
     232                cartan_type = CartanType(args[0])
     233                dynkin_diagram = cartan_type.dynkin_diagram()
     234            except (TypeError, ValueError):
     235                pass
     236
     237            if dynkin_diagram is not None:
     238                n = cartan_type.rank()
     239                index_set = dynkin_diagram.index_set()
     240                reverse = dict((index_set[i], i) for i in range(len(index_set)))
     241                data = {(i, i): 2 for i in range(n)}
     242                for (i,j,l) in dynkin_diagram.edge_iterator():
     243                    data[(reverse[j], reverse[i])] = -l
     244            else:
     245                M = matrix(args[0])
     246                if not is_generalized_cartan_matrix(M):
     247                    raise ValueError("The input matrix is not a generalized Cartan matrix.")
     248                n = M.ncols()
     249                if "cartan_type" in kwds:
     250                    cartan_type = CartanType(kwds["cartan_type"])
     251                elif n == 1:
     252                    cartan_type = CartanType(['A', 1])
     253                elif kwds.get("cartan_type_check", True):
     254                    cartan_type = find_cartan_type_from_matrix(M)
     255                data = M.dict()
     256                subdivisions = M._subdivisions
     257
     258            if len(args) == 1:
     259                if cartan_type is not None:
     260                    index_set = tuple(cartan_type.index_set())
     261                else:
     262                    index_set = tuple(range(M.ncols()))
     263            elif len(args) == 2:
     264                index_set = tuple(args[1])
     265                if len(index_set) != n and len(set(index_set)) != n:
     266                    raise ValueError("The given index set is not valid.")
     267            else:
     268                raise ValueError("Too many arguments.")
     269
     270        mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, cartan_type, index_set)
     271        mat._subdivisions = subdivisions
     272        return mat
     273
     274    def __init__(self, parent, data, cartan_type, index_set):
     275        """
     276        Initialize ``self``.
     277
     278        TESTS::
     279
     280            sage: C = CartanMatrix(['A',1,1])
     281            sage: TestSuite(C).run(skip=["_test_category", "_test_change_ring"])
     282        """
     283        Matrix_integer_sparse.__init__(self, parent, data, False, False)
     284        self._cartan_type = cartan_type
     285        self._index_set = index_set
     286        self.set_immutable()
     287
     288    def root_system(self):
     289        """
     290        Return the root system corresponding to ``self``.
     291
     292        EXAMPLES::
     293
     294            sage: C = CartanMatrix(['A',3])
     295            sage: C.root_system()
     296            Root system of type ['A', 3]
     297        """
     298        if self._cartan_type is not None:
     299            return RootSystem(self._cartan_type)
     300        return self.dynkin_diagram().root_system()
     301
     302    def root_space(self):
     303        """
     304        Return the root space corresponding to ``self``.
     305
     306        EXAMPLES::
     307
     308            sage: C = CartanMatrix(['A',3])
     309            sage: C.root_space()
     310            Root space over the Rational Field of the Root system of type ['A', 3]
     311        """
     312        return self.root_system().root_space()
     313
     314    def reflection_group(self, type="matrix"):
     315        """
     316        Return the reflection group corresponding to ``self``.
     317
     318        EXAMPLES::
     319
     320            sage: C = CartanMatrix(['A',3])
     321            sage: C.reflection_group()
     322            Weyl Group of type ['A', 3] (as a matrix group acting on the root space)
     323        """
     324        from sage.groups.perm_gps.permgroup_named import SymmetricGroup
     325        RS = self.root_space()
     326        G = RS.weyl_group()
     327        if type == "matrix":
     328            return G
     329        elif type == "permutation":
     330            assert G.is_finite()
     331            Phi = RS.roots()
     332            gens = {}
     333            S = SymmetricGroup(len(Phi))
     334            for i in self.index_set():
     335                pi = S([ Phi.index( beta.simple_reflection(i) ) + 1 for beta in Phi ])
     336                gens[i] = pi
     337            return S.subgroup( gens[i] for i in gens )
     338        else:
     339            raise ValueError("The reflection group is only available as a matrix group or as a permutation group.")
     340
     341    ##########################################################################
     342    # Cartan type methods
     343
     344    def index_set(self):
     345        """
     346        Return the index set of ``self``.
     347
     348        EXAMPLES::
     349
     350            sage: C = CartanMatrix(['A',1,1])
     351            sage: C.index_set()
     352            (0, 1)
     353            sage: C = CartanMatrix(['E',6])
     354            sage: C.index_set()
     355            (1, 2, 3, 4, 5, 6)
     356        """
     357        return self._index_set
     358
     359    def cartan_type(self):
     360        """
     361        Return the Cartan type of ``self`` or ``None`` if unknown.
     362
     363        EXAMPLES::
     364
     365            sage: C = CartanMatrix(['A',4,1])
     366            sage: C.cartan_type()
     367            ['A', 4, 1]
     368
     369        If the Cartan type is unknown::
     370
     371            sage: C = CartanMatrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
     372            sage: C.cartan_type()
     373        """
     374        return self._cartan_type
     375
     376    def rank(self):
     377        r"""
     378        Return the rank of ``self``.
     379
     380        EXAMPLES::
     381
     382            sage: CartanMatrix(['C',3]).rank()
     383            3
     384            sage: CartanMatrix(["A2","B2","F4"]).rank()
     385            8
     386        """
     387        return self.ncols()
     388
     389    @cached_method
     390    def dynkin_diagram(self):
     391        """
     392        Return the Dynkin diagram corresponding to ``self``.
     393
     394        EXAMPLES::
     395
     396            sage: C = CartanMatrix(['A',2])
     397            sage: C.dynkin_diagram()
     398            O---O
     399            1   2
     400            A2
     401            sage: C = CartanMatrix(['F',4,1])
     402            sage: C.dynkin_diagram()
     403            O---O---O=>=O---O
     404            0   1   2   3   4
     405            F4~
     406            sage: C = CartanMatrix([[2,-4],[-4,2]])
     407            sage: C.dynkin_diagram()
     408            Dynkin diagram of rank 2
     409        """
     410        from sage.combinat.root_system.dynkin_diagram import DynkinDiagram
     411        if self._cartan_type is not None:
     412            return DynkinDiagram(self._cartan_type)
     413
     414        from dynkin_diagram import DynkinDiagram_class
     415        n = self.nrows()
     416        g = DynkinDiagram_class(self)
     417        for i in range(n):
     418            for j in range(n):
     419                if self[i,j] == -1:
     420                    g.add_edge(i, j)
     421                elif self[i,j] < -1:
     422                    g.add_edge(i, j, -self[i,j])
     423        return g
     424
     425    def cartan_matrix(self):
     426        r"""
     427        Return the Cartan matrix of ``self``.
     428
     429        EXAMPLES::
     430
     431            sage: CartanMatrix(['C',3]).cartan_matrix()
     432            [ 2 -1  0]
     433            [-1  2 -2]
     434            [ 0 -1  2]
     435        """
     436        return self
     437
     438    def dual(self):
     439        r"""
     440        Return the dual Cartan matrix of ``self``, which is obtained by taking
     441        the transpose.
     442
     443        EXAMPLES::
     444
     445            sage: ct = CartanType(['C',3])
     446            sage: M = CartanMatrix(ct); M
     447            [ 2 -1  0]
     448            [-1  2 -2]
     449            [ 0 -1  2]
     450            sage: M.dual()
     451            [ 2 -1  0]
     452            [-1  2 -1]
     453            [ 0 -2  2]
     454            sage: M.dual() == CartanMatrix(ct.dual())
     455            True
     456            sage: M.dual().cartan_type() == ct.dual()
     457            True
     458        """
     459        return CartanMatrix(self._cartan_type.dual())
     460
     461    def is_crystallographic(self):
     462        """
     463        Implements :meth:`CartanType_abstract.is_crystallographic`.
     464
     465        A Cartan matrix is crystallographic if it is symmetrizable.
     466
     467        EXAMPLES::
     468
     469            sage: CartanMatrix(['F',4]).is_crystallographic()
     470            True
     471        """
     472        return self.is_symmetrizable()
     473
     474    def column_with_indices(self, j):
     475        """
     476        Return the `j^{th}` column `(a_{i,j})_i` of ``self`` as a container
     477        (or iterator) of tuples `(i, a_{i,j})`
     478
     479        EXAMPLES::
     480
     481            sage: M = CartanMatrix(['B',4])
     482            sage: [ (i,a) for (i,a) in M.column_with_indices(3) ]
     483            [(3, 2), (2, -1), (4, -2)]
     484        """
     485        return self.dynkin_diagram().column(j)
     486
     487    def row_with_indices(self, i):
     488        """
     489        Return the `i^{th}` row `(a_{i,j})_j` of ``self`` as a container
     490        (or iterator) of tuples `(j, a_{i,j})`
     491
     492        EXAMPLES::
     493
     494            sage: M = CartanMatrix(['C',4])
     495            sage: [ (i,a) for (i,a) in M.row_with_indices(3) ]
     496            [(3, 2), (2, -1), (4, -2)]
     497        """
     498        return self.dynkin_diagram().row(i)
     499
     500    def is_finite(self):
     501        """
     502        Return if ``self`` is a finite type or ``False`` if unknown.
     503
     504        EXAMPLES::
     505
     506            sage: M = CartanMatrix(['C',4])
     507            sage: M.is_finite()
     508            True
     509            sage: M = CartanMatrix(['D',4,1])
     510            sage: M.is_finite()
     511            False
     512        """
     513        if self._cartan_type is None:
     514            return False
     515        return self._cartan_type.is_finite()
     516
     517    def is_affine(self):
     518        """
     519        Return if ``self`` is an affine type or ``False`` if unknown.
     520
     521        EXAMPLES::
     522
     523            sage: M = CartanMatrix(['C',4])
     524            sage: M.is_affine()
     525            False
     526            sage: M = CartanMatrix(['D',4,1])
     527            sage: M.is_affine()
     528            True
     529        """
     530        if self._cartan_type is None:
     531            return False
     532        return self._cartan_type.is_affine()
     533
     534def is_generalized_cartan_matrix(M):
     535    """
     536    Return ``True`` if ``M`` is a generalized Cartan matrix. For a definition
     537    of a generalized Cartan matrix, see :class:`CartanMatrix`.
     538
     539    EXAMPLES::
     540
     541        sage: from sage.combinat.root_system.cartan_matrix import is_generalized_cartan_matrix
     542        sage: M = matrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
     543        sage: is_generalized_cartan_matrix(M)
     544        True
     545        sage: M = matrix([[2,-1,-2], [-1,2,-1], [0,-1,2]])
     546        sage: is_generalized_cartan_matrix(M)
     547        False
     548        sage: M = matrix([[1,-1,-2], [-1,2,-1], [-2,-1,2]])
     549        sage: is_generalized_cartan_matrix(M)
     550        False
     551
     552    A non-symmetrizable example::
     553
     554        sage: M = matrix([[2,-1,-2], [-1,2,-1], [-1,-1,2]])
     555        sage: is_generalized_cartan_matrix(M)
     556        True
     557    """
     558    if not is_Matrix(M):
     559        return False
     560    if not M.is_square():
     561        return False
     562    n = M.ncols()
     563    for i in xrange(n):
     564        if M[i,i] != 2:
     565            return False
     566        for j in xrange(i+1, n):
     567            if M[i,j] > 0 or M[j,i] > 0:
     568                return False
     569            elif M[i,j] == 0 and M[j,i] != 0:
     570                return False
     571            elif M[j,i] == 0 and M[i,j] != 0:
     572                return False
     573    return True
     574
     575def find_cartan_type_from_matrix(CM):
     576    """
     577    Find a Cartan type by direct comparison of matrices given from the
     578    generalized Cartan matrix ``CM`` and return ``None`` if not found.
     579
     580    INPUT:
     581
     582    - ``CM`` -- A generalized Cartan matrix
     583
     584    EXAMPLES::
     585
     586        sage: from sage.combinat.root_system.cartan_matrix import find_cartan_type_from_matrix
     587        sage: M = matrix([[2,-1,-1], [-1,2,-1], [-1,-1,2]])
     588        sage: find_cartan_type_from_matrix(M)
     589        ['A', 2, 1]
     590        sage: M = matrix([[2,-1,0], [-1,2,-2], [0,-1,2]])
     591        sage: find_cartan_type_from_matrix(M)
     592        ['C', 3]
     593        sage: M = matrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
     594        sage: find_cartan_type_from_matrix(M)
     595    """
     596    n = CM.ncols()
     597    # Build the list to test based upon rank
     598    if n == 1:
     599        return CartanType(['A', 1])
     600
     601    test = [['A', n]]
     602    if n >= 2:
     603        if n == 2:
     604            test += [['G',2], ['A',2,2]]
     605        test += [['B',n], ['A',n-1,1]]
     606    if n >= 3:
     607        if n == 3:
     608            test += [['G',2,1], ['D',4,3]]
     609        test += [['C',n], ['BC',n-1,2], ['C',n-1,1]]
     610    if n >= 4:
     611        if n == 4:
     612            test += [['F',4], ['G',2,1], ['D',4,3]]
     613        test += [['D',n], ['B',n-1,1]]
     614    if n == 5:
     615        test += [['F',4,1], ['D',n-1,1]]
     616    elif n == 6:
     617        test.append(['E',6])
     618    elif n == 7:
     619        test += [['E',7], ['E',6,1]]
     620    elif n == 8:
     621        test += [['E',8], ['E',7,1]]
     622    elif n == 9:
     623        test.append(['E',8,1])
     624
     625    # Test every possible Cartan type and its dual
     626    for x in test:
     627        ct = CartanType(x)
     628        if ct.cartan_matrix() == CM:
     629            return ct
     630        if ct == ct.dual():
     631            continue
     632        ct = ct.dual()
     633        if ct.cartan_matrix() == CM:
     634            return ct
     635    return None
     636
     637def cartan_matrix(t):
     638    """
     639    Return the Cartan matrix of type `t`.
     640
     641    .. NOTE::
     642
     643        This function is deprecated in favor of
     644        ``CartanMatrix(...)``, to avoid polluting the
    159645        global namespace.
     646
     647    EXAMPLES::
     648
     649        sage: cartan_matrix(['A', 4])
     650        doctest:1: DeprecationWarning: cartan_matrix() is deprecated. Use CartanMatrix() instead
     651        See http://trac.sagemath.org/14137 for details.
     652        [ 2 -1  0  0]
     653        [-1  2 -1  0]
     654        [ 0 -1  2 -1]
     655        [ 0  0 -1  2]
    160656    """
    161     return CartanType(t).cartan_matrix()
     657    from sage.misc.superseded import deprecation
     658    deprecation(14137, 'cartan_matrix() is deprecated. Use CartanMatrix() instead')
     659    return CartanMatrix(t)
     660
  • sage/combinat/root_system/cartan_type.py

    diff --git a/sage/combinat/root_system/cartan_type.py b/sage/combinat/root_system/cartan_type.py
    a b class CartanType_crystallographic(Cartan 
    13261326            [ 0 -1  2 -1]
    13271327            [ 0  0 -1  2]
    13281328        """
    1329         return self.dynkin_diagram().cartan_matrix()
     1329        from sage.combinat.root_system.cartan_matrix import CartanMatrix
     1330        return CartanMatrix(self.dynkin_diagram())
    13301331
    13311332    @cached_method
    13321333    def coxeter_diagram(self):
  • sage/combinat/root_system/dynkin_diagram.py

    diff --git a/sage/combinat/root_system/dynkin_diagram.py b/sage/combinat/root_system/dynkin_diagram.py
    a b AUTHORS: 
    2626from sage.misc.cachefunc import cached_method
    2727from sage.graphs.digraph import DiGraph
    2828from cartan_type import CartanType, CartanType_abstract
     29from sage.combinat.root_system.cartan_matrix import CartanMatrix
    2930from sage.misc.superseded import deprecated_function_alias
    3031
    3132def DynkinDiagram(*args):
    class DynkinDiagram_class(DiGraph, Carta 
    175176            1   2
    176177            G2
    177178        """
    178         result = self.cartan_type().ascii_art() +"\n" if hasattr(self.cartan_type(), "ascii_art") else ""
     179        ct = self.cartan_type()
     180        result = ct.ascii_art() +"\n" if hasattr(ct, "ascii_art") else ""
    179181
    180         if self.cartan_type() is None:
     182        if ct is None or isinstance(ct, CartanMatrix):
    181183            return result+"Dynkin diagram of rank %s"%self.rank()
    182184        else:
    183             return result+"%s"%self.cartan_type()._repr_(compact = True)
     185            return result+"%s"%ct._repr_(compact=True)
    184186            #return result+"Dynkin diagram of type %s"%self.cartan_type()._repr_(compact = True)
    185187
    186188    def _latex_(self, scale=0.5):
    class DynkinDiagram_class(DiGraph, Carta 
    326328            [-1  2 -2]
    327329            [ 0 -1  2]
    328330        """
    329         from sage.matrix.constructor import identity_matrix
    330         from sage.rings.all import ZZ
    331         index_set = self.index_set()
    332         reverse = dict((index_set[i], i) for i in range(len(index_set)))
    333         m = 2*identity_matrix(ZZ, len(self.index_set()), sparse=True)
    334         for (i,j,l) in self.edge_iterator():
    335             m[reverse[j], reverse[i]] = -l
    336         m.set_immutable()
    337         return m
     331        return CartanMatrix(self)
    338332
    339333    def dual(self):
    340334        r"""
  • sage/combinat/root_system/type_reducible.py

    diff --git a/sage/combinat/root_system/type_reducible.py b/sage/combinat/root_system/type_reducible.py
    a b class CartanType(SageObject, CartanType_ 
    220220
    221221    def cartan_matrix(self, subdivide=True):
    222222        """
    223         Returns the Cartan matrix associated with self. By default
     223        Return the Cartan matrix associated with ``self``. By default
    224224        the Cartan matrix is a subdivided block matrix showing the
    225225        reducibility but the subdivision can be suppressed with
    226         the option subdivide=False.
     226        the option ``subdivide = False``.
     227
     228        .. TODO::
     229
     230            Currently ``subdivide`` is currently ignored.
    227231
    228232        EXAMPLES::
    229        
     233
    230234            sage: ct = CartanType("A2","B2")
    231235            sage: ct.cartan_matrix()
    232236            [ 2 -1| 0  0]
    class CartanType(SageObject, CartanType_ 
    240244            [ 0  0  2 -1]
    241245            [ 0  0 -2  2]
    242246        """
    243         return block_diagonal_matrix([t.cartan_matrix() for t in self._types], subdivide=subdivide)
     247        from sage.combinat.root_system.cartan_matrix import CartanMatrix
     248        return CartanMatrix(block_diagonal_matrix([t.cartan_matrix() for t in self._types], subdivide=subdivide),
     249                            cartan_type=self)
    244250
    245251    def dynkin_diagram(self):
    246252        """