Ticket #14402: trac_14402-tensor_product_infinite_crystals-ts.patch

File trac_14402-tensor_product_infinite_crystals-ts.patch, 56.9 KB (added by tscrim, 7 years ago)
  • sage/categories/crystals.py

    # HG changeset patch
    # User Travis Scrimshaw <tscrim@ucdavis.edur>
    # Date 1368775183 25200
    # Node ID 42389e41b4091efdca2104bfb6bb880688b8277d
    # Parent e78698946e4e570ca3f752c57de66f9d8e019997
    #14402: Change tensor product of crystals to work with infinite crystals
    
    diff --git a/sage/categories/crystals.py b/sage/categories/crystals.py
    a b class Crystals(Category_singleton): 
    11181118            from sage.categories.highest_weight_crystals import HighestWeightCrystals
    11191119            if index_set is None:
    11201120                if HighestWeightCrystals() not in self.parent().categories():
    1121                     raise ValueError, "This is not a highest weight crystals!"
     1121                    raise ValueError("This is not a highest weight crystals!")
    11221122                index_set = self.index_set()
    11231123            for i in index_set:
    1124                 if self.epsilon(i) <> 0:
    1125                     self = self.e(i)
    1126                     hw = self.to_highest_weight(index_set = index_set)
     1124                next = self.e(i)
     1125                if next is not None:
     1126                    hw = next.to_highest_weight(index_set = index_set)
    11271127                    return [hw[0], [i] + hw[1]]
    11281128            return [self, []]
    11291129
    class Crystals(Category_singleton): 
    11621162                    raise ValueError, "This is not a highest weight crystals!"
    11631163                index_set = self.index_set()
    11641164            for i in index_set:
    1165                 if self.phi(i) <> 0:
    1166                     self = self.f(i)
    1167                     lw = self.to_lowest_weight(index_set = index_set)
     1165                next = self.f(i)
     1166                if next is not None:
     1167                    lw = next.to_lowest_weight(index_set = index_set)
    11681168                    return [lw[0], [i] + lw[1]]
    11691169            return [self, []]
    11701170
  • sage/combinat/crystals/generalized_young_walls.py

    diff --git a/sage/combinat/crystals/generalized_young_walls.py b/sage/combinat/crystals/generalized_young_walls.py
    a b Generalized Young walls are certain gene 
    1313introduced in [KS10]_ and designed to be a realization of the crystals
    1414`\mathcal{B}(\infty)` and `\mathcal{B}(\lambda)` in type `A_n^{(1)}`.
    1515
    16 .. WARNING::
    17 
    18     Does not work with :func:`TensorProductOfCrystals`.
    19 
    2016REFERENCES:
    2117
    2218.. [KS10] J.-A. Kim and D.-U. Shin.
  • sage/combinat/crystals/highest_weight_crystals.py

    diff --git a/sage/combinat/crystals/highest_weight_crystals.py b/sage/combinat/crystals/highest_weight_crystals.py
    a b from sage.categories.classical_crystals  
    2121from sage.structure.parent import Parent
    2222from sage.combinat.root_system.cartan_type import CartanType
    2323from sage.combinat.crystals.letters import CrystalOfLetters
    24 from sage.combinat.crystals.tensor_product import TensorProductOfCrystals, CrystalOfWords
     24from sage.combinat.crystals.tensor_product import TensorProductOfCrystals, \
     25    TensorProductOfRegularCrystalsElement
    2526from sage.combinat.crystals.littelmann_path import CrystalOfLSPaths
    2627
    2728
    def HighestWeightCrystal(dominant_weight 
    100101    else:
    101102        raise NotImplementedError
    102103
    103 class FiniteDimensionalHighestWeightCrystal_TypeE(CrystalOfWords):
     104class FiniteDimensionalHighestWeightCrystal_TypeE(TensorProductOfCrystals):
    104105    """
    105106    Commonalities for all finite dimensional type E highest weight crystals
    106107
    class FiniteDimensionalHighestWeightCrys 
    132133        Parent.__init__(self, category = ClassicalCrystals())
    133134        self.module_generators = [self.module_generator()]
    134135
     136    Element = TensorProductOfRegularCrystalsElement
    135137
    136138    def module_generator(self):
    137139        """
  • sage/combinat/crystals/tensor_product.py

    diff --git a/sage/combinat/crystals/tensor_product.py b/sage/combinat/crystals/tensor_product.py
    a b Tensor Products of Crystals 
    33
    44Main entry points:
    55
    6 - :func:`TensorProductOfCrystals`
     6- :class:`TensorProductOfCrystals`
    77- :class:`CrystalOfTableaux`
    88
     9AUTHORS:
     10
     11- Anne Schilling, Nicolas Thiery (2007): Initial version
     12- Ben Salisbury, Travis Scrimshaw (2013): Refactored tensor products to handle
     13  non-regular crystals and created new subclass to take advantage of
     14  the regularity
    915"""
    1016#*****************************************************************************
    1117#       Copyright (C) 2007 Anne Schilling <anne at math.ucdavis.edu>
    Main entry points: 
    2531
    2632import operator
    2733from sage.misc.latex import latex
    28 from sage.misc.cachefunc import cached_method
     34from sage.misc.cachefunc import cached_method, cached_in_parent_method
    2935from sage.structure.parent import Parent
    3036from sage.structure.element import Element, parent
     37from sage.structure.global_options import GlobalOptions
    3138from sage.categories.category import Category
    3239from sage.categories.classical_crystals import ClassicalCrystals
     40from sage.categories.regular_crystals import RegularCrystals
    3341from sage.combinat.root_system.cartan_type import CartanType
    3442from sage.combinat.cartesian_product import CartesianProduct
    3543from sage.combinat.combinat import CombinatorialObject
    class ImmutableListWithParent(Combinator 
    215223        l[k] = value
    216224        return self.sibling(l)
    217225
    218 def TensorProductOfCrystals(*crystals, **options):
    219     r"""
    220     Tensor product of crystals.
    221 
    222     Given two crystals `B` and `B'` of the same type,
    223     one can form the tensor product `B \otimes B'`. As a set
    224     `B \otimes B'` is the Cartesian product
    225     `B \times B'`. The crystal operators `f_i` and
    226     `e_i` act on `b \otimes b' \in B \otimes B'` as
    227     follows:
    228 
    229     .. math::
    230 
    231       f_i(b \otimes b') = \begin{cases}
    232       f_i(b) \otimes b' & \text{if $\varepsilon_i(b) \ge \varphi_i(b')$}\\
    233       b \otimes f_i(b') & \text{otherwise}
    234       \end{cases}
    235 
    236     and
    237 
    238     .. math::
    239 
    240       e_i(b \otimes b') = \begin{cases}
    241       b \otimes e_i(b') & \text{if $\varepsilon_i(b) \le \varphi_i(b')$}\\
    242       e_i(b) \otimes b' & \text{otherwise.}
    243       \end{cases}
    244 
    245     Note that this is the opposite of Kashiwara's convention for tensor
    246     products of crystals.
    247 
    248     EXAMPLES:
    249 
    250     We construct the type `A_2`-crystal generated by `2 \otimes 1 \otimes 1`::
    251 
    252         sage: C = CrystalOfLetters(['A',2])
    253         sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)]])
    254 
    255     It has `8` elements::
    256 
    257         sage: T.list()
    258         [[2, 1, 1], [2, 1, 2], [2, 1, 3], [3, 1, 3], [3, 2, 3], [3, 1, 1], [3, 1, 2], [3, 2, 2]]
    259 
    260     One can also check the Cartan type of the crystal::
    261 
    262         sage: T.cartan_type()
    263         ['A', 2]
    264 
    265     Other examples include crystals of tableaux (which internally are represented as tensor products
    266     obtained by reading the tableaux columnwise)::
    267 
    268         sage: C = CrystalOfTableaux(['A',3], shape=[1,1,0])
    269         sage: D = CrystalOfTableaux(['A',3], shape=[1,0,0])
    270         sage: T = TensorProductOfCrystals(C,D, generators=[[C(rows=[[1], [2]]), D(rows=[[1]])], [C(rows=[[2], [3]]), D(rows=[[1]])]])
    271         sage: T.cardinality()
    272         24
    273         sage: TestSuite(T).run()
    274         sage: T.module_generators
    275         [[[[1], [2]], [[1]]], [[[2], [3]], [[1]]]]
    276         sage: [x.weight() for x in T.module_generators]
    277         [(2, 1, 0, 0), (1, 1, 1, 0)]
    278 
    279     If no module generators are specified, we obtain the full tensor
    280     product::
    281 
    282         sage: C=CrystalOfLetters(['A',2])
    283         sage: T=TensorProductOfCrystals(C,C)
    284         sage: T.list()
    285         [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
    286         sage: T.cardinality()
    287         9
    288 
    289     For a tensor product of crystals without module generators, the
    290     default implementation of module_generators contains all elements
    291     in the tensor product of the crystals. If there is a subset of
    292     elements in the tensor product that still generates the crystal,
    293     this needs to be implemented for the specific crystal separately::
    294 
    295         sage: T.module_generators.list()
    296         [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
    297 
    298     For classical highest weight crystals, it is also possible to list
    299     all highest weight elements::
    300 
    301         sage: C = CrystalOfLetters(['A',2])
    302         sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)],[C(1),C(2),C(1)]])
    303         sage: T.highest_weight_vectors()
    304         [[2, 1, 1], [1, 2, 1]]
    305     """
    306     crystals = tuple(crystals)
    307     if "cartan_type" in options:
    308         cartan_type = CartanType(options["cartan_type"])
    309     else:
    310         if len(crystals) == 0:
    311             raise ValueError, "you need to specify the Cartan type if the tensor product list is empty"
    312         else:
    313             cartan_type = crystals[0].cartan_type()
    314 
    315     if "generators" in options:
    316         generators = tuple(tuple(x) if isinstance(x, list) else x for x in options["generators"])
    317         return TensorProductOfCrystalsWithGenerators(crystals, generators=generators, cartan_type = cartan_type)
    318     else:
    319         return FullTensorProductOfCrystals(crystals, cartan_type = cartan_type)
    320 
    321 
    322226class CrystalOfWords(UniqueRepresentation, Parent):
    323227    """
    324228    Auxiliary class to provide a call method to create tensor product elements.
    class CrystalOfWords(UniqueRepresentatio 
    393297            return sum(q**(c[0].energy_function())*B.sum(B(P0(b.weight())) for b in c) for c in C)
    394298        return B.sum(q**(b.energy_function())*B(P0(b.weight())) for b in self)
    395299
     300TensorProductOfCrystalsOptions=GlobalOptions(name='tensor_product_of_crystals',
     301    doc=r"""
     302    Sets the global options for tensor products of crystals. The default is to
     303    use the anti-Kashiwara convention.
    396304
    397 class TensorProductOfCrystalsWithGenerators(CrystalOfWords):
     305    There are two conventions for how `e_i` and `f_i` act on tensor products,
     306    and the difference between the two is the order of the tensor factors
     307    are reversed. This affects both the input and output. See the example
     308    below.
     309    """,
     310    end_doc=r"""
    398311
     312    .. NOTE::
     313
     314        Changing the ``convention`` also changes how the input is handled.
     315
     316    .. WARNING::
     317
     318        Internally, the crystals are always stored using the anti-Kashiwara
     319        convention.
     320
     321    If no parameters are set, then the function returns a copy of the
     322    options dictionary.
     323
     324    EXAMPLES::
     325
     326        sage: C = CrystalOfLetters(['A',2])
     327        sage: T = TensorProductOfCrystals(C,C)
     328        sage: elt = T(C(1), C(2)); elt
     329        [1, 2]
     330        sage: TensorProductOfCrystals.global_options['convention'] = "Kashiwara"
     331        sage: elt
     332        [2, 1]
     333        sage: T(C(1), C(2)) == elt
     334        False
     335        sage: T(C(2), C(1)) == elt
     336        True
     337        sage: TensorProductOfCrystals.global_options.reset()
     338    """,
     339    convention=dict(default="antiKashiwara",
     340                    description='Sets the convention used for displaying/inputting tensor product of crystals',
     341                    values=dict(antiKashiwara='use the anti-Kashiwara convention',
     342                                Kashiwara='use the Kashiwara convention'),
     343                    alias=dict(anti="antiKashiwara", opposite="antiKashiwara"),
     344                    case_sensitive=False)
     345)
     346
     347class TensorProductOfCrystals(CrystalOfWords):
     348    r"""
     349    Tensor product of crystals.
     350
     351    Given two crystals `B` and `B'` of the same Cartan type,
     352    one can form the tensor product `B \otimes B^{\prime}`. As a set
     353    `B \otimes B^{\prime}` is the Cartesian product
     354    `B \times B^{\prime}`. The crystal operators `f_i` and
     355    `e_i` act on `b \otimes b^{\prime} \in B \otimes B^{\prime}` as
     356    follows:
     357
     358    .. MATH::
     359
     360        f_i(b \otimes b^{\prime}) = \begin{cases}
     361        f_i(b) \otimes b^{\prime} & \text{if } \varepsilon_i(b) \geq
     362        \varphi_i(b^{\prime}) \\
     363        b \otimes f_i(b^{\prime}) & \text{otherwise}
     364        \end{cases}
     365
     366    and
     367
     368    .. MATH::
     369
     370        e_i(b \otimes b^{\prime}) = \begin{cases}
     371        e_i(b) \otimes b^{\prime} & \text{if } \varepsilon_i(b) >
     372        \varphi_i(b^{\prime}) \\
     373        b \otimes e_i(b^{\prime}) & \text{otherwise.}
     374        \end{cases}
     375
     376    We also define:
     377
     378    .. MATH::
     379
     380        \begin{aligned}
     381        \varphi_i(b \otimes b^{\prime}) & = \max\left( \varphi_i(b),
     382        \varphi_i(b) + \varphi_i(b^{\prime}) - \varepsilon_i(b) \right)
     383        \\ \varepsilon_i(b \otimes b^{\prime}) & = \max\left(
     384        \varepsilon_i(b^{\prime}), \varepsilon_i(b^{\prime}) +
     385        \varepsilon_i(b) - \varphi_i(b^{\prime}) \right).
     386        \end{aligned}
     387
     388    .. NOTE::
     389
     390        This is the opposite of Kashiwara's convention for tensor
     391        products of crystals.
     392
     393    Since tensor products are associative `(\mathcal{B} \otimes \mathcal{C})
     394    \otimes \mathcal{D} \cong \mathcal{B} \otimes (\mathcal{C} \otimes
     395    \mathcal{D})` via the natural isomorphism `(b \otimes c) \otimes d \mapsto
     396    b \otimes (c \otimes d)`, we can generalizing this to arbitrary tensor
     397    products. Thus consider `B_N \otimes \cdots \otimes B_1`, where each
     398    `B_k` is an abstract crystal. The underlying set of the tensor product is
     399    `B_N \times \cdots \times B_1`, while the crystal structure is given
     400    as follows. Let `I` be the index set, and fix some `i \in I` and `b_N
     401    \otimes \cdots \otimes b_1 \in B_N \otimes \cdots \otimes B_1`. Define
     402
     403    .. MATH::
     404
     405        a_i(k) := \varepsilon_i(b_k) - \sum_{j=1}^{k-1} \langle
     406        \alpha_i^{\vee}, \mathrm{wt}(b_j) \rangle.
     407
     408    Then
     409
     410    .. MATH::
     411
     412        \begin{aligned}
     413        \mathrm{wt}(b_N \otimes \cdots \otimes b_1) &=
     414        \mathrm{wt}(b_N) + \cdots + \mathrm{wt}(b_1),
     415        \\ \varepsilon_i(b_N \otimes \cdots \otimes b_1) &= \max_{1 \leq k
     416        \leq n}\left( \sum_{j=1}^k \varepsilon_i(b_j) - \sum_{j=1}^{k-1}
     417        \varphi_i(b_j) \right)
     418        \\ & = \max_{1 \leq k \leq N}\bigl( a_i(k) \bigr),
     419        \\ \varphi_i(b_N \otimes \cdots \otimes b_1) &= \max_{1 \leq k \leq N}
     420        \left( \varphi_i(b_N) + \sum_{j=k}^{N-1} \big( \varphi_i(b_j) -
     421        \varepsilon_i(b_{j+1}) \big) \right)
     422        \\ & = \max_{1 \leq k \leq N}\bigl( \lambda_i + a_i(k) \bigr)
     423        \end{aligned}
     424
     425    where `\lambda_i = \langle \alpha_i^{\vee}, \mathrm{wt}(b_N \otimes \cdots
     426    \otimes b_1) \rangle`. Then for `k = 1, \ldots, N` the action of the
     427    Kashiwara operators is determined as follows.
     428
     429    - If `a_i(k) > a_i(j)` for `1 \leq j < k` and `a_i(k) \geq a_i(j)`
     430      for `k < j \leq N`:
     431
     432      .. MATH::
     433
     434          e_i(b_N \otimes \cdots \otimes b_1) = b_N \otimes \cdots \otimes
     435          e_i b_k \otimes \cdots \otimes b_1.
     436
     437    - If `a_i(k) \geq a_i(j)` for `1 \leq j < k` and `a_i(k) > a_i(j)`
     438      for `k < j \leq N`:
     439
     440      .. MATH::
     441
     442          f_i(b_N \otimes \cdots \otimes b_1) = b_N \otimes \cdots \otimes
     443          f_i b_k \otimes \cdots \otimes b_1.
     444
     445    Note that this is just recursively applying the definition of the tensor
     446    product on two crystals. Recall that `\langle \alpha_i^{\vee},
     447    \mathrm{wt}(b_j) \rangle = \varphi_i(b_j) - \varepsilon_i(b_j)` by the
     448    definition of a crystal.
     449
     450    .. RUBRIC:: Regular crystals
     451
     452    Now if all crystals `B_k` are regular crystals, all `\varepsilon_i` and
     453    `\varphi_i` are non-negative and we can
     454    define tensor product by the *signature rule*. We start by writing a word
     455    in `+` and `-` as follows:
     456
     457    .. MATH::
     458
     459        \underbrace{- \cdots -}_{\varphi_i(b_N) \text{ times}} \quad
     460        \underbrace{+ \cdots +}_{\varepsilon_i(b_N) \text{ times}}
     461        \quad \cdots \quad
     462        \underbrace{- \cdots -}_{\varphi_i(b_1) \text{ times}} \quad
     463        \underbrace{+ \cdots +}_{\varepsilon_i(b_1) \text{ times}},
     464
     465    and then canceling ordered pairs of `+-` until the word is in the reduced
     466    form:
     467
     468    .. MATH::
     469
     470        \underbrace{- \cdots -}_{\varphi_i \text{ times}} \quad
     471        \underbrace{+ \cdots +}_{\varepsilon_i \text{ times}}.
     472
     473    Here `e_i` acts on the factor corresponding to the leftmost `+` and `f_i`
     474    on the factor corresponding to the rightmost `-`. If there is no `+` or
     475    `-` respectively, then the result is `0` (``None``).
     476
     477    EXAMPLES:
     478
     479    We construct the type `A_2`-crystal generated by `2 \otimes 1 \otimes 1`::
     480
     481        sage: C = CrystalOfLetters(['A',2])
     482        sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)]])
     483
     484    It has `8` elements::
     485
     486        sage: T.list()
     487        [[2, 1, 1], [2, 1, 2], [2, 1, 3], [3, 1, 3], [3, 2, 3], [3, 1, 1], [3, 1, 2], [3, 2, 2]]
     488
     489    One can also check the Cartan type of the crystal::
     490
     491        sage: T.cartan_type()
     492        ['A', 2]
     493
     494    Other examples include crystals of tableaux (which internally are
     495    represented as tensor products obtained by reading the tableaux
     496    columnwise)::
     497
     498        sage: C = CrystalOfTableaux(['A',3], shape=[1,1,0])
     499        sage: D = CrystalOfTableaux(['A',3], shape=[1,0,0])
     500        sage: T = TensorProductOfCrystals(C,D, generators=[[C(rows=[[1], [2]]), D(rows=[[1]])], [C(rows=[[2], [3]]), D(rows=[[1]])]])
     501        sage: T.cardinality()
     502        24
     503        sage: TestSuite(T).run()
     504        sage: T.module_generators
     505        [[[[1], [2]], [[1]]], [[[2], [3]], [[1]]]]
     506        sage: [x.weight() for x in T.module_generators]
     507        [(2, 1, 0, 0), (1, 1, 1, 0)]
     508
     509    If no module generators are specified, we obtain the full tensor
     510    product::
     511
     512        sage: C = CrystalOfLetters(['A',2])
     513        sage: T = TensorProductOfCrystals(C,C)
     514        sage: T.list()
     515        [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
     516        sage: T.cardinality()
     517        9
     518
     519    For a tensor product of crystals without module generators, the
     520    default implementation of ``module_generators`` contains all elements
     521    in the tensor product of the crystals. If there is a subset of
     522    elements in the tensor product that still generates the crystal,
     523    this needs to be implemented for the specific crystal separately::
     524
     525        sage: T.module_generators.list()
     526        [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
     527
     528    For classical highest weight crystals, it is also possible to list
     529    all highest weight elements::
     530
     531        sage: C = CrystalOfLetters(['A',2])
     532        sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)],[C(1),C(2),C(1)]])
     533        sage: T.highest_weight_vectors()
     534        [[2, 1, 1], [1, 2, 1]]
     535
     536    Examples with non-regular and infinite crystals (these did not work
     537    before :trac:`14402`)::
     538
     539        sage: B = InfinityCrystalOfTableaux(['D',10])
     540        sage: T = TensorProductOfCrystals(B,B)
     541        sage: T
     542        Full tensor product of the crystals
     543        [The infinity crystal of tableaux of type ['D', 10],
     544         The infinity crystal of tableaux of type ['D', 10]]
     545
     546        sage: B = CrystalOfGeneralizedYoungWalls(15)
     547        sage: T = TensorProductOfCrystals(B,B,B)
     548        sage: T
     549        Full tensor product of the crystals
     550        [Crystal of generalized Young walls of type ['A', 15, 1],
     551         Crystal of generalized Young walls of type ['A', 15, 1],
     552         Crystal of generalized Young walls of type ['A', 15, 1]]
     553
     554        sage: La = RootSystem(['A',2,1]).weight_lattice().fundamental_weights()
     555        sage: B = HighestWeightCrystalOfGYW(2,La[0]+La[1])
     556        sage: C = HighestWeightCrystalOfGYW(2,2*La[2])
     557        sage: D = HighestWeightCrystalOfGYW(2,3*La[0]+La[2])
     558        sage: T = TensorProductOfCrystals(B,C,D)
     559        sage: T
     560        Full tensor product of the crystals
     561        [Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight Lambda[0] + Lambda[1].,
     562         Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight 2*Lambda[2].,
     563         Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight 3*Lambda[0] + Lambda[2].]
     564
     565    There is also a global option for setting the convention (by default Sage
     566    uses anti-Kashiwara)::
     567
     568        sage: C = CrystalOfLetters(['A',2])
     569        sage: T = TensorProductOfCrystals(C,C)
     570        sage: elt = T(C(1), C(2)); elt
     571        [1, 2]
     572        sage: TensorProductOfCrystals.global_options['convention'] = "Kashiwara"
     573        sage: elt
     574        [2, 1]
     575        sage: TensorProductOfCrystals.global_options.reset()
     576    """
     577    @staticmethod
     578    def __classcall_private__(cls, *crystals, **options):
     579        """
     580        Create the correct parent object.
     581
     582        EXAMPLES::
     583
     584            sage: C = CrystalOfLetters(['A',2])
     585            sage: T = TensorProductOfCrystals(C, C)
     586            sage: T2 = TensorProductOfCrystals(C, C)
     587            sage: T is T2
     588            True
     589            sage: B = InfinityCrystalOfTableaux(['A',2])
     590            sage: T = TensorProductOfCrystals(B, B)
     591        """
     592        crystals = tuple(crystals)
     593        if "cartan_type" in options:
     594            cartan_type = CartanType(options["cartan_type"])
     595        else:
     596            if len(crystals) == 0:
     597                raise ValueError("you need to specify the Cartan type if the tensor product list is empty")
     598            else:
     599                cartan_type = crystals[0].cartan_type()
     600
     601        if "generators" in options:
     602            generators = tuple(tuple(x) if isinstance(x, list) else x for x in options["generators"])
     603
     604            if all(c in RegularCrystals() for c in crystals):
     605                return TensorProductOfRegularCrystalsWithGenerators(crystals, generators, cartan_type)
     606            return TensorProductOfCrystalsWithGenerators(crystals, generators, cartan_type)
     607
     608        if all(c in RegularCrystals() for c in crystals):
     609            return FullTensorProductOfRegularCrystals(crystals, cartan_type=cartan_type)
     610        return FullTensorProductOfCrystals(crystals, cartan_type=cartan_type)
     611
     612    global_options = TensorProductOfCrystalsOptions
     613
     614    def _element_constructor_(self, *crystalElements):
     615        """
     616        EXAMPLES::
     617
     618            sage: C = CrystalOfLetters(['A',2])
     619            sage: T = TensorProductOfCrystals(C,C)
     620            sage: T(1,1)
     621            [1, 1]
     622            sage: _.parent()
     623            Full tensor product of the crystals [The crystal of letters for type ['A', 2], The crystal of letters for type ['A', 2]]
     624            sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)]])
     625            sage: T(C(2), C(1), C(1))
     626            [2, 1, 1]
     627        """
     628        if self.global_options['convention'] == "Kashiwara":
     629            crystalElements = reversed(crystalElements)
     630        return self.element_class(self, list(crystalElements))
     631
     632class TensorProductOfCrystalsWithGenerators(TensorProductOfCrystals):
     633    """
     634    Tensor product of crystals with a generating set.
     635    """
    399636    def __init__(self, crystals, generators, cartan_type):
    400637        """
    401638        EXAMPLES::
    class TensorProductOfCrystalsWithGenerat 
    408645        assert isinstance(generators, tuple)
    409646        category = Category.meet([crystal.category() for crystal in crystals])
    410647        Parent.__init__(self, category = category)
    411         self.rename("The tensor product of the crystals %s"%(crystals,))
    412648        self.crystals = crystals
    413649        self._cartan_type = cartan_type
    414650        self.module_generators = [ self(*x) for x in generators ]
    415651
     652    def _repr_(self):
     653        """
     654        Return a string representation of ``self``.
    416655
    417 class FullTensorProductOfCrystals(CrystalOfWords):
     656        EXAMPLES::
     657
     658            sage: C = CrystalOfLetters(['A',2])
     659            sage: TensorProductOfCrystals(C,C,generators=[[C(2),C(1)]])
     660            The tensor product of the crystals [The crystal of letters for type ['A', 2], The crystal of letters for type ['A', 2]]
     661        """
     662        if self.global_options['convention'] == "Kashiwara":
     663            st = repr(list(reversed(self.crystals)))
     664        else:
     665            st = repr(list(self.crystals))
     666        return "The tensor product of the crystals %s"%st
     667
     668class FullTensorProductOfCrystals(TensorProductOfCrystals):
     669    """
     670    Full tensor product of crystals.
     671    """
    418672    def __init__(self, crystals, **options):
    419673        """
    420674        TESTS::
    class FullTensorProductOfCrystals(Crysta 
    429683        crystals = list(crystals)
    430684        category = Category.meet([crystal.category() for crystal in crystals])
    431685        Parent.__init__(self, category = category)
    432         self.rename("Full tensor product of the crystals %s"%(crystals,))
    433686        self.crystals = crystals
    434687        if options.has_key('cartan_type'):
    435688            self._cartan_type = CartanType(options['cartan_type'])
    class FullTensorProductOfCrystals(Crysta 
    441694        self.cartesian_product = CartesianProduct(*self.crystals)
    442695        self.module_generators = self
    443696
     697    def _repr_(self):
     698        """
     699        Return a string representation of ``self``.
     700
     701        EXAMPLES::
     702
     703            sage: C = CrystalOfLetters(['A',2])
     704            sage: TensorProductOfCrystals(C,C)
     705            Full tensor product of the crystals [The crystal of letters for type ['A', 2], The crystal of letters for type ['A', 2]]
     706        """
     707        if self.global_options['convention'] == "Kashiwara":
     708            st = repr(reversed(self.crystals))
     709        else:
     710            st = repr(self.crystals)
     711        return "Full tensor product of the crystals %s"%st
     712
    444713    # TODO: __iter__ and cardinality should be inherited from EnumeratedSets().CartesianProducts()
    445714    def __iter__(self):
    446715        """
    class FullTensorProductOfCrystals(Crysta 
    460729
    461730    def cardinality(self):
    462731        """
     732        Return the cardinality of ``self``.
     733
    463734        EXAMPLES::
    464735
    465736            sage: C = CrystalOfLetters(['A',2])
    class FullTensorProductOfCrystals(Crysta 
    469740        """
    470741        return self.cartesian_product.cardinality()
    471742
    472 
    473 
    474743class TensorProductOfCrystalsElement(ImmutableListWithParent):
    475744    r"""
    476     A class for elements of tensor products of crystals
     745    A class for elements of tensor products of crystals.
    477746    """
     747    def _repr_(self):
     748        """
     749        Return a string representation of ``self``.
     750
     751        EXAMPLES::
     752
     753            sage: C = CrystalOfLetters(['A',3])
     754            sage: T = TensorProductOfCrystals(C,C)
     755            sage: T(C(1),C(2))
     756            [1, 2]
     757        """
     758        if self.parent().global_options['convention'] == "Kashiwara":
     759            return repr(list(reversed(self._list)))
     760        return repr(self._list)
     761
     762    def _latex_(self):
     763        r"""
     764        Return latex code for ``self``.
     765
     766        EXAMPLES::
     767
     768            sage: C = CrystalOfLetters(["A",2])
     769            sage: D = CrystalOfTableaux(["A",2], shape=[2])
     770            sage: E = TensorProductOfCrystals(C,D)
     771            sage: latex(E.module_generators[0])
     772            1 \otimes {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
     773            \raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2}
     774            \lr{1}&\lr{1}\\\cline{1-2}
     775            \end{array}$}
     776            }
     777        """
     778        return ' \otimes '.join(latex(c) for c in self)
    478779
    479780    def __lt__(self, other):
    480781        """
    481782        Non elements of the crystal are incomparable with elements of the crystal
    482         (or should it return NotImplemented?)
     783        (or should it return NotImplemented?).
    483784
    484785        Comparison of two elements of this crystal:
    485          - different length: incomparable
    486          - otherwise lexicographicaly, considering self[i] and other[i]
    487            as incomparable if self[i] < other[i] returns NotImplemented
     786
     787        - different length: incomparable
     788        - otherwise lexicographicaly, considering ``self[i]`` and ``other[i]``
     789          as incomparable if ``self[i] < other[i]`` returns NotImplemented
    488790        """
    489791        if parent(self) is not parent(other):
    490792            return False
    class TensorProductOfCrystalsElement(Imm 
    497799                return False
    498800        return False
    499801
     802    def weight(self):
     803        r"""
     804        Return the weight of ``self``.
     805
     806        EXAMPLES::
     807
     808            sage: B = InfinityCrystalOfTableaux("A3")
     809            sage: T = TensorProductOfCrystals(B,B)
     810            sage: b1 = B.highest_weight_vector().f_string([2,1,3])
     811            sage: b2 = B.highest_weight_vector().f(1)
     812            sage: t = T(b2, b1)
     813            sage: t
     814            [[[1, 1, 1, 2], [2, 2], [3]], [[1, 1, 1, 1, 2], [2, 2, 4], [3]]]
     815            sage: t.weight()
     816            -2*alpha[1] - alpha[2] - alpha[3]
     817        """
     818        return sum(self[i].weight() for i in range(len(self)))
     819
     820    def epsilon(self, i):
     821        r"""
     822        Return `\varepsilon_i` of ``self``.
     823
     824        INPUT:
     825
     826        - ``i`` -- An element of the index set
     827
     828        EXAMPLES::
     829
     830            sage: B = InfinityCrystalOfTableaux("G2")
     831            sage: T = TensorProductOfCrystals(B,B)
     832            sage: b1 = B.highest_weight_vector().f(2)
     833            sage: b2 = B.highest_weight_vector().f_string([2,2,1])
     834            sage: t = T(b2, b1)
     835            sage: [t.epsilon(i) for i in B.index_set()]
     836            [0, 3]
     837        """
     838        return max(self._sig(i, k) for k in range(1, len(self)+1))
     839
     840    def phi(self, i):
     841        r"""
     842        Return `\varphi_i` of ``self``.
     843
     844        INPUT:
     845
     846        - ``i`` -- An element of the index set
     847
     848        EXAMPLES::
     849
     850            sage: La = RootSystem(['A',2,1]).weight_lattice().fundamental_weights()
     851            sage: B = HighestWeightCrystalOfGYW(2,La[0]+La[1])
     852            sage: T = TensorProductOfCrystals(B,B)
     853            sage: b1 = B.highest_weight_vector().f_string([1,0])
     854            sage: b2 = B.highest_weight_vector().f_string([0,1])
     855            sage: t = T(b2, b1)
     856            sage: [t.phi(i) for i in B.index_set()]
     857            [1, 1, 4]
     858        """
     859        P = self[-1].parent().weight_lattice_realization()
     860        h = P.simple_coroots()
     861        omega = P(self.weight()).scalar(h[i])
     862        return max([omega + self._sig(i, k) for k in range(len(self))])
     863
     864    @cached_in_parent_method
     865    def _sig(self,i,k):
     866        r"""
     867        Return `a_i(k)` of ``self``.
     868
     869        The value `a_i(k)` of a crystal `b = b_N \otimes \cdots \otimes b_1`
     870        is defined as:
     871
     872        .. MATH::
     873
     874            a_i(k) = \varepsilon_i(b_k) - \sum_{j=1}^{k-1} \langle h_i,
     875            \mathrm{wt}(b_j) \rangle
     876
     877        where `\mathrm{wt}` is the :meth:`weight` of `b_j`.
     878
     879        INPUT:
     880
     881        - ``i`` -- An element of the index set
     882
     883        - ``k`` -- The (1-based) index of the tensor factor of ``self``
     884
     885        EXAMPLES::
     886
     887            sage: B = CrystalOfGeneralizedYoungWalls(3)
     888            sage: T = TensorProductOfCrystals(B,B)
     889            sage: b1 = B.highest_weight_vector().f_string([0,3,1])
     890            sage: b2 = B.highest_weight_vector().f_string([3,2,1,0,2,3])
     891            sage: t = T(b1, b2)
     892            sage: [[t._sig(i,k) for k in range(1,len(t)+1)] for i in B.index_set()]
     893            [[0, -1], [0, 0], [0, 1], [1, 2]]
     894        """
     895        if k == 1:
     896            return self[-1].epsilon(i)
     897        return self._sig(i, k-1) + self[-k].epsilon(i) - self[-k+1].phi(i)
     898
     899    def e(self,i):
     900        r"""
     901        Return the action of `e_i` on ``self``.
     902
     903        INPUT:
     904
     905        - ``i`` -- An element of the index set
     906
     907        EXAMPLES::
     908
     909            sage: B = InfinityCrystalOfTableaux("D4")
     910            sage: T = TensorProductOfCrystals(B,B)
     911            sage: b1 = B.highest_weight_vector().f_string([1,4,3])
     912            sage: b2 = B.highest_weight_vector().f_string([2,2,3,1,4])
     913            sage: t = T(b2, b1)
     914            sage: t.e(1)
     915            [[[1, 1, 1, 1, 1], [2, 2, 3, -3], [3]], [[1, 1, 1, 1, 2], [2, 2, 2], [3, -3]]]
     916            sage: t.e(2)
     917            sage: t.e(3)
     918            [[[1, 1, 1, 1, 1, 2], [2, 2, 3, -4], [3]], [[1, 1, 1, 1, 2], [2, 2, 2], [3, -3]]]
     919            sage: t.e(4)
     920            [[[1, 1, 1, 1, 1, 2], [2, 2, 3, 4], [3]], [[1, 1, 1, 1, 2], [2, 2, 2], [3, -3]]]
     921        """
     922        N = len(self) + 1
     923        for k in range(1, N):
     924            if all(self._sig(i,k) > self._sig(i,j) for j in range(1, k)) and \
     925                    all(self._sig(i,k) >= self._sig(i,j) for j in range(k+1, N)):
     926                crystal = self[-k].e(i)
     927                if crystal is None:
     928                    return None
     929                return self.set_index(-k, crystal)
     930        return None
     931
     932    def f(self,i):
     933        r"""
     934        Return the action of `f_i` on ``self``.
     935
     936        INPUT:
     937
     938        - ``i`` -- An element of the index set
     939
     940        EXAMPLES::
     941
     942            sage: La = RootSystem(['A',3,1]).weight_lattice().fundamental_weights()
     943            sage: B = HighestWeightCrystalOfGYW(3,La[0])
     944            sage: T = TensorProductOfCrystals(B,B,B)
     945            sage: b1 = B.highest_weight_vector().f_string([0,3])
     946            sage: b2 = B.highest_weight_vector().f_string([0])
     947            sage: b3 = B.highest_weight_vector()
     948            sage: t = T(b3, b2, b1)
     949            sage: t.f(0)
     950            [[[0]], [[0]], [[0, 3]]]
     951            sage: t.f(1)
     952            [[], [[0]], [[0, 3], [1]]]
     953            sage: t.f(2)
     954            [[], [[0]], [[0, 3, 2]]]
     955            sage: t.f(3)
     956            [[], [[0, 3]], [[0, 3]]]
     957        """
     958        N = len(self) + 1
     959        for k in range(1, N):
     960            if all(self._sig(i,k) >= self._sig(i,j) for j in range(1, k)) and \
     961                    all(self._sig(i,k) > self._sig(i,j) for j in range(k+1, N)):
     962                crystal = self[-k].f(i)
     963                if crystal is None:
     964                    return None
     965                return self.set_index(-k, crystal)
     966        return None
     967
     968class TensorProductOfRegularCrystalsElement(TensorProductOfCrystalsElement):
     969    """
     970    Element class for a tensor product of regular crystals.
     971
     972    TESTS::
     973
     974        sage: C = CrystalOfLetters(['A',2])
     975        sage: T = TensorProductOfCrystals(C, C)
     976        sage: elt = T(C(1), C(2))
     977        sage: from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement
     978        sage: isinstance(elt, TensorProductOfRegularCrystalsElement)
     979        True
     980    """
    500981    def e(self, i):
    501982        """
    502         Returns the action of `e_i` on self.
     983        Return the action of `e_i` on ``self``.
    503984
    504985        EXAMPLES::
    505986
    class TensorProductOfCrystalsElement(Imm 
    512993            sage: T(C(2),C(2)).e(1) == T(C(1),C(2))
    513994            True
    514995        """
    515         assert i in self.index_set()
     996        if i not in self.index_set():
     997            raise ValueError("i must be in the index set")
    516998        position = self.positions_of_unmatched_plus(i)
    517999        if position == []:
    5181000            return None
    class TensorProductOfCrystalsElement(Imm 
    5211003
    5221004    def weight(self):
    5231005        """
    524         Returns the weight of self.
     1006        Return the weight of ``self``.
    5251007
    5261008        EXAMPLES::
    5271009
    class TensorProductOfCrystalsElement(Imm 
    5371019
    5381020    def f(self, i):
    5391021        """
    540         Returns the action of `f_i` on self.
     1022        Return the action of `f_i` on ``self``.
    5411023
    5421024        EXAMPLES::
    5431025
    class TensorProductOfCrystalsElement(Imm 
    5501032            sage: T(C(2),C(1)).f(1) is None
    5511033            True
    5521034        """
    553         assert i in self.index_set()
     1035        if i not in self.index_set():
     1036            raise ValueError("i must be in the index set")
    5541037        position = self.positions_of_unmatched_minus(i)
    5551038        if position == []:
    5561039            return None
    class TensorProductOfCrystalsElement(Imm 
    5581041        return self.set_index(k, self[k].f(i))
    5591042
    5601043    def phi(self, i):
    561         """
     1044        r"""
     1045        Return `\varphi_i` of ``self``.
     1046
    5621047        EXAMPLES::
    5631048
    5641049            sage: C = CrystalOfLetters(['A',5])
    class TensorProductOfCrystalsElement(Imm 
    5821067        return height
    5831068
    5841069    def epsilon(self, i):
    585         """
     1070        r"""
     1071        Return `\varepsilon_i` of ``self``.
     1072
    5861073        EXAMPLES::
    5871074
    5881075            sage: C = CrystalOfLetters(['A',5])
    class TensorProductOfCrystalsElement(Imm 
    6541141        l.reverse()
    6551142        return [len(self)-1-l[j] for j in range(len(l))]
    6561143
    657     def _latex_(self):
    658         """
    659         Returns latex code for self.
    660 
    661         EXAMPLES::
    662 
    663             sage: C = CrystalOfLetters(["A",2])
    664             sage: D = CrystalOfTableaux(["A",2], shape=[2])
    665             sage: E = TensorProductOfCrystals(C,D)
    666             sage: print E.module_generators[0]._latex_()
    667             1\otimes{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
    668             \raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2}
    669             \lr{1}&\lr{1}\\\cline{1-2}
    670             \end{array}$}
    671             }
    672         """
    673         return '\otimes'.join(latex(c) for c in self)
    674 
    6751144    def energy_function(self):
    6761145        r"""
    677         Returns the energy function of `self`.
     1146        Return the energy function of ``self``.
    6781147
    6791148        INPUT:
    6801149
    class TensorProductOfCrystalsElement(Imm 
    6881157
    6891158        REFERENCES:
    6901159
    691             .. [SchillingTingley2011] A. Schilling, P. Tingley.
    692                Demazure crystals, Kirillov-Reshetikhin crystals, and the energy function.
    693                preprint arXiv:1104.2359
     1160        .. [SchillingTingley2011] A. Schilling, P. Tingley.
     1161           Demazure crystals, Kirillov-Reshetikhin crystals, and the energy
     1162           function. Electronic Journal of Combinatorics. **19(2)**. 2012.
     1163           :arXiv:`1104.2359`
    6941164
    6951165        EXAMPLES::
    6961166
    class TensorProductOfCrystalsElement(Imm 
    7271197            sage: t.energy_function()
    7281198            Traceback (most recent call last):
    7291199            ...
    730             AssertionError: All crystals in the tensor product need to be perfect of the same level
     1200            ValueError: All crystals in the tensor product need to be perfect of the same level
    7311201        """
    7321202        C = self.parent().crystals[0]
    7331203        ell = ceil(C.s()/C.cartan_type().c()[C.r()])
    734         assert all(ell == K.s()/K.cartan_type().c()[K.r()] for K in self.parent().crystals), \
    735             "All crystals in the tensor product need to be perfect of the same level"
     1204        if any(ell != K.s()/K.cartan_type().c()[K.r()] for K in self.parent().crystals):
     1205            raise ValueError("All crystals in the tensor product need to be perfect of the same level")
    7361206        t = self.parent()(*[K.module_generator() for K in self.parent().crystals])
    7371207        d = t.affine_grading()
    7381208        return d - self.affine_grading()
    class TensorProductOfCrystalsElement(Imm 
    8231293            sage: y.e_string_to_ground_state()
    8241294            ()
    8251295        """
    826         assert self.parent().crystals[0].__module__ == 'sage.combinat.crystals.kirillov_reshetikhin', \
    827             "All crystals in the tensor product need to be Kirillov-Reshetikhin crystals"
     1296        if self.parent().crystals[0].__module__ != 'sage.combinat.crystals.kirillov_reshetikhin':
     1297            raise ValueError("All crystals in the tensor product need to be Kirillov-Reshetikhin crystals")
    8281298        I = self.index_set()
    8291299        I.remove(0)
    8301300        ell = max(ceil(K.s()/K.cartan_type().c()[K.r()]) for K in self.parent().crystals)
    class TensorProductOfCrystalsElement(Imm 
    8371307
    8381308CrystalOfWords.Element = TensorProductOfCrystalsElement
    8391309
     1310class FullTensorProductOfRegularCrystals(FullTensorProductOfCrystals):
     1311    """
     1312    Full tensor product of regular crystals.
     1313    """
     1314    Element = TensorProductOfRegularCrystalsElement
     1315
     1316class TensorProductOfRegularCrystalsWithGenerators(TensorProductOfCrystalsWithGenerators):
     1317    """
     1318    Tensor product of regular crystals with a generating set.
     1319    """
     1320    Element = TensorProductOfRegularCrystalsElement
     1321
     1322#########################################################
     1323## Crystal of tableaux
    8401324
    8411325class CrystalOfTableaux(CrystalOfWords):
    8421326    r"""
    class CrystalOfTableaux(CrystalOfWords): 
    8441328
    8451329    INPUT:
    8461330
    847      - ``cartan_type`` -- a Cartan type
    848      - ``shape`` -- a partition of length at most ``cartan_type.rank()``
    849      - ``shapes`` -- a list of such partitions
     1331    - ``cartan_type`` -- a Cartan type
     1332    - ``shape`` -- a partition of length at most ``cartan_type.rank()``
     1333    - ``shapes`` -- a list of such partitions
    8501334
    8511335    This constructs a classical crystal with the given Cartan type and
    8521336    highest weight(s) corresponding to the given shape(s).
    8531337
    8541338    If the type is `D_r`, the shape is permitted to have a negative
    855     value in the `r`-th position. Thus if shape=`[s_1,\dots,s_r]` then
    856     `s_r` may be negative but in any case `s_1 \ge \cdots \ge s_{r-1}
    857     \ge |s_r|`. This crystal is related to that of shape
    858     `[s_1,\dots,|s_r|]` by the outer automorphism of `SO(2r)`.
     1339    value in the `r`-th position. Thus if the shape equals `[s_1,\ldots,s_r]`,
     1340    then `s_r` may be negative but in any case `s_1 \geq \cdots \geq s_{r-1}
     1341    \geq |s_r|`. This crystal is related to that of shape
     1342    `[s_1,\ldots,|s_r|]` by the outer automorphism of `SO(2r)`.
    8591343
    8601344    If the type is `D_r` or `B_r`, the shape is permitted to be of
    8611345    length `r` with all parts of half integer value. This corresponds
    class CrystalOfTableaux(CrystalOfWords): 
    8641348    have this property.
    8651349
    8661350    Crystals of tableaux are constructed using an embedding into
    867     tensor products following Kashiwara and Nakashima [Kashiwara,
    868     Masaki; Nakashima, Toshiki, *Crystal graphs for representations of
    869     the q-analogue of classical Lie algebras*, J. Algebra 165 (1994),
    870     no. 2, 295-345.]. Sage's tensor product rule for crystals differs
    871     from that of Kashiwara and Nakashima by reversing the order of the
    872     tensor factors. Sage produces the same crystals of tableaux as
    873     Kashiwara and Nakashima. With Sage's convention, the tensor
    874     product of crystals is the same as the monoid operation on
     1351    tensor products following Kashiwara and Nakashima [KN94]_. Sage's tensor
     1352    product rule for crystals differs from that of Kashiwara and Nakashima
     1353    by reversing the order of the tensor factors. Sage produces the same
     1354    crystals of tableaux as Kashiwara and Nakashima. With Sage's convention,
     1355    the tensor product of crystals is the same as the monoid operation on
    8751356    tableaux and hence the plactic monoid.
    8761357
    877     .. seealso:: :mod:`sage.combinat.crystals.crystals` for general help on
    878         crystals, and in particular plotting and LaTeX output.
     1358    .. SEEALSO::
     1359
     1360        :mod:`sage.combinat.crystals.crystals` for general help on
     1361        crystals, and in particular plotting and `\LaTeX` output.
    8791362
    8801363    EXAMPLES:
    8811364
    8821365    We create the crystal of tableaux for type `A_2`, with
    883     highest weight given by the partition [2,1,1]::
     1366    highest weight given by the partition `[2,1,1]`::
    8841367
    8851368        sage: T = CrystalOfTableaux(['A',3], shape = [2,1,1])
    8861369
    class CrystalOfTableaux(CrystalOfWords): 
    9121395        sage: Tab(columns=[[3,1],[4,2]])
    9131396        [[1, 2], [3, 4]]
    9141397
    915     FIXME:
     1398    .. TODO::
    9161399
    917      - do we want to specify the columns increasingly or
    918        decreasingly. That is, should this be Tab(columns = [[1,3],[2,4]])
    919      - make this fully consistent with :func:`~sage.combinat.tableau.Tableau`!
     1400        FIXME:
     1401
     1402        - Do we want to specify the columns increasingly or
     1403          decreasingly? That is, should this be
     1404          ``Tab(columns = [[1,3],[2,4]])``?
     1405        - Make this fully consistent with
     1406          :func:`~sage.combinat.tableau.Tableau`!
    9201407
    9211408    We illustrate the use of a shape with a negative last entry in
    9221409    type `D`::
    class CrystalOfTableaux(CrystalOfWords): 
    10311518        # integer partitions of length the rank for type B and D. In
    10321519        # particular, for type D, the spins all have to be plus or all
    10331520        # minus spins
    1034         assert all(len(sh) == n for sh in shapes), \
    1035             "the length of all half-integer partition shapes should be the rank"
    1036         assert all(2*i % 2 == 1 for shape in spin_shapes for i in shape), \
    1037             "shapes should be either all partitions or all half-integer partitions"
     1521        if any(len(sh) != n for sh in shapes):
     1522            raise ValueError("the length of all half-integer partition shapes should be the rank")
     1523        if any(2*i % 2 != 1 for shape in spin_shapes for i in shape):
     1524            raise ValueError("shapes should be either all partitions or all half-integer partitions")
    10381525        if cartan_type.type() == 'D':
    10391526            if all( i >= 0 for shape in spin_shapes for i in shape):
    10401527                S = CrystalOfSpinsPlus(cartan_type)
    10411528            elif all(shape[-1]<0 for shape in spin_shapes):
    10421529                S = CrystalOfSpinsMinus(cartan_type)
    10431530            else:
    1044                 raise ValueError, "In type D spins should all be positive or negative"
     1531                raise ValueError("In type D spins should all be positive or negative")
    10451532        else:
    1046             assert all( i >= 0 for shape in spin_shapes for i in shape), \
    1047                 "shapes should all be partitions"
     1533            if any( i < 0 for shape in spin_shapes for i in shape):
     1534                raise ValueError("shapes should all be partitions")
    10481535            S = CrystalOfSpins(cartan_type)
    10491536        B = CrystalOfTableaux(cartan_type, shapes = shapes)
    10501537        T = TensorProductOfCrystals(S,B, generators=[[S.module_generators[0],x] for x in B.module_generators])
    class CrystalOfTableaux(CrystalOfWords): 
    10581545        Construct the crystal of all tableaux of the given shapes
    10591546
    10601547        INPUT:
    1061          - ``cartan_type`` - (data coercible into) a cartan type
    1062          - ``shapes``      - a list (or iterable) of shapes
    1063          - ``shape` `      - a shape
     1548
     1549        - ``cartan_type`` - (data coercible into) a cartan type
     1550        - ``shapes``      - a list (or iterable) of shapes
     1551        - ``shape` `      - a shape
    10641552
    10651553        shapes themselves are lists (or iterable) of integers
    10661554
    class CrystalOfTableaux(CrystalOfWords): 
    11411629
    11421630
    11431631
    1144 class CrystalOfTableauxElement(TensorProductOfCrystalsElement):
     1632class CrystalOfTableauxElement(TensorProductOfRegularCrystalsElement):
     1633    """
     1634    Element in a crystal of tableaux.
     1635    """
    11451636    def __init__(self, parent, *args, **options):
    11461637        """
    11471638        There are several ways to input tableaux, by rows,
    class CrystalOfTableauxElement(TensorPro 
    12171708                list+=col
    12181709        else:
    12191710            list = [i for i in args]
    1220         TensorProductOfCrystalsElement.__init__(self, parent, map(parent.letters, list))
     1711        TensorProductOfRegularCrystalsElement.__init__(self, parent, map(parent.letters, list))
    12211712
    12221713    def _repr_(self):
    12231714        """
  • sage/combinat/rigged_configurations/kr_tableaux.py

    diff --git a/sage/combinat/rigged_configurations/kr_tableaux.py b/sage/combinat/rigged_configurations/kr_tableaux.py
    a b from sage.rings.integer import Integer 
    4949from sage.combinat.crystals.letters import CrystalOfLetters
    5050from sage.combinat.root_system.cartan_type import CartanType
    5151from sage.combinat.crystals.tensor_product import CrystalOfWords
    52 from sage.combinat.crystals.tensor_product import TensorProductOfCrystalsElement
     52from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement
    5353from sage.combinat.crystals.kirillov_reshetikhin import horizontal_dominoes_removed, \
    5454  KirillovReshetikhinCrystal, KirillovReshetikhinGenericCrystalElement
    5555from sage.combinat.partition import Partition
    class KRTableauxSpin(KRTableauxRectangle 
    477477#        shapes = [Partition(map(lambda x: Integer(x*2), shape)).conjugate() for shape in shapes]
    478478#        self.module_generators = tuple(self._fill(Partition(shape).conjugate()) for shape in shapes)
    479479
    480 class KirillovReshetikhinTableauxElement(TensorProductOfCrystalsElement):
     480class KirillovReshetikhinTableauxElement(TensorProductOfRegularCrystalsElement):
    481481    r"""
    482482    A Kirillov-Reshetikhin tableau.
    483483
    class KirillovReshetikhinTableauxElement 
    499499        # Make sure we are a list of letters
    500500        if list != [] and type(list[0]) is not CrystalOfLetters:
    501501            list = [parent.letters(x) for x in list]
    502         TensorProductOfCrystalsElement.__init__(self, parent, list)
     502        TensorProductOfRegularCrystalsElement.__init__(self, parent, list)
    503503
    504504    def _repr_(self):
    505505        """
    class KirillovReshetikhinTableauxElement 
    690690            if ret is None:
    691691                return None
    692692            return ret.to_Kirillov_Reshetikhin_tableau()
    693         return TensorProductOfCrystalsElement.e(self, i)
     693        return TensorProductOfRegularCrystalsElement.e(self, i)
    694694
    695695    def f(self, i):
    696696        """
    class KirillovReshetikhinTableauxElement 
    711711            if ret is None:
    712712                return None
    713713            return ret.to_Kirillov_Reshetikhin_tableau()
    714         return TensorProductOfCrystalsElement.f(self, i)
     714        return TensorProductOfRegularCrystalsElement.f(self, i)
    715715
    716716KirillovReshetikhinTableaux.Element = KirillovReshetikhinTableauxElement
    717717
    class KRTableauxSpinElement(KirillovResh 
    733733            [[1], [3], [-4], [-2]]
    734734            sage: KRT([-1, -4, 3, 2]).e(3)
    735735        """
    736         half = TensorProductOfCrystalsElement.e(self, i)
     736        half = TensorProductOfRegularCrystalsElement.e(self, i)
    737737        if half is None:
    738738            return None
    739         return TensorProductOfCrystalsElement.e(half, i)
     739        return TensorProductOfRegularCrystalsElement.e(half, i)
    740740
    741741    def f(self, i):
    742742        r"""
    class KRTableauxSpinElement(KirillovResh 
    749749            sage: KRT([-1, -4, 3, 2]).f(3)
    750750            [[2], [4], [-3], [-1]]
    751751        """
    752         half = TensorProductOfCrystalsElement.f(self, i)
     752        half = TensorProductOfRegularCrystalsElement.f(self, i)
    753753        if half is None:
    754754            return None
    755755
    756         return TensorProductOfCrystalsElement.f(half, i)
     756        return TensorProductOfRegularCrystalsElement.f(half, i)
    757757
    758758    def epsilon(self, i):
    759759        r"""
    class KRTableauxSpinElement(KirillovResh 
    767767            sage: KRT([-1, -4, 3, 2]).epsilon(3)
    768768            0
    769769        """
    770         return TensorProductOfCrystalsElement.epsilon(self, i) / 2
     770        return TensorProductOfRegularCrystalsElement.epsilon(self, i) / 2
    771771
    772772    def phi(self, i):
    773773        r"""
    class KRTableauxSpinElement(KirillovResh 
    781781            sage: KRT([-1, -4, 3, 2]).phi(3)
    782782            1
    783783        """
    784         return TensorProductOfCrystalsElement.phi(self, i) / 2
     784        return TensorProductOfRegularCrystalsElement.phi(self, i) / 2
    785785
    786786    @cached_method
    787787    def to_array(self, rows=True):
  • sage/combinat/rigged_configurations/rigged_configurations.py

    diff --git a/sage/combinat/rigged_configurations/rigged_configurations.py b/sage/combinat/rigged_configurations/rigged_configurations.py
    a b class AbstractRiggedConfigurations(Uniqu 
    436436                raise ValueError("Incorrect bijection image.")
    437437            return lst[0].to_rigged_configuration()
    438438
    439         from sage.combinat.crystals.tensor_product import TensorProductOfCrystalsElement
    440         if isinstance(lst[0], TensorProductOfCrystalsElement):
     439        from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement
     440        if isinstance(lst[0], TensorProductOfRegularCrystalsElement):
    441441            lst = lst[0]
    442442        from sage.combinat.crystals.kirillov_reshetikhin import KirillovReshetikhinGenericCrystalElement
    443443        if isinstance(lst[0], KirillovReshetikhinGenericCrystalElement):
  • sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py

    diff --git a/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py b/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py
    a b Type `D_n^{(1)}` examples:: 
    6767from sage.misc.cachefunc import cached_method
    6868from sage.misc.lazy_attribute import lazy_attribute
    6969
    70 from sage.combinat.crystals.tensor_product import FullTensorProductOfCrystals
     70from sage.combinat.crystals.tensor_product import FullTensorProductOfRegularCrystals
    7171from sage.combinat.crystals.letters import CrystalOfLetters
    7272from sage.combinat.root_system.cartan_type import CartanType
    7373
    from sage.combinat.rigged_configurations 
    7676
    7777from sage.rings.integer import Integer
    7878
    79 class AbstractTensorProductOfKRTableaux(FullTensorProductOfCrystals):
     79class AbstractTensorProductOfKRTableaux(FullTensorProductOfRegularCrystals):
    8080    r"""
    8181    Abstract class for all of tensor product of KR tableaux of a given Cartan type.
    8282
    class AbstractTensorProductOfKRTableaux( 
    115115            tensorProd.append(KirillovReshetikhinTableaux(
    116116              self.letters.cartan_type(),
    117117              rectDims[0], rectDims[1]))
    118         FullTensorProductOfCrystals.__init__(self, tuple(tensorProd))
     118        FullTensorProductOfRegularCrystals.__init__(self, tuple(tensorProd))
    119119       
    120120    def _highest_weight_iter(self):
    121121        r"""
    class AbstractTensorProductOfKRTableaux( 
    159159        if isinstance(path[0], KirillovReshetikhinGenericCrystalElement):
    160160            return self.element_class(self, *[x.to_Kirillov_Reshetikhin_tableau() for x in path])
    161161
    162         from sage.combinat.crystals.tensor_product import TensorProductOfCrystalsElement
    163         if isinstance(path[0], TensorProductOfCrystalsElement) and \
     162        from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement
     163        if isinstance(path[0], TensorProductOfRegularCrystalsElement) and \
    164164          isinstance(path[0][0], KirillovReshetikhinGenericCrystalElement):
    165165            return self.element_class(self, *[x.to_Kirillov_Reshetikhin_tableau() for x in path[0]])
    166166
    class TensorProductOfKirillovReshetikhin 
    564564            sage: T is KRT.tensor_product_of_Kirillov_Reshetikhin_crystals()
    565565            True
    566566        """
    567         return FullTensorProductOfCrystals(tuple(x.Kirillov_Reshetikhin_crystal() for x in self.crystals),
     567        return FullTensorProductOfRegularCrystals(tuple(x.Kirillov_Reshetikhin_crystal() for x in self.crystals),
    568568                                           cartan_type=self.affine_ct)
    569569
    570570TensorProductOfKirillovReshetikhinTableaux.Element = TensorProductOfKirillovReshetikhinTableauxElement
  • sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py

    diff --git a/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py b/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py
    a b Type `D_n^{(1)}` examples:: 
    9696#*****************************************************************************
    9797
    9898from sage.combinat.root_system.cartan_type import CartanType
    99 from sage.combinat.crystals.tensor_product import TensorProductOfCrystalsElement
     99from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement
    100100from sage.combinat.rigged_configurations.bijection import KRTToRCBijection
    101101
    102 class TensorProductOfKirillovReshetikhinTableauxElement(TensorProductOfCrystalsElement):
     102class TensorProductOfKirillovReshetikhinTableauxElement(TensorProductOfRegularCrystalsElement):
    103103    """
    104104    An element in a tensor product of Kirillov-Reshetikhin tableaux.
    105105
    class TensorProductOfKirillovReshetikhin 
    134134
    135135        if "pathlist" in options:
    136136            pathlist = options["pathlist"]
    137             TensorProductOfCrystalsElement.__init__(self, parent,
     137            TensorProductOfRegularCrystalsElement.__init__(self, parent,
    138138              [parent.crystals[i](list(tab)) for i, tab in enumerate(pathlist)])
    139139        elif "list" in options:
    140             TensorProductOfCrystalsElement.__init__(self, parent, **options)
     140            TensorProductOfRegularCrystalsElement.__init__(self, parent, **options)
    141141        else:
    142             TensorProductOfCrystalsElement.__init__(self, parent, list(path))
     142            TensorProductOfRegularCrystalsElement.__init__(self, parent, list(path))
    143143
    144144    def _repr_(self):
    145145        """
    class TensorProductOfKirillovReshetikhin 
    170170            [[2], [4]]
    171171        """
    172172        if i != 0:
    173             return TensorProductOfCrystalsElement.e(self, i)
     173            return TensorProductOfRegularCrystalsElement.e(self, i)
    174174
    175175        return None
    176176
    class TensorProductOfKirillovReshetikhin 
    187187            [[-4], [4]]
    188188        """
    189189        if i != 0:
    190             return TensorProductOfCrystalsElement.f(self, i)
     190            return TensorProductOfRegularCrystalsElement.f(self, i)
    191191
    192192        return None
    193193
  • sage/doctest/sources.py

    diff --git a/sage/doctest/sources.py b/sage/doctest/sources.py
    a b class FileDocTestSource(DocTestSource): 
    674674            ....:             FDS._test_enough_doctests(verbose=False)
    675675            There are 18 tests in sage/combinat/partition.py that are not being run
    676676            There are 18 tests in sage/combinat/tableau.py that are not being run
     677            There are 8 tests in sage/combinat/crystals/tensor_product.py that are not being run
    677678            There are 15 tests in sage/combinat/root_system/cartan_type.py that are not being run
    678679            There are 8 tests in sage/combinat/root_system/type_A.py that are not being run
    679680            There are 8 tests in sage/combinat/root_system/type_G.py that are not being run