# Ticket #14137: cartan_matrix.py

File cartan_matrix.py, 7.8 KB (added by stumpc5, 7 years ago)
Line
1"""
2Cartan matrices
3
4AUTHORS:
5
6- Travis Scrimshaw (2012-04-22): Nicolas M. Thiery moved matrix creation to
7    :class:`CartanType` to prepare cartan_matrix() for deprecation.
8
9- Christian Stump
10"""
11#*****************************************************************************
12#       Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
13#                     2012 Christian Stump <christian.stump@gmail.com>
14#
16#
17#    This code is distributed in the hope that it will be useful,
18#    but WITHOUT ANY WARRANTY; without even the implied warranty of
19#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20#    General Public License for more details.
21#
22#  The full text of the GPL is available at:
23#
25#*****************************************************************************
26from sage.misc.cachefunc import cached_method
27from cartan_type import CartanType
28from dynkin_diagram import DynkinDiagram
29from sage.matrix.constructor import Matrix
30from sage.matrix.matrix import is_Matrix
31
32class CartanMatrix(object):
33    def __init__(self, *args):
34        if len(args) == 0:
35            M = Matrix()
36            n = 0
37            index_set = tuple()
38            cartan_type = None
39        elif not is_Matrix(args[0]):
40            ct = CartanType(*args)
41            if not hasattr(ct, "cartan_matrix"):
42                raise ValueError, "Cartan matrix data not yet hardcoded for type %s"%ct
43            M = ct.cartan_matrix()
44            n = M.ncols()
45            index_set = ct.index_set()
46            cartan_type = ct
47        else:
48            M = args[0]
49            n = M.ncols()
50            cartan_type = None
51            assert is_generalized_cartan_matrix(M), "The input matrix is not a generalized Cartan matrix."
52            M.set_immutable()
53            if len(args) == 1:
54                index_set = tuple(range(n))
55            elif len(args) == 2:
56                index_set = tuple( x for x in args[1] )
57                assert len(set(index_set)) == n, "The given index set is not valid."
58            else:
59                raise ValueError, "You have given a symmetrizable matrix, but too many additional arguments."
60
61        self._M = M
62        self._rank = n
63        self._index_set = index_set
64        self._cartan_type = cartan_type
65
66    def __repr__(self):
67        return self._M.__repr__()
68
69    def index_set(self):
70        return self._index_set
71
72    def dynkin_diagram(self):
73        if self._cartan_type is not None:
74            return DynkinDiagram(self._cartan_type)
75        else:
76            return DynkinDiagram(self._M)
77
78    def cartan_type(self):
79        return self._cartan_type
80
81    def root_system(self):
82        return self.dynkin_diagram().root_system()
83
84    def root_space(self):
85        return self.root_system().root_space()
86
87    def reflection_group(self, type="matrix"):
88        from sage.groups.perm_gps.permgroup_named import SymmetricGroup
89        RS = self.root_space()
90        G = RS.weyl_group()
91        if type == "matrix":
92            return G
93        elif type == "permutation":
94            assert G.is_finite()
95            Phi = RS.roots()
96            gens = {}
97            S = SymmetricGroup(len(Phi))
98            for i in self.index_set():
99                pi = S([ Phi.index( beta.simple_reflection(i) ) + 1 for beta in Phi ])
100                gens[i] = pi
101            return S.subgroup( gens[i] for i in gens )
102        else:
103            raise ValueError, "The reflection group is only available as a matrix group or as a permutation group."
104
105def is_generalized_cartan_matrix(M):
106        n = M.ncols()
107        return M.is_square() and \
108               all( M[i,i] == 2 for i in xrange(n) ) and \
109               all( M[i,j] <= 0 for i in range(n) for j in range(n) if i != j ) and \
110               all( M[j,i] == 0 for i in range(n) for j in range(i+1,n) if M[i,j] == 0 ) and \
111               M.is_symmetrizable()
112
113def cartan_matrix(t):
114    """
115    Returns the Cartan matrix corresponding to type t.
116
117    EXAMPLES::
118
119        sage: cartan_matrix(['A', 4])
120        [ 2 -1  0  0]
121        [-1  2 -1  0]
122        [ 0 -1  2 -1]
123        [ 0  0 -1  2]
124        sage: cartan_matrix(['B', 6])
125        [ 2 -1  0  0  0  0]
126        [-1  2 -1  0  0  0]
127        [ 0 -1  2 -1  0  0]
128        [ 0  0 -1  2 -1  0]
129        [ 0  0  0 -1  2 -1]
130        [ 0  0  0  0 -2  2]
131        sage: cartan_matrix(['C', 4])
132        [ 2 -1  0  0]
133        [-1  2 -1  0]
134        [ 0 -1  2 -2]
135        [ 0  0 -1  2]
136        sage: cartan_matrix(['D', 6])
137        [ 2 -1  0  0  0  0]
138        [-1  2 -1  0  0  0]
139        [ 0 -1  2 -1  0  0]
140        [ 0  0 -1  2 -1 -1]
141        [ 0  0  0 -1  2  0]
142        [ 0  0  0 -1  0  2]
143        sage: cartan_matrix(['E',6])
144        [ 2  0 -1  0  0  0]
145        [ 0  2  0 -1  0  0]
146        [-1  0  2 -1  0  0]
147        [ 0 -1 -1  2 -1  0]
148        [ 0  0  0 -1  2 -1]
149        [ 0  0  0  0 -1  2]
150        sage: cartan_matrix(['E',7])
151        [ 2  0 -1  0  0  0  0]
152        [ 0  2  0 -1  0  0  0]
153        [-1  0  2 -1  0  0  0]
154        [ 0 -1 -1  2 -1  0  0]
155        [ 0  0  0 -1  2 -1  0]
156        [ 0  0  0  0 -1  2 -1]
157        [ 0  0  0  0  0 -1  2]
158        sage: cartan_matrix(['E', 8])
159        [ 2  0 -1  0  0  0  0  0]
160        [ 0  2  0 -1  0  0  0  0]
161        [-1  0  2 -1  0  0  0  0]
162        [ 0 -1 -1  2 -1  0  0  0]
163        [ 0  0  0 -1  2 -1  0  0]
164        [ 0  0  0  0 -1  2 -1  0]
165        [ 0  0  0  0  0 -1  2 -1]
166        [ 0  0  0  0  0  0 -1  2]
167        sage: cartan_matrix(['F', 4])
168        [ 2 -1  0  0]
169        [-1  2 -1  0]
170        [ 0 -2  2 -1]
171        [ 0  0 -1  2]
172
173    This is different from MuPAD-Combinat, due to different node
174    convention?
175
176    ::
177
178        sage: cartan_matrix(['G', 2])
179        [ 2 -3]
180        [-1  2]
181        sage: cartan_matrix(['A',1,1])
182        [ 2 -2]
183        [-2  2]
184        sage: cartan_matrix(['A', 3, 1])
185        [ 2 -1  0 -1]
186        [-1  2 -1  0]
187        [ 0 -1  2 -1]
188        [-1  0 -1  2]
189        sage: cartan_matrix(['B', 3, 1])
190        [ 2  0 -1  0]
191        [ 0  2 -1  0]
192        [-1 -1  2 -1]
193        [ 0  0 -2  2]
194        sage: cartan_matrix(['C', 3, 1])
195        [ 2 -1  0  0]
196        [-2  2 -1  0]
197        [ 0 -1  2 -2]
198        [ 0  0 -1  2]
199        sage: cartan_matrix(['D', 4, 1])
200        [ 2  0 -1  0  0]
201        [ 0  2 -1  0  0]
202        [-1 -1  2 -1 -1]
203        [ 0  0 -1  2  0]
204        [ 0  0 -1  0  2]
205        sage: cartan_matrix(['E', 6, 1])
206        [ 2  0 -1  0  0  0  0]
207        [ 0  2  0 -1  0  0  0]
208        [-1  0  2  0 -1  0  0]
209        [ 0 -1  0  2 -1  0  0]
210        [ 0  0 -1 -1  2 -1  0]
211        [ 0  0  0  0 -1  2 -1]
212        [ 0  0  0  0  0 -1  2]
213        sage: cartan_matrix(['E', 7, 1])
214        [ 2 -1  0  0  0  0  0  0]
215        [-1  2  0 -1  0  0  0  0]
216        [ 0  0  2  0 -1  0  0  0]
217        [ 0 -1  0  2 -1  0  0  0]
218        [ 0  0 -1 -1  2 -1  0  0]
219        [ 0  0  0  0 -1  2 -1  0]
220        [ 0  0  0  0  0 -1  2 -1]
221        [ 0  0  0  0  0  0 -1  2]
222        sage: cartan_matrix(['E', 8, 1])
223        [ 2  0  0  0  0  0  0  0 -1]
224        [ 0  2  0 -1  0  0  0  0  0]
225        [ 0  0  2  0 -1  0  0  0  0]
226        [ 0 -1  0  2 -1  0  0  0  0]
227        [ 0  0 -1 -1  2 -1  0  0  0]
228        [ 0  0  0  0 -1  2 -1  0  0]
229        [ 0  0  0  0  0 -1  2 -1  0]
230        [ 0  0  0  0  0  0 -1  2 -1]
231        [-1  0  0  0  0  0  0 -1  2]
232        sage: cartan_matrix(['F', 4, 1])
233        [ 2 -1  0  0  0]
234        [-1  2 -1  0  0]
235        [ 0 -1  2 -1  0]
236        [ 0  0 -2  2 -1]
237        [ 0  0  0 -1  2]
238        sage: cartan_matrix(['G', 2, 1])
239        [ 2  0 -1]
240        [ 0  2 -3]
241        [-1 -1  2]
242
243    .. note::
244
245        This function is likely to be deprecated in favor of
246        ``CartanType(...).cartan_matrix()``, to avoid polluting the
247        global namespace.
248    """
249    from sage.misc.misc import deprecation
250    from cartan_type import CartanType
251    deprecation("cartan_type is deprecated, use CartanType instead!")
252    return CartanMatrix(t)