Path: blob/master/src/sage/combinat/crystals/crystals.py
8817 views
r"""1Crystals23Let `T` be a CartanType with index set `I`, and4`W` be a realization of the type `T` weight5lattice.67A type `T` crystal `C` is a colored oriented graph8equipped with a weight function from the nodes to some realization9of the type `T` weight lattice such that:101112- Each edge is colored with a label in `i \in I`.1314- For each `i\in I`, each node `x` has:151617- at most one `i`-successor `f_i(x)`;1819- at most one `i`-predecessor `e_i(x)`.202122Furthermore, when they exist,232425- `f_i(x)`.weight() = x.weight() - `\alpha_i`;2627- `e_i(x)`.weight() = x.weight() + `\alpha_i`.28293031This crystal actually models a representation of a Lie algebra if32it satisfies some further local conditions due to Stembridge [St2003]_.3334REFERENCES:3536.. [St2003] J. Stembridge, *A local characterization of simply-laced crystals*,37Trans. Amer. Math. Soc. 355 (2003), no. 12, 4807-4823.3839EXAMPLES:4041We construct the type `A_5` crystal on letters (or in representation42theoretic terms, the highest weight crystal of type `A_5`43corresponding to the highest weight `\Lambda_1`)::4445sage: C = CrystalOfLetters(['A',5]); C46The crystal of letters for type ['A', 5]4748It has a single highest weight element::4950sage: C.highest_weight_vectors()51[1]5253A crystal is an enumerated set (see :class:`EnumeratedSets`); and we54can count and list its elements in the usual way::5556sage: C.cardinality()57658sage: C.list()59[1, 2, 3, 4, 5, 6]6061as well as use it in for loops::6263sage: [x for x in C]64[1, 2, 3, 4, 5, 6]6566Here are some more elaborate crystals (see their respective67documentations)::6869sage: Tens = TensorProductOfCrystals(C, C)70sage: Spin = CrystalOfSpins(['B', 3])71sage: Tab = CrystalOfTableaux(['A', 3], shape = [2,1,1])72sage: Fast = FastCrystal(['B', 2], shape = [3/2, 1/2])73sage: KR = KirillovReshetikhinCrystal(['A',2,1],1,1)7475One can get (currently) crude plotting via::7677sage: Tab.plot()7879If dot2tex is installed, one can obtain nice latex pictures via::8081sage: K = KirillovReshetikhinCrystal(['A',3,1], 1,1)82sage: view(K, pdflatex=True, tightpage=True) #optional - dot2tex graphviz8384or with colored edges::8586sage: K = KirillovReshetikhinCrystal(['A',3,1], 1,1)87sage: G = K.digraph()88sage: G.set_latex_options(color_by_label = {0:"black", 1:"red", 2:"blue", 3:"green"}) #optional - dot2tex graphviz89sage: view(G, pdflatex=True, tightpage=True) #optional - dot2tex graphviz9091For rank two crystals, there is an alternative method of getting92metapost pictures. For more information see C.metapost?9394See also the categories :class:`Crystals`, :class:`ClassicalCrystals`,95:class:`FiniteCrystals`, :class:`HighestWeightCrystals`.969798.. TODO::99100- Vocabulary and conventions:101102- For a classical crystal: connected / highest weight /103irreducible104105- ...106107- Layout instructions for plot() for rank 2 types108109- RestrictionOfCrystal110111112Most of the above features (except Littelmann/alcove paths) are in113MuPAD-Combinat (see lib/COMBINAT/crystals.mu), which could provide114inspiration.115"""116117#*****************************************************************************118# Copyright (C) 2007 Anne Schilling <anne at math.ucdavis.edu>119# Nicolas Thiery <nthiery at users.sf.net>120#121# Distributed under the terms of the GNU General Public License (GPL)122#123# This code is distributed in the hope that it will be useful,124# but WITHOUT ANY WARRANTY; without even the implied warranty of125# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU126# General Public License for more details.127#128# The full text of the GPL is available at:129#130# http://www.gnu.org/licenses/131#****************************************************************************132# Acknowledgment: most of the design and implementation of this133# library is heavily inspired from MuPAD-Combinat.134#****************************************************************************135136#from sage.structure.unique_representation import UniqueRepresentation137#from sage.structure.parent import Parent138#from sage.structure.element import Element139#from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets140#from sage.graphs.all import DiGraph141#from sage.combinat import ranker142#from sage.combinat.root_system.weyl_characters import WeylCharacter143from sage.combinat.backtrack import GenericBacktracker144145class CrystalBacktracker(GenericBacktracker):146def __init__(self, crystal, index_set=None):147r"""148Time complexity: `O(nF)` amortized for each produced149element, where `n` is the size of the index set, and `F` is150the cost of computing `e` and `f` operators.151152Memory complexity: `O(D)` where `D` is the depth of the crystal.153154Principle of the algorithm:155156Let `C` be a classical crystal. It's an acyclic graph where all157connected component has a unique element without predecessors (the158highest weight element for this component). Let's assume for159simplicity that `C` is irreducible (i.e. connected) with highest160weight element `u`.161162One can define a natural spanning tree of `C` by taking163`u` as the root of the tree, and for any other element164`y` taking as ancestor the element `x` such that165there is an `i`-arrow from `x` to `y` with166`i` minimal. Then, a path from `u` to `y`167describes the lexicographically smallest sequence168`i_1,\dots,i_k` such that169`(f_{i_k} \circ f_{i_1})(u)=y`.170171Morally, the iterator implemented below just does a depth first172search walk through this spanning tree. In practice, this can be173achieved recursively as follow: take an element `x`, and174consider in turn each successor `y = f_i(x)`, ignoring175those such that `y = f_j(x^{\prime})` for some `x^{\prime}` and176`j<i` (this can be tested by computing `e_j(y)`177for `j<i`).178179EXAMPLES::180181sage: from sage.combinat.crystals.crystals import CrystalBacktracker182sage: C = CrystalOfTableaux(['B',3],shape=[3,2,1])183sage: CB = CrystalBacktracker(C)184sage: len(list(CB))1851617186sage: CB = CrystalBacktracker(C, [1,2])187sage: len(list(CB))1888189"""190GenericBacktracker.__init__(self, None, None)191self._crystal = crystal192if index_set is None:193self._index_set = crystal.index_set()194else:195self._index_set = index_set196197def _rec(self, x, state):198"""199Return an iterator for the (immediate) children of ``x`` in the search200tree.201202EXAMPLES::203204sage: from sage.combinat.crystals.crystals import CrystalBacktracker205sage: C = CrystalOfLetters(['A', 5])206sage: CB = CrystalBacktracker(C)207sage: list(CB._rec(C(1), 'n/a'))208[(2, 'n/a', True)]209"""210#We will signal the initial case by having a object and state211#of None and consider it separately.212if x is None and state is None:213for gen in self._crystal.highest_weight_vectors():214yield gen, "n/a", True215return216217# Run through the children y of x218for i in self._index_set:219y = x.f(i)220if y is None:221continue222# Ignore those which can be reached by an arrow with smaller label223hasParent = False224for j in self._index_set:225if j == i:226break227if not y.e(j) is None:228hasParent = True229break230if hasParent:231continue232233# yield y and all elements further below234yield y, "n/a", True235236237238