Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/combinat/crystals/crystals.py
8817 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
.. TODO::
100
101
- Vocabulary and conventions:
102
103
- For a classical crystal: connected / highest weight /
104
irreducible
105
106
- ...
107
108
- Layout instructions for plot() for rank 2 types
109
110
- RestrictionOfCrystal
111
112
113
Most of the above features (except Littelmann/alcove paths) are in
114
MuPAD-Combinat (see lib/COMBINAT/crystals.mu), which could provide
115
inspiration.
116
"""
117
118
#*****************************************************************************
119
# Copyright (C) 2007 Anne Schilling <anne at math.ucdavis.edu>
120
# Nicolas Thiery <nthiery at users.sf.net>
121
#
122
# Distributed under the terms of the GNU General Public License (GPL)
123
#
124
# This code is distributed in the hope that it will be useful,
125
# but WITHOUT ANY WARRANTY; without even the implied warranty of
126
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
127
# General Public License for more details.
128
#
129
# The full text of the GPL is available at:
130
#
131
# http://www.gnu.org/licenses/
132
#****************************************************************************
133
# Acknowledgment: most of the design and implementation of this
134
# library is heavily inspired from MuPAD-Combinat.
135
#****************************************************************************
136
137
#from sage.structure.unique_representation import UniqueRepresentation
138
#from sage.structure.parent import Parent
139
#from sage.structure.element import Element
140
#from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
141
#from sage.graphs.all import DiGraph
142
#from sage.combinat import ranker
143
#from sage.combinat.root_system.weyl_characters import WeylCharacter
144
from sage.combinat.backtrack import GenericBacktracker
145
146
class CrystalBacktracker(GenericBacktracker):
147
def __init__(self, crystal, index_set=None):
148
r"""
149
Time complexity: `O(nF)` amortized for each produced
150
element, where `n` is the size of the index set, and `F` is
151
the cost of computing `e` and `f` operators.
152
153
Memory complexity: `O(D)` where `D` is the depth of the crystal.
154
155
Principle of the algorithm:
156
157
Let `C` be a classical crystal. It's an acyclic graph where all
158
connected component has a unique element without predecessors (the
159
highest weight element for this component). Let's assume for
160
simplicity that `C` is irreducible (i.e. connected) with highest
161
weight element `u`.
162
163
One can define a natural spanning tree of `C` by taking
164
`u` as the root of the tree, and for any other element
165
`y` taking as ancestor the element `x` such that
166
there is an `i`-arrow from `x` to `y` with
167
`i` minimal. Then, a path from `u` to `y`
168
describes the lexicographically smallest sequence
169
`i_1,\dots,i_k` such that
170
`(f_{i_k} \circ f_{i_1})(u)=y`.
171
172
Morally, the iterator implemented below just does a depth first
173
search walk through this spanning tree. In practice, this can be
174
achieved recursively as follow: take an element `x`, and
175
consider in turn each successor `y = f_i(x)`, ignoring
176
those such that `y = f_j(x^{\prime})` for some `x^{\prime}` and
177
`j<i` (this can be tested by computing `e_j(y)`
178
for `j<i`).
179
180
EXAMPLES::
181
182
sage: from sage.combinat.crystals.crystals import CrystalBacktracker
183
sage: C = CrystalOfTableaux(['B',3],shape=[3,2,1])
184
sage: CB = CrystalBacktracker(C)
185
sage: len(list(CB))
186
1617
187
sage: CB = CrystalBacktracker(C, [1,2])
188
sage: len(list(CB))
189
8
190
"""
191
GenericBacktracker.__init__(self, None, None)
192
self._crystal = crystal
193
if index_set is None:
194
self._index_set = crystal.index_set()
195
else:
196
self._index_set = index_set
197
198
def _rec(self, x, state):
199
"""
200
Return an iterator for the (immediate) children of ``x`` in the search
201
tree.
202
203
EXAMPLES::
204
205
sage: from sage.combinat.crystals.crystals import CrystalBacktracker
206
sage: C = CrystalOfLetters(['A', 5])
207
sage: CB = CrystalBacktracker(C)
208
sage: list(CB._rec(C(1), 'n/a'))
209
[(2, 'n/a', True)]
210
"""
211
#We will signal the initial case by having a object and state
212
#of None and consider it separately.
213
if x is None and state is None:
214
for gen in self._crystal.highest_weight_vectors():
215
yield gen, "n/a", True
216
return
217
218
# Run through the children y of x
219
for i in self._index_set:
220
y = x.f(i)
221
if y is None:
222
continue
223
# Ignore those which can be reached by an arrow with smaller label
224
hasParent = False
225
for j in self._index_set:
226
if j == i:
227
break
228
if not y.e(j) is None:
229
hasParent = True
230
break
231
if hasParent:
232
continue
233
234
# yield y and all elements further below
235
yield y, "n/a", True
236
237
238