# HG changeset patch
# User Christian Stump <christian.stump at gmail.com>
# Date 1352623639 -3600
# Node ID 79ce1f7cd3129cb2207af0607b4012ea77251484
# Parent d6172b786bffcff29765e8b323b3b2964ece57be
#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: |
6 | 6 | - Travis Scrimshaw (2012-04-22): Nicolas M. Thiery moved Cartan matrix creation |
7 | 7 | to here and I cached results for speed. |
8 | 8 | |
| 9 | - Christian Stump, Travis Scrimshaw (2013-04-11): Added Cartan matrix as |
| 10 | possible input for Dynkin diagrams. |
9 | 11 | """ |
10 | 12 | #***************************************************************************** |
11 | | # Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>, |
| 13 | # Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>, |
| 14 | # Copyright (C) 2013 Travis Scrimshaw <tscrim@ucdavis.edu>, |
12 | 15 | # |
13 | 16 | # Distributed under the terms of the GNU General Public License (GPL) |
14 | 17 | # |
… |
… |
AUTHORS: |
22 | 25 | # http://www.gnu.org/licenses/ |
23 | 26 | #***************************************************************************** |
24 | 27 | from sage.misc.cachefunc import cached_method |
| 28 | from sage.matrix.matrix import is_Matrix |
| 29 | from sage.functions.generalized import sgn |
25 | 30 | from sage.graphs.digraph import DiGraph |
26 | | from cartan_type import CartanType, CartanType_abstract |
| 31 | from sage.combinat.root_system.cartan_type import CartanType, CartanType_abstract |
27 | 32 | from sage.combinat.root_system.cartan_matrix import CartanMatrix |
28 | 33 | |
29 | 34 | def DynkinDiagram(*args): |
30 | 35 | r""" |
31 | | Return a Dynkin diagram for type ``ct``. |
| 36 | Return the Dynkin diagram corresponding to the input. |
32 | 37 | |
33 | 38 | INPUT: |
34 | 39 | |
35 | | - ``ct`` -- a Cartan Type |
| 40 | The input can be one of the following: |
| 41 | |
| 42 | - empty to obtain an empty Dynkin diagram |
| 43 | - a Cartan type |
| 44 | - a Cartan matrix |
| 45 | - a Cartan matrix and an indexing set |
36 | 46 | |
37 | 47 | The edge multiplicities are encoded as edge labels. This uses the |
38 | 48 | convention in Hong and Kang and crystals. This is the **opposite** |
… |
… |
def DynkinDiagram(*args): |
87 | 97 | 5 6 7 8 |
88 | 98 | A2xB2xF4 |
89 | 99 | |
| 100 | sage: R = RootSystem("A2xB2xF4") |
| 101 | sage: CM = R.cartan_matrix(); CM |
| 102 | [ 2 -1| 0 0| 0 0 0 0] |
| 103 | [-1 2| 0 0| 0 0 0 0] |
| 104 | [-----+-----+-----------] |
| 105 | [ 0 0| 2 -1| 0 0 0 0] |
| 106 | [ 0 0|-2 2| 0 0 0 0] |
| 107 | [-----+-----+-----------] |
| 108 | [ 0 0| 0 0| 2 -1 0 0] |
| 109 | [ 0 0| 0 0|-1 2 -1 0] |
| 110 | [ 0 0| 0 0| 0 -2 2 -1] |
| 111 | [ 0 0| 0 0| 0 0 -1 2] |
| 112 | sage: DD = DynkinDiagram(CM); DD |
| 113 | O---O |
| 114 | 1 2 |
| 115 | O=>=O |
| 116 | 3 4 |
| 117 | O---O=>=O---O |
| 118 | 5 6 7 8 |
| 119 | A2xB2xF4 |
| 120 | sage: DD.cartan_matrix() |
| 121 | [ 2 -1 0 0 0 0 0 0] |
| 122 | [-1 2 0 0 0 0 0 0] |
| 123 | [ 0 0 2 -1 0 0 0 0] |
| 124 | [ 0 0 -2 2 0 0 0 0] |
| 125 | [ 0 0 0 0 2 -1 0 0] |
| 126 | [ 0 0 0 0 -1 2 -2 0] |
| 127 | [ 0 0 0 0 0 -1 2 -1] |
| 128 | [ 0 0 0 0 0 0 -1 2] |
| 129 | |
90 | 130 | .. SEEALSO:: |
91 | 131 | |
92 | 132 | :func:`CartanType` for a general discussion on Cartan |
93 | 133 | types and in particular node labeling conventions. |
94 | 134 | """ |
95 | 135 | if len(args) == 0: |
96 | | return DynkinDiagram_class() |
| 136 | return DynkinDiagram_class() |
| 137 | mat = args[0] |
| 138 | if is_Matrix(mat): |
| 139 | mat = CartanMatrix(*args) |
| 140 | if isinstance(mat, CartanMatrix): |
| 141 | if mat.cartan_type() is not None: |
| 142 | try: |
| 143 | return mat.cartan_type().dynkin_diagram() |
| 144 | except AttributeError: |
| 145 | raise ValueError("Dynkin diagram data not yet hardcoded for type %s"%ct) |
| 146 | D = DynkinDiagram_class() |
| 147 | index_set = mat.index_set() |
| 148 | for i in range(n): |
| 149 | for j in range(n): |
| 150 | if i != j: |
| 151 | D.add_edge(index_set[i], index_set[j], -mat._M[i,j]) |
| 152 | return D |
97 | 153 | ct = CartanType(*args) |
98 | | if hasattr(ct, "dynkin_diagram"): |
| 154 | try: |
99 | 155 | return ct.dynkin_diagram() |
100 | | else: |
101 | | raise ValueError, "Dynkin diagram data not yet hardcoded for type %s"%ct |
| 156 | except AttributeError: |
| 157 | raise ValueError("Dynkin diagram data not yet hardcoded for type %s"%ct) |
102 | 158 | |
103 | 159 | def dynkin_diagram(t): |
104 | 160 | """ |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
130 | 186 | - ``t`` -- a Cartan type or ``None`` |
131 | 187 | |
132 | 188 | EXAMPLES:: |
133 | | |
| 189 | |
134 | 190 | sage: d = DynkinDiagram(["A", 3]) |
135 | 191 | sage: d == loads(dumps(d)) |
136 | 192 | True |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
146 | 202 | def __copy__(self): |
147 | 203 | """ |
148 | 204 | EXAMPLES:: |
149 | | |
| 205 | |
150 | 206 | sage: d = DynkinDiagram(["A", 3]) |
151 | 207 | sage: type(copy(d)) |
152 | 208 | <class 'sage.combinat.root_system.dynkin_diagram.DynkinDiagram_class'> |
153 | 209 | """ |
154 | | import copy |
| 210 | import copy |
155 | 211 | # we have to go back to the generic copy method because the DiGraph one returns a DiGraph, not a DynkinDiagram |
156 | 212 | return copy._reconstruct(self,self.__reduce_ex__(2),0) |
157 | 213 | |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
199 | 255 | ret += "\n\\end{tikzpicture}" |
200 | 256 | return ret |
201 | 257 | |
| 258 | def _matrix_(self): |
| 259 | """ |
| 260 | Return a regular matrix from ``self``. |
| 261 | |
| 262 | EXAMPLES:: |
| 263 | |
| 264 | sage: M = DynkinDiagram(['C',3])._matrix_(); M |
| 265 | [ 2 -1 0] |
| 266 | [-1 2 -2] |
| 267 | [ 0 -1 2] |
| 268 | sage: type(M) |
| 269 | <type 'sage.matrix.matrix_integer_sparse.Matrix_integer_sparse'> |
| 270 | """ |
| 271 | return self.cartan_matrix()._matrix_() |
| 272 | |
202 | 273 | def add_edge(self, i, j, label=1): |
203 | 274 | """ |
204 | 275 | EXAMPLES:: |
205 | | |
| 276 | |
206 | 277 | sage: from sage.combinat.root_system.dynkin_diagram import DynkinDiagram_class |
207 | 278 | sage: d = DynkinDiagram_class(CartanType(['A',3])) |
208 | 279 | sage: list(sorted(d.edges())) |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
246 | 317 | [ 2 -1 -1] |
247 | 318 | [-2 2 -1] |
248 | 319 | [-1 -1 2] |
249 | | |
| 320 | |
250 | 321 | """ |
251 | 322 | # hyperbolic Dynkin diagram of Exercise 4.9 p. 57 of Kac Infinite Dimensional Lie Algebras. |
252 | 323 | g = DynkinDiagram() |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
262 | 333 | def index_set(self): |
263 | 334 | """ |
264 | 335 | EXAMPLES:: |
265 | | |
| 336 | |
266 | 337 | sage: DynkinDiagram(['C',3]).index_set() |
267 | 338 | [1, 2, 3] |
268 | 339 | sage: DynkinDiagram("A2","B2","F4").index_set() |
269 | 340 | [1, 2, 3, 4, 5, 6, 7, 8] |
270 | 341 | """ |
271 | 342 | return self.vertices() |
272 | | |
| 343 | |
273 | 344 | def cartan_type(self): |
274 | 345 | """ |
275 | 346 | EXAMPLES:: |
276 | | |
| 347 | |
277 | 348 | sage: DynkinDiagram("A2","B2","F4").cartan_type() |
278 | 349 | A2xB2xF4 |
279 | 350 | """ |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
282 | 353 | def rank(self): |
283 | 354 | r""" |
284 | 355 | Returns the index set for this Dynkin diagram |
285 | | |
| 356 | |
286 | 357 | EXAMPLES:: |
287 | | |
| 358 | |
288 | 359 | sage: DynkinDiagram(['C',3]).rank() |
289 | 360 | 3 |
290 | 361 | sage: DynkinDiagram("A2","B2","F4").rank() |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
295 | 366 | def dynkin_diagram(self): |
296 | 367 | """ |
297 | 368 | EXAMPLES:: |
298 | | |
| 369 | |
299 | 370 | sage: DynkinDiagram(['C',3]).dynkin_diagram() |
300 | 371 | O---O=<=O |
301 | 372 | 1 2 3 |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
334 | 405 | [(1, 2, 1), (2, 1, 1), (2, 3, 2), (3, 2, 1)] |
335 | 406 | sage: D.dual() == DynkinDiagram(['B',3]) |
336 | 407 | True |
337 | | |
| 408 | |
338 | 409 | TESTS:: |
339 | | |
| 410 | |
340 | 411 | sage: D = DynkinDiagram(['A',0]); D |
341 | 412 | A0 |
342 | 413 | sage: D.edges() |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
375 | 446 | """ |
376 | 447 | return True |
377 | 448 | |
378 | | |
379 | 449 | def __getitem__(self, i): |
380 | 450 | r""" |
381 | 451 | With a tuple (i,j) as argument, returns the scalar product |
382 | 452 | `\langle |
383 | 453 | \alpha^\vee_i, \alpha_j\rangle`. |
384 | | |
| 454 | |
385 | 455 | Otherwise, behaves as the usual DiGraph.__getitem__ |
386 | | |
| 456 | |
387 | 457 | EXAMPLES: We use the `C_4` dynkin diagram as a cartan |
388 | 458 | matrix:: |
389 | | |
| 459 | |
390 | 460 | sage: g = DynkinDiagram(['C',4]) |
391 | 461 | sage: matrix([[g[i,j] for j in range(1,5)] for i in range(1,5)]) |
392 | 462 | [ 2 -1 0 0] |
393 | 463 | [-1 2 -1 0] |
394 | 464 | [ 0 -1 2 -2] |
395 | 465 | [ 0 0 -1 2] |
396 | | |
| 466 | |
397 | 467 | The neighbors of a node can still be obtained in the usual way:: |
398 | | |
| 468 | |
399 | 469 | sage: [g[i] for i in range(1,5)] |
400 | 470 | [[2], [1, 3], [2, 4], [3]] |
401 | 471 | """ |
… |
… |
class DynkinDiagram_class(DiGraph, Carta |
414 | 484 | Returns the `j^{th}` column `(a_{i,j})_i` of the |
415 | 485 | Cartan matrix corresponding to this Dynkin diagram, as a container |
416 | 486 | (or iterator) of tuples `(i, a_{i,j})` |
417 | | |
| 487 | |
418 | 488 | EXAMPLES:: |
419 | | |
| 489 | |
420 | 490 | sage: g = DynkinDiagram(["B",4]) |
421 | 491 | sage: [ (i,a) for (i,a) in g.column(3) ] |
422 | 492 | [(3, 2), (2, -1), (4, -2)] |
… |
… |
def precheck(t, letter=None, length=None |
471 | 541 | if length is not None: |
472 | 542 | if len(t) != length: |
473 | 543 | raise ValueError, "len(t) must be = %s"%length |
474 | | |
| 544 | |
475 | 545 | if affine is not None: |
476 | 546 | try: |
477 | 547 | if t[2] != affine: |