Ticket #14137: trac_14137-cartan_matrix_class-ts.2.patch

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

    # HG changeset patch
    # User Travis Scrimshaw <tscrim@ucdavis.edu>
    # Date 1365541717 25200
    # Node ID b5d5678edcd6d706b16f155f1fe469ac4a3e31ef
    # Parent 38973f20a88c4ed792f885613fe41096822645d7
    #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 
    44from cartan_type import CartanType
    55from virtual_cartan_type import VirtualCartanType
    66from dynkin_diagram import DynkinDiagram, dynkin_diagram
    7 from cartan_matrix import cartan_matrix
     7from cartan_matrix import CartanMatrix, cartan_matrix
    88from coxeter_matrix import coxeter_matrix
    99from root_system import RootSystem, WeylDim
    1010from 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]
     185    """
     186    __metaclass__ = ClasscallMetaclass
    154187
    155     .. note::
     188    @staticmethod
     189    def __classcall_private__(cls, *args, **kwds):
     190        """
     191        Normalize input so we can inherit from spare integer matrix.
    156192
    157         This function is likely to be deprecated in favor of
    158         ``CartanType(...).cartan_matrix()``, to avoid polluting the
     193        .. NOTE::
     194
     195            To disable the Cartan type check, use the optional argument
     196            ``cartan_type_check = False``.
     197
     198        EXAMPLES::
     199
     200            sage: C = CartanMatrix(['A',1,1])
     201            sage: C2 = CartanMatrix([[2, -2], [-2, 2]])
     202            sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1])
     203            sage: C == C2 and C == C3
     204            True
     205        """
     206        # Special case with 0 args and kwds has cartan type
     207        if "cartan_type" in kwds and len(args) == 0:
     208            args = (CartanType(kwds["cartan_type"]),)
     209        if len(args) == 0:
     210            data = []
     211            n = 0
     212            index_set = tuple()
     213            cartan_type = None
     214            subdivisions = None
     215        elif len(args) == 4 and isinstance(args[0], MatrixSpace): # For pickling
     216            return typecall(cls, args[0], args[1], args[2], args[3])
     217        elif isinstance(args[0], CartanMatrix):
     218            return args[0]
     219        else:
     220            cartan_type = None
     221            dynkin_diagram = None
     222            subdivisions = None
     223            try:
     224                cartan_type = CartanType(args[0])
     225                dynkin_diagram = cartan_type.dynkin_diagram()
     226            except (TypeError, ValueError):
     227                pass
     228
     229            if dynkin_diagram is not None:
     230                n = cartan_type.rank()
     231                index_set = dynkin_diagram.index_set()
     232                reverse = dict((index_set[i], i) for i in range(len(index_set)))
     233                data = {(i, i): 2 for i in range(n)}
     234                for (i,j,l) in dynkin_diagram.edge_iterator():
     235                    data[(reverse[j], reverse[i])] = -l
     236            else:
     237                M = matrix(args[0])
     238                if not is_generalized_cartan_matrix(M):
     239                    raise ValueError("The input matrix is not a generalized Cartan matrix.")
     240                n = M.ncols()
     241                if "cartan_type" in kwds:
     242                    cartan_type = CartanType(kwds["cartan_type"])
     243                elif n == 1:
     244                    cartan_type = CartanType(['A', 1])
     245                elif kwds.get("cartan_type_check", True):
     246                    cartan_type = find_cartan_type_from_matrix(M)
     247                data = M.dict()
     248                subdivisions = M._subdivisions
     249
     250            if len(args) == 1:
     251                if cartan_type is not None:
     252                    index_set = tuple(cartan_type.index_set())
     253                else:
     254                    index_set = tuple(range(M.ncols()))
     255            elif len(args) == 2:
     256                index_set = tuple(args[1])
     257                if len(index_set) != n and len(set(index_set)) != n:
     258                    raise ValueError("The given index set is not valid.")
     259            else:
     260                raise ValueError("Too many arguments.")
     261
     262        mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, cartan_type, index_set)
     263        mat._subdivisions = subdivisions
     264        return mat
     265
     266    def __init__(self, parent, data, cartan_type, index_set):
     267        """
     268        Initialize ``self``.
     269
     270        TESTS::
     271
     272            sage: C = CartanMatrix(['A',1,1])
     273            sage: TestSuite(C).run(skip=["_test_category", "_test_change_ring"])
     274        """
     275        Matrix_integer_sparse.__init__(self, parent, data, False, False)
     276        self._cartan_type = cartan_type
     277        self._index_set = index_set
     278        self.set_immutable()
     279
     280    def root_system(self):
     281        """
     282        Return the root system corresponding to ``self``.
     283
     284        EXAMPLES::
     285
     286            sage: C = CartanMatrix(['A',3])
     287            sage: C.root_system()
     288            Root system of type ['A', 3]
     289        """
     290        if self._cartan_type is not None:
     291            return RootSystem(self._cartan_type)
     292        return self.dynkin_diagram().root_system()
     293
     294    def root_space(self):
     295        """
     296        Return the root space corresponding to ``self``.
     297
     298        EXAMPLES::
     299
     300            sage: C = CartanMatrix(['A',3])
     301            sage: C.root_space()
     302            Root space over the Rational Field of the Root system of type ['A', 3]
     303        """
     304        return self.root_system().root_space()
     305
     306    def reflection_group(self, type="matrix"):
     307        """
     308        Return the reflection group corresponding to ``self``.
     309
     310        EXAMPLES::
     311
     312            sage: C = CartanMatrix(['A',3])
     313            sage: C.reflection_group()
     314            Weyl Group of type ['A', 3] (as a matrix group acting on the root space)
     315        """
     316        from sage.groups.perm_gps.permgroup_named import SymmetricGroup
     317        RS = self.root_space()
     318        G = RS.weyl_group()
     319        if type == "matrix":
     320            return G
     321        elif type == "permutation":
     322            assert G.is_finite()
     323            Phi = RS.roots()
     324            gens = {}
     325            S = SymmetricGroup(len(Phi))
     326            for i in self.index_set():
     327                pi = S([ Phi.index( beta.simple_reflection(i) ) + 1 for beta in Phi ])
     328                gens[i] = pi
     329            return S.subgroup( gens[i] for i in gens )
     330        else:
     331            raise ValueError("The reflection group is only available as a matrix group or as a permutation group.")
     332
     333    ##########################################################################
     334    # Cartan type methods
     335
     336    def index_set(self):
     337        """
     338        Return the index set of ``self``.
     339
     340        EXAMPLES::
     341
     342            sage: C = CartanMatrix(['A',1,1])
     343            sage: C.index_set()
     344            (0, 1)
     345            sage: C = CartanMatrix(['E',6])
     346            sage: C.index_set()
     347            (1, 2, 3, 4, 5, 6)
     348        """
     349        return self._index_set
     350
     351    def cartan_type(self):
     352        """
     353        Return the Cartan type of ``self`` or ``None`` if unknown.
     354
     355        EXAMPLES::
     356
     357            sage: C = CartanMatrix(['A',4,1])
     358            sage: C.cartan_type()
     359            ['A', 4, 1]
     360
     361        If the Cartan type is unknown::
     362
     363            sage: C = CartanMatrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
     364            sage: C.cartan_type()
     365        """
     366        return self._cartan_type
     367
     368    def rank(self):
     369        r"""
     370        Return the rank of ``self``.
     371
     372        EXAMPLES::
     373
     374            sage: CartanMatrix(['C',3]).rank()
     375            3
     376            sage: CartanMatrix(["A2","B2","F4"]).rank()
     377            8
     378        """
     379        return self.ncols()
     380
     381    @cached_method
     382    def dynkin_diagram(self):
     383        """
     384        Return the Dynkin diagram corresponding to ``self``.
     385
     386        EXAMPLES::
     387
     388            sage: C = CartanMatrix(['A',2])
     389            sage: C.dynkin_diagram()
     390            O---O
     391            1   2
     392            A2
     393            sage: C = CartanMatrix(['F',4,1])
     394            sage: C.dynkin_diagram()
     395            O---O---O=>=O---O
     396            0   1   2   3   4
     397            F4~
     398        """
     399        from sage.combinat.root_system.dynkin_diagram import DynkinDiagram
     400        if self._cartan_type is not None:
     401            return DynkinDiagram(self._cartan_type)
     402        else:
     403            return DynkinDiagram(self)
     404
     405    def cartan_matrix(self):
     406        r"""
     407        Return the Cartan matrix of ``self``.
     408
     409        EXAMPLES::
     410
     411            sage: CartanMatrix(['C',3]).cartan_matrix()
     412            [ 2 -1  0]
     413            [-1  2 -2]
     414            [ 0 -1  2]
     415        """
     416        return self
     417
     418    def dual(self):
     419        r"""
     420        Return the dual Cartan matrix of ``self``, which is obtained by taking
     421        the transpose.
     422
     423        EXAMPLES::
     424
     425            sage: ct = CartanType(['C',3])
     426            sage: M = CartanMatrix(ct); M
     427            [ 2 -1  0]
     428            [-1  2 -2]
     429            [ 0 -1  2]
     430            sage: M.dual()
     431            [ 2 -1  0]
     432            [-1  2 -1]
     433            [ 0 -2  2]
     434            sage: M.dual() == CartanMatrix(ct.dual())
     435            True
     436            sage: M.dual().cartan_type() == ct.dual()
     437            True
     438        """
     439        return CartanMatrix(self._cartan_type.dual())
     440
     441    def is_crystalographic(self):
     442        """
     443        Implements :meth:`CartanType_abstract.is_crystalographic`.
     444
     445        A Cartan matrix is crystalographic if it is symmetrizable.
     446
     447        EXAMPLES::
     448
     449            sage: CartanMatrix(['F',4]).is_crystalographic()
     450            True
     451        """
     452        return self.is_symmetrizable()
     453
     454    def column(self, j):
     455        """
     456        Return the `j^{th}` column `(a_{i,j})_i` of ``self`` as a container
     457        (or iterator) of tuples `(i, a_{i,j})`
     458
     459        EXAMPLES::
     460
     461            sage: M = CartanMatrix(['B',4])
     462            sage: [ (i,a) for (i,a) in M.column(3) ]
     463            [(3, 2), (2, -1), (4, -2)]
     464        """
     465        return self.dynkin_diagram().column(j)
     466
     467    def row(self, i):
     468        """
     469        Return the `i^{th}` row `(a_{i,j})_j` of ``self`` as a container
     470        (or iterator) of tuples `(j, a_{i,j})`
     471
     472        EXAMPLES::
     473
     474            sage: M = CartanMatrix(['C',4])
     475            sage: [ (i,a) for (i,a) in M.row(3) ]
     476            [(3, 2), (2, -1), (4, -2)]
     477        """
     478        return self.dynkin_diagram().row(i)
     479
     480    def is_finite(self):
     481        """
     482        Return if ``self`` is a finite type or ``False`` if unknown.
     483
     484        EXAMPLES::
     485
     486            sage: M = CartanMatrix(['C',4])
     487            sage: M.is_finite()
     488            True
     489            sage: M = CartanMatrix(['D',4,1])
     490            sage: M.is_finite()
     491            False
     492        """
     493        if self._cartan_type is None:
     494            return False
     495        return self._cartan_type.is_finite()
     496
     497    def is_affine(self):
     498        """
     499        Return if ``self`` is an affine type or ``False`` if unknown.
     500
     501        EXAMPLES::
     502
     503            sage: M = CartanMatrix(['C',4])
     504            sage: M.is_affine()
     505            False
     506            sage: M = CartanMatrix(['D',4,1])
     507            sage: M.is_affine()
     508            True
     509        """
     510        if self._cartan_type is None:
     511            return False
     512        return self._cartan_type.is_affine()
     513
     514def is_generalized_cartan_matrix(M):
     515    """
     516    Return ``True`` if ``M`` is a generalized Cartan matrix. For a definition
     517    of a generalized Cartan matrix, see :class:`CartanMatrix`.
     518
     519    EXAMPLES::
     520
     521        sage: from sage.combinat.root_system.cartan_matrix import is_generalized_cartan_matrix
     522        sage: M = matrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
     523        sage: is_generalized_cartan_matrix(M)
     524        True
     525        sage: M = matrix([[2,-1,-2], [-1,2,-1], [0,-1,2]])
     526        sage: is_generalized_cartan_matrix(M)
     527        False
     528        sage: M = matrix([[1,-1,-2], [-1,2,-1], [-2,-1,2]])
     529        sage: is_generalized_cartan_matrix(M)
     530        False
     531
     532    A non-symmetrizable example::
     533
     534        sage: M = matrix([[2,-1,-2], [-1,2,-1], [-1,-1,2]])
     535        sage: is_generalized_cartan_matrix(M)
     536        True
     537    """
     538    if not is_Matrix(M):
     539        return False
     540    if not M.is_square():
     541        return False
     542    n = M.ncols()
     543    for i in xrange(n):
     544        if M[i,i] != 2:
     545            return False
     546        for j in xrange(i+1, n):
     547            if M[i,j] > 0 or M[j,i] > 0:
     548                return False
     549            elif M[i,j] == 0 and M[j,i] != 0:
     550                return False
     551            elif M[j,i] == 0 and M[i,j] != 0:
     552                return False
     553    return True
     554
     555def find_cartan_type_from_matrix(CM):
     556    """
     557    Find a Cartan type by direct comparison of matrices given from the
     558    generalized Cartan matrix ``CM`` and return ``None`` if not found.
     559
     560    INPUT:
     561
     562    - ``CM`` -- A generalized Cartan matrix
     563
     564    EXAMPLES::
     565
     566        sage: from sage.combinat.root_system.cartan_matrix import find_cartan_type_from_matrix
     567        sage: M = matrix([[2,-1,-1], [-1,2,-1], [-1,-1,2]])
     568        sage: find_cartan_type_from_matrix(M)
     569        ['A', 2, 1]
     570        sage: M = matrix([[2,-1,0], [-1,2,-2], [0,-1,2]])
     571        sage: find_cartan_type_from_matrix(M)
     572        ['C', 3]
     573        sage: M = matrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
     574        sage: find_cartan_type_from_matrix(M)
     575    """
     576    n = CM.ncols()
     577    # Build the list to test based upon rank
     578    if n == 1:
     579        return CartanType(['A', 1])
     580
     581    test = [['A', n]]
     582    if n >= 2:
     583        if n == 2:
     584            test += [['G',2], ['A',2,2]]
     585        test += [['B',n], ['A',n-1,1]]
     586    if n >= 3:
     587        if n == 3:
     588            test += [['G',2,1], ['D',4,3]]
     589        test += [['C',n], ['BC',n-1,2], ['C',n-1,1]]
     590    if n >= 4:
     591        if n == 4:
     592            test += [['F',4], ['G',2,1], ['D',4,3]]
     593        test += [['D',n], ['B',n-1,1]]
     594    if n == 5:
     595        test.append(['F',4,1])
     596    elif n == 6:
     597        test.append(['E',6])
     598    elif n == 7:
     599        test += [['E',7], ['E',6,1]]
     600    elif n == 8:
     601        test += [['E',8], ['E',7,1]]
     602    elif n == 9:
     603        test.append(['E',8,1])
     604
     605    # Test every possible Cartan type and its dual
     606    for x in test:
     607        ct = CartanType(x)
     608        if ct.cartan_matrix() == CM:
     609            return ct
     610        if ct == ct.dual():
     611            continue
     612        ct = ct.dual()
     613        if ct.cartan_matrix() == CM:
     614            return ct
     615    return None
     616
     617def cartan_matrix(t):
     618    """
     619    Return the Cartan matrix of type `t`.
     620
     621    .. NOTE::
     622
     623        This function is deprecated in favor of
     624        ``CartanMatrix(...)``, to avoid polluting the
    159625        global namespace.
     626
     627    EXAMPLES::
     628
     629        sage: cartan_matrix(['A', 4])
     630        doctest:1: DeprecationWarning: cartan_matrix() is deprecated. Use CartanMatrix() instead
     631        See http://trac.sagemath.org/14137 for details.
     632        [ 2 -1  0  0]
     633        [-1  2 -1  0]
     634        [ 0 -1  2 -1]
     635        [ 0  0 -1  2]
    160636    """
    161     return CartanType(t).cartan_matrix()
     637    from sage.misc.superseded import deprecation
     638    deprecation(14137, 'cartan_matrix() is deprecated. Use CartanMatrix() instead')
     639    return CartanMatrix(t)
     640
  • 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_crystalographic(CartanT 
    13141314            [ 0 -1  2 -1]
    13151315            [ 0  0 -1  2]
    13161316        """
    1317         return self.dynkin_diagram().cartan_matrix()
     1317        from sage.combinat.root_system.cartan_matrix import CartanMatrix
     1318        return CartanMatrix(self.dynkin_diagram())
    13181319
    13191320    @cached_method
    13201321    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: 
    2424from sage.misc.cachefunc import cached_method
    2525from sage.graphs.digraph import DiGraph
    2626from cartan_type import CartanType, CartanType_abstract
     27from sage.combinat.root_system.cartan_matrix import CartanMatrix
    2728
    2829def DynkinDiagram(*args):
    2930    r"""
    class DynkinDiagram_class(DiGraph, Carta 
    314315            [-1  2 -2]
    315316            [ 0 -1  2]
    316317        """
    317         from sage.matrix.constructor import identity_matrix
    318         from sage.rings.all import ZZ
    319         index_set = self.index_set()
    320         reverse = dict((index_set[i], i) for i in range(len(index_set)))
    321         m = 2*identity_matrix(ZZ, len(self.index_set()), sparse=True)
    322         for (i,j,l) in self.edge_iterator():
    323             m[reverse[j], reverse[i]] = -l
    324         m.set_immutable()
    325         return m
     318        return CartanMatrix(self)
    326319
    327320    def dual(self):
    328321        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_ 
    219219
    220220    def cartan_matrix(self, subdivide=True):
    221221        """
    222         Returns the Cartan matrix associated with self. By default
     222        Return the Cartan matrix associated with ``self``. By default
    223223        the Cartan matrix is a subdivided block matrix showing the
    224224        reducibility but the subdivision can be suppressed with
    225         the option subdivide=False.
     225        the option ``subdivide = False``.
     226
     227        .. TODO::
     228
     229            Currently ``subdivide`` is currently ignored.
    226230
    227231        EXAMPLES::
    228        
     232
    229233            sage: ct = CartanType("A2","B2")
    230234            sage: ct.cartan_matrix()
    231235            [ 2 -1| 0  0]
    class CartanType(SageObject, CartanType_ 
    239243            [ 0  0  2 -1]
    240244            [ 0  0 -2  2]
    241245        """
    242         return block_diagonal_matrix([t.cartan_matrix() for t in self._types], subdivide=subdivide)
     246        from sage.combinat.root_system.cartan_matrix import CartanMatrix
     247        return CartanMatrix(block_diagonal_matrix([t.cartan_matrix() for t in self._types], subdivide=subdivide),
     248                            cartan_type=self)
    243249
    244250    def dynkin_diagram(self):
    245251        """