Ticket #3601: tensor_product-for_trac.patch

File tensor_product-for_trac.patch, 9.4 KB (added by aschilling, 13 years ago)
  • sage/combinat/crystals/crystals.py

    # HG changeset patch
    # User Anne Schilling <anne@math.ucdavis.edu>
    # Date 1215484652 25200
    # Node ID 223e6d24a3b0f28c987484936196a1f23dec5a5e
    # Parent  8b9cf9661a96accee427b930c06247b30e89d67e
    [mq]: tensor_product-as.patch
    
    diff -r 8b9cf9661a96 -r 223e6d24a3b0 sage/combinat/crystals/crystals.py
    a b class Crystal(CombinatorialClass, Parent 
    236236        INPUT: R, a WeylCharacterRing. Produces the character of the crystal.
    237237        EXAMPLES:
    238238           sage: C = CrystalOfLetters(['A',2])
    239            sage: T = TensorProductOfCrystals(C, C, generators = "all")
     239           sage: T = TensorProductOfCrystals(C, C)
    240240           sage: A2 = WeylCharacterRing(C.cartan_type); A2
    241241           The Weyl Character Ring of Type [A,2] with Integer Ring coefficients
    242242           sage: chi = T.character(A2); chi
    class Crystal(CombinatorialClass, Parent 
    248248            raise ValueError, "ring does not have the right Cartan type"
    249249        hlist = {}
    250250        mlist = {}
    251         for x in self.module_generators:
     251#        for x in self.module_generators:
     252        for x in self.highest_weight_vectors():
    252253            k = tuple(x.weight())
    253254            if k in hlist:
    254255                hlist[k] += 1
  • sage/combinat/crystals/tensor_product.py

    diff -r 8b9cf9661a96 -r 223e6d24a3b0 sage/combinat/crystals/tensor_product.py
    a b from sage.combinat.combinat import Combi 
    2525from sage.combinat.combinat import CombinatorialObject
    2626from sage.combinat.partition import Partition
    2727from sage.combinat.tableau import Tableau
    28 from crystals import CrystalElement, ClassicalCrystal
     28from crystals import CrystalElement, ClassicalCrystal, Crystal
    2929from letters import CrystalOfLetters
    3030from sage.misc.flatten import flatten
    3131from sage.rings.integer import Integer
    3232from sage.misc.mrange import xmrange_iter
     33from sage.misc.mrange import cartesian_product_iterator
     34from sage.combinat.combinat import CombinatorialClass
    3335
    3436##############################################################################
    3537# Support classes
    class ImmutableListWithParent(Combinator 
    160162        l[k] = value
    161163        return self.sibling(l)
    162164
    163 # FIXME: should be, or not, in ClassicalCrystal depending on the input
    164 class TensorProductOfCrystals(ClassicalCrystal):
     165def TensorProductOfCrystals(*crystals, **options):
    165166    r"""
    166167    Tensor product of crystals.
    167168
    class TensorProductOfCrystals(ClassicalC 
    175176
    176177        It has $8$ elements
    177178
    178         sage: [t for t in T]                                                 
    179         [[2, 1, 1],
    180         [2, 1, 2],
    181         [2, 1, 3],
    182         [3, 1, 3],
    183         [3, 2, 3],
    184         [3, 1, 1],
    185         [3, 1, 2],
    186         [3, 2, 2]]
     179        sage: T.list()
     180        [[2, 1, 1], [2, 1, 2], [2, 1, 3], [3, 1, 3], [3, 2, 3], [3, 1, 1], [3, 1, 2], [3, 2, 2]]
    187181
    188182        sage: C = CrystalOfTableaux(['A',3], shape=[1,1,0])
    189183        sage: D = CrystalOfTableaux(['A',3], shape=[1,0,0])
    190         sage: T = TensorProductOfCrystals(C,D,generators="all")
     184        sage: T = TensorProductOfCrystals(C,D, generators=[[C(rows=[[1], [2]]), D(rows=[[1]])], [C(rows=[[2], [3]]), D(rows=[[1]])]])
    191185        sage: T.count()
    192186        24
    193187        sage: T.check()
    194188        True
    195189        sage: T.module_generators
    196         [[[[1], [2]], [[1]]], [[[2], [3]], [[1]]]]
    197         sage: [x.weight() for x in T.module_generators]
    198         [(2, 1, 0, 0), (1, 1, 1, 0)]
     190        [[[[1], [2]], [[1]]], [[[2], [3]], [[1]]]]
     191        sage: [x.weight() for x in T.module_generators]
     192        [(2, 1, 0, 0), (1, 1, 1, 0)]
     193
     194        If no module generators are specified, we obtain the full tensor product:
     195
     196        sage: C=CrystalOfLetters(['A',2])
     197        sage: T=TensorProductOfCrystals(C,C)
     198        sage: T.list()
     199        [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
     200        sage: T.count()
     201        9
     202
     203        For a tensor product of crystals without module generators, the default implementation of module_generators
     204        contains all elements in the tensor product of the crystals. If there is a subset of elements
     205        in the tensor product that still generates the crystal, this needs to be implemented for the specific
     206        crystal separately:
     207       
     208        sage: T.module_generators.list()
     209        [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
     210
     211        For classical highest weight crystals, it is also possible to list all highest weight elements:
     212       
     213        sage: C = CrystalOfLetters(['A',2])
     214        sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)],[C(1),C(2),C(1)]])
     215        sage: T.highest_weight_vectors()
     216        [[2, 1, 1], [1, 2, 1]]
    199217    """
     218    if options.has_key('generators'):
     219        if all(isinstance(crystal,ClassicalCrystal) for crystal in crystals):
     220            return TensorProductOfClassicalCrystalsWithGenerators(generators=options['generators'], *crystals)
     221        else:
     222            return TensorProductOfCrystalsWithGenerators(generators=options['generators'], *crystals)
     223    else:
     224        if all(isinstance(crystal,ClassicalCrystal) for crystal in crystals):
     225            return FullTensorProductOfClassicalCrystals(*crystals)
     226        else:
     227            return FullTensorProductOfCrystals(*crystals)
     228
     229class TensorProductOfCrystalsWithGenerators(Crystal):
     230
    200231    def __init__(self, *crystals, **options):
    201232        """
    202233        EXAMPLES:
    class TensorProductOfCrystals(ClassicalC 
    216247            else:
    217248                self.cartan_type = crystals[0].cartan_type
    218249        self.index_set = self.cartan_type.index_set()
    219         if options.has_key('generators'):
    220             if options['generators'] == "all":
    221                 self.module_generators = []
    222                 for c in list(xmrange_iter([D.list() for D in crystals])):
    223                     candidate = self(*c)
    224                     if all(candidate.e(k) == None for k in self.index_set):
    225                         self.module_generators.append(candidate)
    226             else:
    227                 self.module_generators = [ self(*x) for x in options['generators']]
     250#        if options.has_key('generators'):
     251#            if options['generators'] == "all":
     252#                self.module_generators = []
     253#                for c in list(xmrange_iter([D.list() for D in crystals])):
     254#                    candidate = self(*c)
     255#                    if all(candidate.e(k) == None for k in self.index_set):
     256#                        self.module_generators.append(candidate)
     257#            else:
     258#                self.module_generators = [ self(*x) for x in options['generators']]
     259        self.module_generators = [ self(*x) for x in options['generators']]
    228260
    229261    def __call__(self, *args):
    230262        """
    class TensorProductOfCrystals(ClassicalC 
    236268        """
    237269        return TensorProductOfCrystalsElement(self,
    238270                                              [crystalElement for crystalElement in args])
     271
     272class TensorProductOfClassicalCrystalsWithGenerators(TensorProductOfCrystalsWithGenerators, ClassicalCrystal):
     273    pass
     274
     275class FullTensorProductOfCrystals(Crystal):
     276 
     277    def __init__(self, *crystals, **options):
     278        crystals = [ crystal for crystal in crystals]
     279        self._name = "Full tensor product of the crystals %s"%crystals
     280        self.crystals = crystals
     281        if options.has_key('cartan_type'):
     282            self.cartan_type = CartanType(options['cartan_type'])
     283        else:
     284            if len(crystals) == 0:
     285                raise ValueError, "you need to specify the Cartan type if the tensor product list is empty"
     286            else:
     287                self.cartan_type = crystals[0].cartan_type
     288            self.index_set = self.cartan_type.index_set()
     289        self.cartesian_product = CartesianProduct(*self.crystals)
     290        self.module_generators = self
     291
     292    def iterator(self):
     293        for x in self.cartesian_product:
     294            yield self(*x)
     295
     296    __iter__ = iterator
     297
     298    list = CombinatorialClass._CombinatorialClass__list_from_iterator
     299   
     300    def count(self):
     301        return self.cartesian_product.count()
     302
     303    def __call__(self, *args):
     304        return TensorProductOfCrystalsElement(self,
     305                                              [crystalElement for crystalElement in args])
     306
     307class FullTensorProductOfClassicalCrystals(FullTensorProductOfCrystals, ClassicalCrystal):
     308    pass
    239309
    240310class TensorProductOfCrystalsElement(ImmutableListWithParent, CrystalElement):
    241311    r"""
    class TensorProductOfCrystalsElement(Imm 
    390460        l.reverse()
    391461        return [len(self)-1-l[j] for j in range(len(l))]
    392462       
    393 class CrystalOfTableaux(TensorProductOfCrystals):
     463class CrystalOfTableaux(TensorProductOfCrystalsWithGenerators, ClassicalCrystal):
    394464    r"""
    395465    Crystals of tableaux. Input: a Cartan Type type and "shape",
    396466    a partition of length <= type[1]. Produces a classical crystal with
    class CrystalOfTableaux(TensorProductOfC 
    517587                if module_generator[i] == type[1]:
    518588                    module_generator[i] = -type[1]
    519589        module_generator=[self.letters(x) for x in module_generator]
    520         TensorProductOfCrystals.__init__(self, *[self.letters]*shape.size(), **{'generators':[module_generator],'cartan_type':type})
     590        TensorProductOfCrystalsWithGenerators.__init__(self, *[self.letters]*shape.size(),
     591                                                       **{'generators':[module_generator],'cartan_type':type})
    521592        self._name = "The crystal of tableaux of type %s and shape %s"%(type, str(shape))
    522593        self.shape = shape
    523594