Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/combinat/crystals/crystals.py
4072 views
1
r"""
2
Crystals
3
4
Let `T` be a CartanType with index set `I`, and
5
`W` be a realization of the type `T` weight
6
lattice.
7
8
A type `T` crystal `C` is a colored oriented graph
9
equipped with a weight function from the nodes to some realization
10
of the type `T` weight lattice such that:
11
12
13
- Each edge is colored with a label in `i \in I`.
14
15
- For each `i\in I`, each node `x` has:
16
17
18
- at most one `i`-successor `f_i(x)`;
19
20
- at most one `i`-predecessor `e_i(x)`.
21
22
23
Furthermore, when they exist,
24
25
26
- `f_i(x)`.weight() = x.weight() - `\alpha_i`;
27
28
- `e_i(x)`.weight() = x.weight() + `\alpha_i`.
29
30
31
32
This crystal actually models a representation of a Lie algebra if
33
it satisfies some further local conditions due to Stembridge [St2003].
34
35
REFERENCES:
36
37
.. [St2003] J. Stembridge, *A local characterization of simply-laced crystals*,
38
Trans. Amer. Math. Soc. 355 (2003), no. 12, 4807-4823.
39
40
EXAMPLES:
41
42
We construct the type `A_5` crystal on letters (or in representation
43
theoretic terms, the highest weight crystal of type `A_5`
44
corresponding to the highest weight `\Lambda_1`)::
45
46
sage: C = CrystalOfLetters(['A',5]); C
47
The crystal of letters for type ['A', 5]
48
49
It has a single highest weight element::
50
51
sage: C.highest_weight_vectors()
52
[1]
53
54
A crystal is an enumerated set (see :class:`EnumeratedSets`); and we
55
can count and list its elements in the usual way::
56
57
sage: C.cardinality()
58
6
59
sage: C.list()
60
[1, 2, 3, 4, 5, 6]
61
62
as well as use it in for loops::
63
64
sage: [x for x in C]
65
[1, 2, 3, 4, 5, 6]
66
67
Here are some more elaborate crystals (see their respective
68
documentations)::
69
70
sage: Tens = TensorProductOfCrystals(C, C)
71
sage: Spin = CrystalOfSpins(['B', 3])
72
sage: Tab = CrystalOfTableaux(['A', 3], shape = [2,1,1])
73
sage: Fast = FastCrystal(['B', 2], shape = [3/2, 1/2])
74
sage: KR = KirillovReshetikhinCrystal(['A',2,1],1,1)
75
76
One can get (currently) crude plotting via::
77
78
sage: Tab.plot()
79
80
If dot2tex is installed, one can obtain nice latex pictures via::
81
82
sage: K = KirillovReshetikhinCrystal(['A',3,1], 1,1)
83
sage: view(K, pdflatex=True, tightpage=True) #optional - dot2tex graphviz
84
85
or with colored edges::
86
87
sage: K = KirillovReshetikhinCrystal(['A',3,1], 1,1)
88
sage: G = K.digraph()
89
sage: G.set_latex_options(color_by_label = {0:"black", 1:"red", 2:"blue", 3:"green"}) #optional - dot2tex graphviz
90
sage: view(G, pdflatex=True, tightpage=True) #optional - dot2tex graphviz
91
92
For rank two crystals, there is an alternative method of getting
93
metapost pictures. For more information see C.metapost?
94
95
See also the categories :class:`Crystals`, :class:`ClassicalCrystals`,
96
:class:`FiniteCrystals`, :class:`HighestWeightCrystals`.
97
98
99
Caveat: this crystal library, although relatively featureful for
100
classical crystals, is still in an early development stage, and the
101
syntax details may be subject to changes.
102
103
TODO:
104
105
- Vocabulary and conventions:
106
107
- For a classical crystal: connected / highest weight /
108
irreducible
109
110
- ...
111
112
- More introductory doc explaining the mathematical background
113
114
- Layout instructions for plot() for rank 2 types
115
116
- Littelmann paths and/or alcove paths (this would give us the
117
exceptional types)
118
119
- RestrictionOfCrystal
120
121
122
Most of the above features (except Littelmann/alcove paths) are in
123
MuPAD-Combinat (see lib/COMBINAT/crystals.mu), which could provide
124
inspiration.
125
"""
126
127
#*****************************************************************************
128
# Copyright (C) 2007 Anne Schilling <anne at math.ucdavis.edu>
129
# Nicolas Thiery <nthiery at users.sf.net>
130
#
131
# Distributed under the terms of the GNU General Public License (GPL)
132
#
133
# This code is distributed in the hope that it will be useful,
134
# but WITHOUT ANY WARRANTY; without even the implied warranty of
135
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
136
# General Public License for more details.
137
#
138
# The full text of the GPL is available at:
139
#
140
# http://www.gnu.org/licenses/
141
#****************************************************************************
142
# Acknowledgment: most of the design and implementation of this
143
# library is heavily inspired from MuPAD-Combinat.
144
#****************************************************************************
145
146
#from sage.structure.unique_representation import UniqueRepresentation
147
#from sage.structure.parent import Parent
148
#from sage.structure.element import Element
149
#from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
150
#from sage.graphs.all import DiGraph
151
#from sage.combinat import ranker
152
#from sage.combinat.root_system.weyl_characters import WeylCharacter
153
from sage.combinat.backtrack import GenericBacktracker
154
155
class CrystalBacktracker(GenericBacktracker):
156
def __init__(self, crystal):
157
"""
158
Time complexity: `O(nf)` amortized for each produced
159
element, where `n` is the size of the index set, and f is
160
the cost of computing `e` and `f` operators.
161
162
Memory complexity: O(depth of the crystal)
163
164
Principle of the algorithm:
165
166
Let C be a classical crystal. It's an acyclic graph where all
167
connected component has a unique element without predecessors (the
168
highest weight element for this component). Let's assume for
169
simplicity that C is irreducible (i.e. connected) with highest
170
weight element u.
171
172
One can define a natural spanning tree of `C` by taking
173
`u` as rot of the tree, and for any other element
174
`y` taking as ancestor the element `x` such that
175
there is an `i`-arrow from `x` to `y` with
176
`i` minimal. Then, a path from `u` to `y`
177
describes the lexicographically smallest sequence
178
`i_1,\dots,i_k` such that
179
`(f_{i_k} \circ f_{i_1})(u)=y`.
180
181
Morally, the iterator implemented below just does a depth first
182
search walk through this spanning tree. In practice, this can be
183
achieved recursively as follow: take an element `x`, and
184
consider in turn each successor `y = f_i(x)`, ignoring
185
those such that `y = f_j(x')` for some `x'` and
186
`j<i` (this can be tested by computing `e_j(y)`
187
for `j<i`).
188
189
EXAMPLES::
190
191
sage: from sage.combinat.crystals.crystals import CrystalBacktracker
192
sage: C = CrystalOfTableaux(['B',3],shape=[3,2,1])
193
sage: CB = CrystalBacktracker(C)
194
sage: len(list(CB))
195
1617
196
"""
197
GenericBacktracker.__init__(self, None, None)
198
self._crystal = crystal
199
200
def _rec(self, x, state):
201
"""
202
Returns an iterator for the (immediate) children of x in the search
203
tree.
204
205
EXAMPLES::
206
207
sage: from sage.combinat.crystals.crystals import CrystalBacktracker
208
sage: C = CrystalOfLetters(['A', 5])
209
sage: CB = CrystalBacktracker(C)
210
sage: list(CB._rec(C(1), 'n/a'))
211
[(2, 'n/a', True)]
212
"""
213
#We will signal the initial case by having a object and state
214
#of None and consider it separately.
215
if x is None and state is None:
216
for gen in self._crystal.highest_weight_vectors():
217
yield gen, "n/a", True
218
return
219
220
# Run through the children y of x
221
for i in self._crystal.index_set():
222
y = x.f(i)
223
if y is None:
224
continue
225
# Ignore those which can be reached by an arrow with smaller label
226
hasParent = False
227
for j in x.index_set():
228
if j == i:
229
break
230
if not y.e(j) is None:
231
hasParent = True
232
break
233
if hasParent:
234
continue
235
236
# yield y and all elements further below
237
yield y, "n/a", True
238
239