Ticket #12882: trac_12882-generalized_cartan_matrix_as_dynkin_diagram_input-cs.patch

File trac_12882-generalized_cartan_matrix_as_dynkin_diagram_input-cs.patch, 11.8 KB (added by stumpc5, 10 years ago)
  • sage/combinat/root_system/dynkin_diagram.py

    # HG changeset patch
    # User Christian Stump <christian.stump at gmail.com>
    # Date 1352623639 -3600
    # Node ID 79ce1f7cd3129cb2207af0607b4012ea77251484
    # Parent  257ad14e3668760e87b5978588eeec0d98da40a7
    #12882 Allows a generalized Cartan matrix as input for Dynkin diagrams
    
    diff --git a/sage/combinat/root_system/dynkin_diagram.py b/sage/combinat/root_system/dynkin_diagram.py
    a b AUTHORS: 
    55
    66- Travis Scrimshaw (2012-04-22): Nicolas M. Thiery moved Cartan matrix creation
    77    to here and I cached results for speed.
    8    
     8
     9- Christian Stump (2012-11-11): Added Cartan matrix as possible input for Dynkin diagrams
    910"""
    1011#*****************************************************************************
    11 #       Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>, 
     12#       Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
    1213#
    1314#  Distributed under the terms of the GNU General Public License (GPL)
    1415#
    AUTHORS: 
    2425from sage.misc.cachefunc import cached_method
    2526from sage.graphs.digraph import DiGraph
    2627from cartan_type import CartanType, CartanType_abstract
     28from sage.matrix.matrix import is_Matrix
     29from sage.functions.generalized import sgn
    2730
    2831def DynkinDiagram(*args):
    2932    """
    3033    INPUT:
    3134
    32      -  ``ct`` - a Cartan Type
     35    The input can be one of the following:
    3336
    34     Returns a Dynkin diagram for type ct.
    35    
    36    
     37    - empty to obtain an empty Dynkin diagram
     38    - input for a Cartan type
     39    - Cartan matrix
     40    - Cartan matrix and an indexing set
     41
     42    Returns a corresponding Dynkin diagram.
     43
     44
    3745    The edge multiplicities are encoded as edge labels. This uses the
    3846    convention in Kac / Fulton Harris, Representation theory / Wikipedia
    3947    (http://en.wikipedia.org/wiki/Dynkin_diagram). That is for i != j::
    4048
    41        j --k--> i <==> a_ij = -k 
     49       j --k--> i <==> a_ij = -k
    4250                  <==> -scalar(coroot[i], root[j]) = k
    43                   <==> multiple arrows point from the longer root 
     51                  <==> multiple arrows point from the longer root
    4452                       to the shorter one
    45    
     53
    4654    EXAMPLES::
    47    
     55
    4856        sage: DynkinDiagram(['A', 4])
    4957        O---O---O---O
    5058        1   2   3   4
    def DynkinDiagram(*args): 
    6775        5   6   7   8
    6876        A2xB2xF4
    6977
     78        sage: R = RootSystem("A2xB2xF4")
     79        sage: R.cartan_matrix()
     80        [ 2 -1| 0  0| 0  0  0  0]
     81        [-1  2| 0  0| 0  0  0  0]
     82        [-----+-----+-----------]
     83        [ 0  0| 2 -1| 0  0  0  0]
     84        [ 0  0|-2  2| 0  0  0  0]
     85        [-----+-----+-----------]
     86        [ 0  0| 0  0| 2 -1  0  0]
     87        [ 0  0| 0  0|-1  2 -1  0]
     88        [ 0  0| 0  0| 0 -2  2 -1]
     89        [ 0  0| 0  0| 0  0 -1  2]
     90
     91        sage: DD = DynkinDiagram(R.cartan_matrix()); DD
     92        Dynkin diagram of rank 8
     93        sage: DD.cartan_matrix()
     94        [ 2 -1  0  0  0  0  0  0]
     95        [-1  2  0  0  0  0  0  0]
     96        [ 0  0  2 -2  0  0  0  0]
     97        [ 0  0 -1  2  0  0  0  0]
     98        [ 0  0  0  0  2 -1  0  0]
     99        [ 0  0  0  0 -1  2 -2  0]
     100        [ 0  0  0  0  0 -1  2 -1]
     101        [ 0  0  0  0  0  0 -1  2]
     102
    70103    SEE ALSO: :func:`CartanType` for a general discussion on Cartan
    71104    types and in particular node labeling conventions.
    72105    """
    73106    if len(args) == 0:
    74107       return DynkinDiagram_class()
     108    if is_Matrix(args[0]):
     109        M = args[0]
     110        n = M.ncols()
     111        if any( ( M[i,j] > 0 ) if i != j else ( M[i,j] != 2 ) for i in xrange(n) for j in xrange(n) ):
     112            for i in xrange(n):
     113                for j in xrange(n):
     114                    print i,j,M[i,j],M[i,j]>0
     115            raise ValueError, "The input matrix is not a valid Cartan datum."
     116
     117        if not all( sgn(M[i,j]) == sgn(M[j,i]) for i in xrange(n) for j in xrange(i+1,n) ):
     118            raise ValueError, "The input matrix is not a valid Cartan datum."
     119
     120        if not M.is_symmetrizable():
     121            "The input matrix is not a valid Cartan datum."
     122
     123        if len(args) == 1:
     124            index_set = range(n)
     125        elif len(args) == 2:
     126            index_set = tuple( x for x in args[1] )
     127        else:
     128            raise ValueError, "You have given a Cartan matrix, but too many additional arguments."
     129
     130        D = DynkinDiagram_class()
     131        for i in range(n):
     132            for j in range(n):
     133                if i != j:
     134                    D.add_edge( index_set[i], index_set[j], -M[i,j] )
     135        return D
     136
    75137    ct = CartanType(*args)
    76138    if hasattr(ct, "dynkin_diagram"):
    77139        return ct.dynkin_diagram()
    def DynkinDiagram(*args): 
    81143def dynkin_diagram(t):
    82144    """
    83145    Returns the Dynkin diagram of type t.
    84    
     146
    85147    Note that this function is deprecated, and that you should use
    86148    DynkinDiagram instead as this will be disappearing in the near
    87149    future.
    88    
     150
    89151    EXAMPLES::
    90    
     152
    91153        sage: dynkin_diagram(["A", 3])
    92154        doctest:1: DeprecationWarning: dynkin_diagram is deprecated, use DynkinDiagram instead!
    93155        See http://trac.sagemath.org/3654 for details.
    class DynkinDiagram_class(DiGraph, Carta 
    108170         - ``t`` - a Cartan type or None
    109171
    110172        EXAMPLES::
    111        
     173
    112174            sage: d = DynkinDiagram(["A", 3])
    113175            sage: d == loads(dumps(d))
    114176            True
    class DynkinDiagram_class(DiGraph, Carta 
    124186    def __copy__(self):
    125187        """
    126188        EXAMPLES::
    127        
     189
    128190            sage: d = DynkinDiagram(["A", 3])
    129191            sage: type(copy(d))
    130192            <class 'sage.combinat.root_system.dynkin_diagram.DynkinDiagram_class'>
    131193        """
    132         import copy 
     194        import copy
    133195        # we have to go back to the generic copy method because the DiGraph one returns a DiGraph, not a DynkinDiagram
    134196        return copy._reconstruct(self,self.__reduce_ex__(2),0)
    135197
    class DynkinDiagram_class(DiGraph, Carta 
    144206            G2
    145207        """
    146208        result = self.cartan_type().ascii_art() +"\n" if hasattr(self.cartan_type(), "ascii_art") else ""
    147            
     209
    148210        if self.cartan_type() is None:
    149211            return result+"Dynkin diagram of rank %s"%self.rank()
    150212        else:
    class DynkinDiagram_class(DiGraph, Carta 
    154216    def add_edge(self, i, j, label=1):
    155217        """
    156218        EXAMPLES::
    157        
     219
    158220            sage: from sage.combinat.root_system.dynkin_diagram import DynkinDiagram_class
    159221            sage: d = DynkinDiagram_class(CartanType(['A',3]))
    160222            sage: list(sorted(d.edges()))
    class DynkinDiagram_class(DiGraph, Carta 
    198260            [ 2 -1 -1]
    199261            [-2  2 -1]
    200262            [-1 -1  2]
    201        
     263
    202264        """
    203265        # hyperbolic Dynkin diagram of Exercise 4.9 p. 57 of Kac Infinite Dimensional Lie Algebras.
    204266        g = DynkinDiagram()
    class DynkinDiagram_class(DiGraph, Carta 
    214276    def index_set(self):
    215277        """
    216278        EXAMPLES::
    217        
     279
    218280            sage: DynkinDiagram(['C',3]).index_set()
    219281            [1, 2, 3]
    220282            sage: DynkinDiagram("A2","B2","F4").index_set()
    221283            [1, 2, 3, 4, 5, 6, 7, 8]
    222284        """
    223285        return self.vertices()
    224        
     286
    225287    def cartan_type(self):
    226288        """
    227289        EXAMPLES::
    228        
     290
    229291            sage: DynkinDiagram("A2","B2","F4").cartan_type()
    230292            A2xB2xF4
    231293        """
    class DynkinDiagram_class(DiGraph, Carta 
    234296    def rank(self):
    235297        r"""
    236298        Returns the index set for this Dynkin diagram
    237        
     299
    238300        EXAMPLES::
    239        
     301
    240302            sage: DynkinDiagram(['C',3]).rank()
    241303            3
    242304            sage: DynkinDiagram("A2","B2","F4").rank()
    class DynkinDiagram_class(DiGraph, Carta 
    247309    def dynkin_diagram(self):
    248310        """
    249311        EXAMPLES::
    250        
     312
    251313            sage: DynkinDiagram(['C',3]).dynkin_diagram()
    252314            O---O=<=O
    253315            1   2   3
    class DynkinDiagram_class(DiGraph, Carta 
    280342    def dual(self):
    281343        r"""
    282344        Returns the dual Dynkin diagram, obtained by reversing all edges.
    283        
     345
    284346        EXAMPLES::
    285        
     347
    286348            sage: D = DynkinDiagram(['C',3])
    287349            sage: D.edges()
    288350            [(1, 2, 1), (2, 1, 1), (2, 3, 1), (3, 2, 2)]
    class DynkinDiagram_class(DiGraph, Carta 
    294356            [(1, 2, 1), (2, 1, 1), (2, 3, 2), (3, 2, 1)]
    295357            sage: D.dual() == DynkinDiagram(['B',3])
    296358            True
    297        
     359
    298360        TESTS::
    299        
     361
    300362            sage: D = DynkinDiagram(['A',0]); D
    301363            A0
    302364            sage: D.edges()
    class DynkinDiagram_class(DiGraph, Carta 
    335397        """
    336398        return True
    337399
    338 
    339400    def __getitem__(self, i):
    340401        r"""
    341402        With a tuple (i,j) as argument, returns the scalar product
    342403        `\langle
    343404                \alpha^\vee_i, \alpha_j\rangle`.
    344        
     405
    345406        Otherwise, behaves as the usual DiGraph.__getitem__
    346        
     407
    347408        EXAMPLES: We use the `C_4` dynkin diagram as a cartan
    348409        matrix::
    349        
     410
    350411            sage: g = DynkinDiagram(['C',4])
    351412            sage: matrix([[g[i,j] for j in range(1,5)] for i in range(1,5)])
    352413            [ 2 -1  0  0]
    353414            [-1  2 -1  0]
    354415            [ 0 -1  2 -2]
    355416            [ 0  0 -1  2]
    356        
     417
    357418        The neighbors of a node can still be obtained in the usual way::
    358        
     419
    359420            sage: [g[i] for i in range(1,5)]
    360421            [[2], [1, 3], [2, 4], [3]]
    361422        """
    class DynkinDiagram_class(DiGraph, Carta 
    374435        Returns the `j^{th}` column `(a_{i,j})_i` of the
    375436        Cartan matrix corresponding to this Dynkin diagram, as a container
    376437        (or iterator) of tuples `(i, a_{i,j})`
    377        
     438
    378439        EXAMPLES::
    379        
     440
    380441            sage: g = DynkinDiagram(["B",4])
    381442            sage: [ (i,a) for (i,a) in g.column(3) ]
    382443            [(3, 2), (2, -1), (4, -2)]
    class DynkinDiagram_class(DiGraph, Carta 
    388449        Returns the `i^{th}` row `(a_{i,j})_j` of the
    389450        Cartan matrix corresponding to this Dynkin diagram, as a container
    390451        (or iterator) of tuples `(j, a_{i,j})`
    391        
     452
    392453        EXAMPLES::
    393        
     454
    394455            sage: g = DynkinDiagram(["C",4])
    395456            sage: [ (i,a) for (i,a) in g.row(3) ]
    396457            [(3, 2), (2, -1), (4, -2)]
    397458        """
    398459        return [(i,2)] + [(j,-m) for (j, i1, m) in self.incoming_edges(i)]
    399    
     460
    400461    def digraph(self):
    401462        """
    402463        Returns the DiGraph associated to self.
    class DynkinDiagram_class(DiGraph, Carta 
    417478            G.set_latex_options(format="dot2tex", edge_labels = True, color_by_label = self.cartan_type()._index_set_coloring,
    418479                                edge_options = lambda (u,v,label): ({"backward":label ==0}))
    419480        return G
    420        
     481
    421482    def _latex_(self, **options):
    422483        r"""
    423484        Returns the crystal graph as a latex string. This can be exported
    424485        to a file with self.latex_file('filename').
    425        
     486
    426487        EXAMPLES::
    427        
     488
    428489        """
    429490        if not have_dot2tex():
    430491            print "dot2tex not available.  Install after running \'sage -sh\'"
    431492            return
    432493        G = self.digraph()
    433         G.set_latex_options(format="dot2tex", edge_labels = True, 
     494        G.set_latex_options(format="dot2tex", edge_labels = True,
    434495                            edge_options = lambda (u,v,label): ({"backward":label ==0}), **options)
    435496        return G._latex_()
    436497
    437498def precheck(t, letter=None, length=None, affine=None, n_ge=None, n=None):
    438499    """
    439500    EXAMPLES::
    440    
     501
    441502        sage: from sage.combinat.root_system.dynkin_diagram import precheck
    442503        sage: ct = CartanType(['A',4])
    443504        sage: precheck(ct, letter='C')
    def precheck(t, letter=None, length=None 
    468529    if length is not None:
    469530        if len(t) != length:
    470531            raise ValueError, "len(t) must be = %s"%length
    471        
     532
    472533    if affine is not None:
    473534        try:
    474535            if t[2] != affine: