Path: blob/master/sage/categories/classical_crystals.py
4057 views
r"""1Classical Crystals2"""3#*****************************************************************************4# Copyright (C) 2010 Anne Schilling <anne at math.ucdavis.edu>5#6# Distributed under the terms of the GNU General Public License (GPL)7# http://www.gnu.org/licenses/8#******************************************************************************910from sage.misc.cachefunc import cached_method11from sage.categories.category import Category12from sage.categories.category_singleton import Category_singleton13from sage.categories.finite_crystals import FiniteCrystals14from sage.categories.highest_weight_crystals import HighestWeightCrystals1516class ClassicalCrystals(Category_singleton):17"""18The category of classical crystals, that is crystals of finite Cartan type.1920EXAMPLES::2122sage: C = ClassicalCrystals()23sage: C24Category of classical crystals25sage: C.super_categories()26[Category of finite crystals, Category of highest weight crystals]27sage: C.example()28Highest weight crystal of type A_3 of highest weight omega_12930TESTS::3132sage: TestSuite(C).run()33sage: B = FiniteCrystals().example()34sage: TestSuite(B).run(verbose = True)35running ._test_an_element() . . . pass36running ._test_category() . . . pass37running ._test_elements() . . .38Running the test suite of self.an_element()39running ._test_category() . . . pass40running ._test_eq() . . . pass41running ._test_not_implemented_methods() . . . pass42running ._test_pickling() . . . pass43running ._test_stembridge_local_axioms() . . . pass44pass45running ._test_elements_eq() . . . pass46running ._test_enumerated_set_contains() . . . pass47running ._test_enumerated_set_iter_cardinality() . . . pass48running ._test_enumerated_set_iter_list() . . . pass49running ._test_eq() . . . pass50running ._test_fast_iter() . . . pass51running ._test_not_implemented_methods() . . . pass52running ._test_pickling() . . . pass53running ._test_some_elements() . . . pass54running ._test_stembridge_local_axioms() . . . pass55"""5657def super_categories(self):58r"""59EXAMPLES::6061sage: ClassicalCrystals().super_categories()62[Category of finite crystals, Category of highest weight crystals]63"""64return [FiniteCrystals(), HighestWeightCrystals()]6566def example(self, n = 3):67"""68Returns an example of highest weight crystals, as per69:meth:`Category.example`.7071EXAMPLES::7273sage: B = ClassicalCrystals().example(); B74Highest weight crystal of type A_3 of highest weight omega_175"""76from sage.categories.crystals import Crystals77return Crystals().example(n)787980class ParentMethods:8182@cached_method83def opposition_automorphism(self):84r"""85Returns the opposition automorphism8687The *opposition automorphism* is the automorphism88`i \mapsto i^*` of the vertices Dynkin diagram such that,89for `w_0` the longest element of the Weyl group, and any90simple root `\alpha_i`, one has `\alpha_{i^*} = -w_0(\alpha_i)`.9192The automorphism is returned as a dictionary.9394EXAMPLES::9596sage: T = CrystalOfTableaux(['A',5],shape=[1])97sage: T.opposition_automorphism()98{1: 5, 2: 4, 3: 3, 4: 2, 5: 1}99100sage: T = CrystalOfTableaux(['D',4],shape=[1])101sage: T.opposition_automorphism()102{1: 1, 2: 2, 3: 3, 4: 4}103104sage: T = CrystalOfTableaux(['D',5],shape=[1])105sage: T.opposition_automorphism()106{1: 1, 2: 2, 3: 3, 4: 5, 5: 4}107108sage: T = CrystalOfTableaux(['C',4],shape=[1])109sage: T.opposition_automorphism()110{1: 1, 2: 2, 3: 3, 4: 4}111"""112L = self.cartan_type().root_system().root_lattice()113W = L.weyl_group()114w0 = W.long_element()115alpha = L.simple_roots()116return dict( (i, (w0.action(alpha[i])).leading_support()) for i in self.index_set() )117118def demazure_character(self, weight, reduced_word = False):119r"""120Returns the Demazure character associated to the specified121weight in the ambient weight lattice.122123INPUT:124125- ``weight`` -- an element of the weight lattice126realization of the crystal, or a reduced word127- ``reduced_word`` -- a boolean (default: ``False``)128whether ``weight`` is given as a reduced word129130This is currently only supported for crystals whose131underlying weight space is the ambient space.132133EXAMPLES::134135sage: T = CrystalOfTableaux(['A',2], shape = [2,1])136sage: e = T.weight_lattice_realization().basis()137sage: weight = e[0] + 2*e[2]138sage: weight.reduced_word()139[2, 1]140sage: T.demazure_character(weight)141x1^2*x2 + x1^2*x3 + x1*x2^2 + x1*x2*x3 + x1*x3^2142143sage: T = CrystalOfTableaux(['A',3],shape=[2,1])144sage: T.demazure_character([1,2,3], reduced_word = True)145x1^2*x2 + x1^2*x3 + x1*x2^2 + x1*x2*x3 + x2^2*x3146147sage: T = CrystalOfTableaux(['B',2], shape = [2])148sage: e = T.weight_lattice_realization().basis()149sage: weight = -2*e[1]150sage: T.demazure_character(weight)151x1^2 + x1*x2 + x2^2 + x1 + x2 + x1/x2 + 1/x2 + 1/x2^2 + 1152153TODO: detect automatically if weight is a reduced word,154and remove the (untested!) ``reduced_word`` option.155156REFERENCES::157158.. [D1974] M. Demazure, Desingularisation des varietes de Schubert,159Ann. E. N. S., Vol. 6, (1974), p. 163-172160161.. [M2009] Sarah Mason, An Explicit Construction of Type A Demazure Atoms,162Journal of Algebraic Combinatorics, Vol. 29, (2009), No. 3, p.295-313163(arXiv:0707.4267)164165"""166from sage.misc.misc_c import prod167from sage.rings.rational_field import QQ168from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing169if reduced_word:170word = weight171else:172word = weight.reduced_word()173n = self.weight_lattice_realization().n174u = list( self.module_generators )175for i in reversed(word):176u = u + sum((x.demazure_operator(i, truncated = True) for x in u), [])177x = ['x%s'%i for i in range(1,n+1)]178P = PolynomialRing(QQ, x)179u = [b.weight() for b in u]180return sum((prod((x[i]**(la[i]) for i in range(n)), P.one()) for la in u), P.zero())181182def character(self, R=None):183"""184Returns the character of this crystal.185186INPUT:187188- ``R`` -- a :class:`WeylCharacterRing`189(default: the default :class:`WeylCharacterRing` for this Cartan type)190191Returns the character of ``self`` as an element of ``R``.192193EXAMPLES::194195sage: C = CrystalOfTableaux("A2", shape=[2,1])196sage: chi = C.character(); chi197A2(2,1,0)198199sage: T = TensorProductOfCrystals(C,C)200sage: chiT = T.character(); chiT201A2(2,2,2) + 2*A2(3,2,1) + A2(3,3,0) + A2(4,1,1) + A2(4,2,0)202sage: chiT == chi^2203True204205One may specify an alternate :class:`WeylCharacterRing`::206207sage: R = WeylCharacterRing("A2", style="coroots")208sage: chiT = T.character(R); chiT209A2(0,0) + 2*A2(1,1) + A2(0,3) + A2(3,0) + A2(2,2)210sage: chiT in R211True212213It should have the same cartan type and use the same214realization of the weight lattice as ``self``::215216sage: R = WeylCharacterRing("A3", style="coroots")217sage: T.character(R)218Traceback (most recent call last):219...220ValueError: Weyl character ring does not have the right Cartan type221222"""223from sage.combinat.root_system.weyl_characters import WeylCharacterRing224if R == None:225R = WeylCharacterRing(self.cartan_type())226if not R.cartan_type() == self.cartan_type():227raise ValueError, "Weyl character ring does not have the right Cartan type"228assert R.basis().keys() == self.weight_lattice_realization()229230return R.sum_of_monomials( x.weight() for x in self.highest_weight_vectors() )231232def list(self):233r"""234Returns the list of the elements of ``self``, as per235:meth:`FiniteEnumeratedSets.ParentMethods.list`236237EXAMPLES::238239sage: C = CrystalOfLetters(['D',4])240sage: C.list()241[1, 2, 3, 4, -4, -3, -2, -1]242243FIXME: this is just there to reinstate the default244implementation of :meth:`.list` from :meth:`.__iter__`245which is overriden in :class:`Crystals`.246"""247return self._list_from_iterator()248249def __iter__(self):250r"""251Returns an iterator over the elements of this crystal.252253This iterator uses little memory, storing only one element254of the crystal at a time. For details on the complexity, see255:class:`sage.combinat.crystals.crystals.CrystalBacktracker`.256257EXAMPLES::258259sage: C = CrystalOfLetters(['A',5])260sage: [x for x in C]261[1, 2, 3, 4, 5, 6]262263TESTS::264265sage: C = CrystalOfLetters(['D',4])266sage: D = CrystalOfSpinsPlus(['D',4])267sage: E = CrystalOfSpinsMinus(['D',4])268sage: T=TensorProductOfCrystals(D,E,generators=[[D.list()[0],E.list()[0]]])269sage: U=TensorProductOfCrystals(C,E,generators=[[C(1),E.list()[0]]])270sage: T.cardinality()27156272273sage: TestSuite(T).run(verbose = True)274running ._test_an_element() . . . pass275running ._test_category() . . . pass276running ._test_elements() . . .277Running the test suite of self.an_element()278running ._test_category() . . . pass279running ._test_eq() . . . pass280running ._test_not_implemented_methods() . . . pass281running ._test_pickling() . . . pass282running ._test_stembridge_local_axioms() . . . pass283pass284running ._test_elements_eq() . . . pass285running ._test_enumerated_set_contains() . . . pass286running ._test_enumerated_set_iter_cardinality() . . . pass287running ._test_enumerated_set_iter_list() . . . pass288running ._test_eq() . . . pass289running ._test_fast_iter() . . . pass290running ._test_not_implemented_methods() . . . pass291running ._test_pickling() . . . pass292running ._test_some_elements() . . . pass293running ._test_stembridge_local_axioms() . . . pass294295sage: TestSuite(U).run(verbose = True)296running ._test_an_element() . . . pass297running ._test_category() . . . pass298running ._test_elements() . . .299Running the test suite of self.an_element()300running ._test_category() . . . pass301running ._test_eq() . . . pass302running ._test_not_implemented_methods() . . . pass303running ._test_pickling() . . . pass304running ._test_stembridge_local_axioms() . . . pass305pass306running ._test_elements_eq() . . . pass307running ._test_enumerated_set_contains() . . . pass308running ._test_enumerated_set_iter_cardinality() . . . pass309running ._test_enumerated_set_iter_list() . . . pass310running ._test_eq() . . . pass311running ._test_fast_iter() . . . pass312running ._test_not_implemented_methods() . . . pass313running ._test_pickling() . . . pass314running ._test_some_elements() . . . pass315running ._test_stembridge_local_axioms() . . . pass316317Bump's systematic tests::318319sage: fa3 = lambda a,b,c: CrystalOfTableaux(['A',3],shape=[a+b+c,b+c,c])320sage: fb3 = lambda a,b,c: CrystalOfTableaux(['B',3],shape=[a+b+c,b+c,c])321sage: fc3 = lambda a,b,c: CrystalOfTableaux(['C',3],shape=[a+b+c,b+c,c])322sage: fb4 = lambda a,b,c,d: CrystalOfTableaux(['B',4],shape=[a+b+c+d,b+c+d,c+d,d])323sage: fd4 = lambda a,b,c,d: CrystalOfTableaux(['D',4],shape=[a+b+c+d,b+c+d,c+d,d])324sage: fd5 = lambda a,b,c,d,e: CrystalOfTableaux(['D',5],shape=[a+b+c+d+e,b+c+d+e,c+d+e,d+e,e])325sage: def fd4spinplus(a,b,c,d):326... C = CrystalOfTableaux(['D',4],shape=[a+b+c+d,b+c+d,c+d,d])327... D = CrystalOfSpinsPlus(['D',4])328... return TensorProductOfCrystals(C,D,generators=[[C[0],D[0]]])329sage: def fb3spin(a,b,c):330... C = CrystalOfTableaux(['B',3],shape=[a+b+c,b+c,c])331... D = CrystalOfSpins(['B',3])332... return TensorProductOfCrystals(C,D,generators=[[C[0],D[0]]])333334TODO: choose a good panel of values for a,b,c ... both for335basic systematic tests and for conditionally run,336computationally involved tests.337338::339340sage: TestSuite(fb4(1,0,1,0)).run(verbose = True) # long time (8s on sage.math, 2011)341running ._test_an_element() . . . pass342running ._test_category() . . . pass343running ._test_elements() . . .344Running the test suite of self.an_element()345running ._test_category() . . . pass346running ._test_eq() . . . pass347running ._test_not_implemented_methods() . . . pass348running ._test_pickling() . . . pass349running ._test_stembridge_local_axioms() . . . pass350pass351running ._test_elements_eq() . . . pass352running ._test_enumerated_set_contains() . . . pass353running ._test_enumerated_set_iter_cardinality() . . . pass354running ._test_enumerated_set_iter_list() . . .Enumerated set too big; skipping test; see ``self.max_test_enumerated_set_loop``355pass356running ._test_eq() . . . pass357running ._test_fast_iter() . . . pass358running ._test_not_implemented_methods() . . . pass359running ._test_pickling() . . . pass360running ._test_some_elements() . . . pass361running ._test_stembridge_local_axioms() . . . pass362363::364365#sage: fb4(1,1,1,1).check() # expensive: the crystal is of size 297297366#True367"""368from sage.combinat.crystals.crystals import CrystalBacktracker369return iter(CrystalBacktracker(self))370371def _test_fast_iter(self, **options):372r"""373Tests whether the elements returned by :meth:`.__iter__`374and ``Crystal.list(self)`` are the same (the two375algorithms are different).376377EXAMPLES::378379sage: C = CrystalOfLetters(['A', 5])380sage: C._test_fast_iter()381"""382tester = self._tester(**options)383S = self._list_brute_force()384SS = set(S)385tester.assert_( len(S) == len(SS) )386tester.assert_( set(self) == set(SS) )387388def cardinality(self):389r"""390Returns the number of elements of the crystal, using Weyl's391dimension formula on each connected component.392393EXAMPLES::394395sage: C = ClassicalCrystals().example(5)396sage: C.cardinality()3976398"""399return sum(self.weight_lattice_realization().weyl_dimension(x.weight())400for x in self.highest_weight_vectors())401402class ElementMethods:403404def lusztig_involution(self):405r"""406Returns the Lusztig involution on the classical highest weight crystal self.407408The Lusztig involution on a finite-dimensional highest weight crystal `B(\lambda)` of highest weight `\lambda`409maps the highest weight vector to the lowest weight vector and the Kashiwara operator `f_i` to410`e_{i^*}`, where `i^*` is defined as `\alpha_{i^*} = -w_0(\alpha_i)`. Here `w_0` is the longest element411of the Weyl group acting on the `i`-th simple root `\alpha_i`.412413EXAMPLES::414415sage: B = CrystalOfTableaux(['A',3],shape=[2,1])416sage: b = B(rows=[[1,2],[4]])417sage: b.lusztig_involution()418[[1, 4], [3]]419sage: b.to_tableau().schuetzenberger_involution(n=4)420[[1, 4], [3]]421422sage: all(b.lusztig_involution().to_tableau() == b.to_tableau().schuetzenberger_involution(n=4) for b in B)423True424425sage: B = CrystalOfTableaux(['D',4],shape=[1])426sage: [[b,b.lusztig_involution()] for b in B]427[[[[1]], [[-1]]], [[[2]], [[-2]]], [[[3]], [[-3]]], [[[4]], [[-4]]], [[[-4]],428[[4]]], [[[-3]], [[3]]], [[[-2]], [[2]]], [[[-1]], [[1]]]]429430sage: B = CrystalOfTableaux(['D',3],shape=[1])431sage: [[b,b.lusztig_involution()] for b in B]432[[[[1]], [[-1]]], [[[2]], [[-2]]], [[[3]], [[3]]], [[[-3]], [[-3]]],433[[[-2]], [[2]]], [[[-1]], [[1]]]]434435sage: C=CartanType(['E',6])436sage: La=C.root_system().weight_lattice().fundamental_weights()437sage: T = HighestWeightCrystal(La[1])438sage: t = T[3]; t439[[-4, 2, 5]]440sage: t.lusztig_involution()441[[-2, -3, 4]]442"""443hw = self.to_highest_weight()[1]444hw.reverse()445hw = [self.parent().opposition_automorphism()[i] for i in hw]446return self.to_lowest_weight()[0].e_string(hw)447448449