Tensor products of crystals - Combinatorics

Skip to content
Back to top
View this page
Edit this page

# Tensor products of crystals

Main entry points:

- `TensorProductOfCrystals`

- `CrystalOfTableaux`

AUTHORS:

- Anne Schilling, Nicolas Thiery (2007): initial version

- Ben Salisbury, Travis Scrimshaw (2013): refactored tensor products to handle non-regular crystals and created new subclass to take advantage of the regularity

- Travis Scrimshaw (2020): added queer crystal

class sage.combinat.crystals.tensor_product.CrystalOfQueerTableaux(cartan_type, shape)

  Bases: `CrystalOfWords`, `QueerSuperCrystalsMixin`

  A queer crystal of the semistandard decomposition tableaux of a given shape.

  INPUT:

  - `cartan_type` – a Cartan type

  - `shape` – a shape

  class Element

    Bases: `TensorProductOfQueerSuperCrystalsElement`

    rows()

      Return the list of rows of `self`.

      EXAMPLES:

      Sage

          sage: B = crystals.Tableaux(['Q',3], shape=[3,2,1])
          sage: t = B.an_element()
          sage: t.rows()
          [[3, 3, 3], [2, 2], [1]]

      Python

          >>> from sage.all import *
          >>> B = crystals.Tableaux(['Q',Integer(3)], shape=[Integer(3),Integer(2),Integer(1)])
          >>> t = B.an_element()
          >>> t.rows()
          [[3, 3, 3], [2, 2], [1]]

class sage.combinat.crystals.tensor_product.CrystalOfTableaux(cartan_type, shapes)

  Bases: `CrystalOfWords`

  A class for crystals of tableaux with integer valued shapes.

  INPUT:

  - `cartan_type` – a Cartan type

  - `shape` – a partition of length at most `cartan_type.rank()`

  - `shapes` – list of such partitions

  This constructs a classical crystal with the given Cartan type and highest weight(s) corresponding to the given shape(s).

  If the type is \(D_r\), the shape is permitted to have a negative value in the \(r\)-th position. Thus if the shape equals \([s_1,\ldots,s_r]\), then \(s_r\) may be negative but in any case \(s_1 \geq \cdots \geq s_{r-1} \geq |s_r|\). This crystal is related to that of shape \([s_1,\ldots,|s_r|]\) by the outer automorphism of \(SO(2r)\).

  If the type is \(D_r\) or \(B_r\), the shape is permitted to be of length \(r\) with all parts of half integer value. This corresponds to having one spin column at the beginning of the tableau. If several shapes are provided, they currently should all or none have this property.

  Crystals of tableaux are constructed using an embedding into tensor products following Kashiwara and Nakashima [KN1994]. Sage’s tensor product rule for crystals differs from that of Kashiwara and Nakashima by reversing the order of the tensor factors. Sage produces the same crystals of tableaux as Kashiwara and Nakashima. With Sage’s convention, the tensor product of crystals is the same as the monoid operation on tableaux and hence the plactic monoid.

  See also

  `sage.combinat.crystals.crystals` for general help on crystals, and in particular plotting and \(\LaTeX\) output.

  EXAMPLES:

  We create the crystal of tableaux for type \(A_2\), with highest weight given by the partition \([2,1,1]\):

  Sage

      sage: T = crystals.Tableaux(['A',3], shape = [2,1,1])

  Python

      >>> from sage.all import *
      >>> T = crystals.Tableaux(['A',Integer(3)], shape = [Integer(2),Integer(1),Integer(1)])

  Here is the list of its elements:

  Sage

      sage: T.list()
      [[[1, 1], [2], [3]], [[1, 2], [2], [3]], [[1, 3], [2], [3]],
       [[1, 4], [2], [3]], [[1, 4], [2], [4]], [[1, 4], [3], [4]],
       [[2, 4], [3], [4]], [[1, 1], [2], [4]], [[1, 2], [2], [4]],
       [[1, 3], [2], [4]], [[1, 3], [3], [4]], [[2, 3], [3], [4]],
       [[1, 1], [3], [4]], [[1, 2], [3], [4]], [[2, 2], [3], [4]]]

  [Python]

      >>> from sage.all import *
      >>> T.list()
      [[[1, 1], [2], [3]], [[1, 2], [2], [3]], [[1, 3], [2], [3]],
       [[1, 4], [2], [3]], [[1, 4], [2], [4]], [[1, 4], [3], [4]],
       [[2, 4], [3], [4]], [[1, 1], [2], [4]], [[1, 2], [2], [4]],
       [[1, 3], [2], [4]], [[1, 3], [3], [4]], [[2, 3], [3], [4]],
       [[1, 1], [3], [4]], [[1, 2], [3], [4]], [[2, 2], [3], [4]]]

  Internally, a tableau of a given Cartan type is represented as a tensor product of letters of the same type. The order in which the tensor factors appear is by reading the columns of the tableaux left to right, top to bottom (in French notation). As an example:

  Sage

      sage: T = crystals.Tableaux(['A',2], shape = [3,2])
      sage: T.module_generators[0]
      [[1, 1, 1], [2, 2]]
      sage: list(T.module_generators[0])
      [2, 1, 2, 1, 1]

  Python

      >>> from sage.all import *
      >>> T = crystals.Tableaux(['A',Integer(2)], shape = [Integer(3),Integer(2)])
      >>> T.module_generators[Integer(0)]
      [[1, 1, 1], [2, 2]]
      >>> list(T.module_generators[Integer(0)])
      [2, 1, 2, 1, 1]

  To create a tableau, one can use:

  Sage

      sage: Tab = crystals.Tableaux(['A',3], shape = [2,2])
      sage: Tab(rows=[[1,2],[3,4]])
      [[1, 2], [3, 4]]
      sage: Tab(columns=[[3,1],[4,2]])
      [[1, 2], [3, 4]]

  [Python]

      >>> from sage.all import *
      >>> Tab = crystals.Tableaux(['A',Integer(3)], shape = [Integer(2),Integer(2)])
      >>> Tab(rows=[[Integer(1),Integer(2)],[Integer(3),Integer(4)]])
      [[1, 2], [3, 4]]
      >>> Tab(columns=[[Integer(3),Integer(1)],[Integer(4),Integer(2)]])
      [[1, 2], [3, 4]]

  Todo

  FIXME:

  - Do we want to specify the columns increasingly or decreasingly? That is, should this be `Tab(columns = [[1,3],[2,4]])`?

  - Make this fully consistent with `Tableau()`!

  We illustrate the use of a shape with a negative last entry in type \(D\):

  Sage

      sage: T = crystals.Tableaux(['D',4],shape=[1,1,1,-1])
      sage: T.cardinality()
      35
      sage: TestSuite(T).run()

  Python

      >>> from sage.all import *
      >>> T = crystals.Tableaux(['D',Integer(4)],shape=[Integer(1),Integer(1),Integer(1),-Integer(1)])
      >>> T.cardinality()
      35
      >>> TestSuite(T).run()

  We illustrate the construction of crystals of spin tableaux when the partitions have half integer values in type \(B\) and \(D\):

  Sage

      sage: T = crystals.Tableaux(['B',3],shape=[3/2,1/2,1/2]); T
      The crystal of tableaux of type ['B', 3] and shape(s) [[3/2, 1/2, 1/2]]
      sage: T.cardinality()
      48
      sage: T.module_generators
      ([+++, [[1]]],)
      sage: TestSuite(T).run()

      sage: T = crystals.Tableaux(['D',3],shape=[3/2,1/2,-1/2]); T
      The crystal of tableaux of type ['D', 3] and shape(s) [[3/2, 1/2, -1/2]]
      sage: T.cardinality()
      20
      sage: T.module_generators
      ([++-, [[1]]],)
      sage: TestSuite(T).run()

  [Python]

      >>> from sage.all import *
      >>> T = crystals.Tableaux(['B',Integer(3)],shape=[Integer(3)/Integer(2),Integer(1)/Integer(2),Integer(1)/Integer(2)]); T
      The crystal of tableaux of type ['B', 3] and shape(s) [[3/2, 1/2, 1/2]]
      >>> T.cardinality()
      48
      >>> T.module_generators
      ([+++, [[1]]],)
      >>> TestSuite(T).run()

      >>> T = crystals.Tableaux(['D',Integer(3)],shape=[Integer(3)/Integer(2),Integer(1)/Integer(2),-Integer(1)/Integer(2)]); T
      The crystal of tableaux of type ['D', 3] and shape(s) [[3/2, 1/2, -1/2]]
      >>> T.cardinality()
      20
      >>> T.module_generators
      ([++-, [[1]]],)
      >>> TestSuite(T).run()

  We can also construct the tableaux for \(\mathfrak{gl}(m|n)\) as given by [BKK2000]:

  Sage

      sage: T = crystals.Tableaux(['A', [1,2]], shape=[4,2,1,1,1])
      sage: T.cardinality()
      1392

  Python

      >>> from sage.all import *
      >>> T = crystals.Tableaux(['A', [Integer(1),Integer(2)]], shape=[Integer(4),Integer(2),Integer(1),Integer(1),Integer(1)])
      >>> T.cardinality()
      1392

  We can also construct the tableaux for \(\mathfrak{q}(n)\) as given by [GJK+2014]:

  Sage

      sage: T = crystals.Tableaux(['Q', 3], shape=[3,1])
      sage: T.cardinality()
      24

  [Python]

      >>> from sage.all import *
      >>> T = crystals.Tableaux(['Q', Integer(3)], shape=[Integer(3),Integer(1)])
      >>> T.cardinality()
      24

  class Element

    Bases: `CrystalOfTableauxElement`

  cartan_type()

    Return the Cartan type of the associated crystal.

    EXAMPLES:

    Sage

        sage: T = crystals.Tableaux(['A',3], shape = [2,2])
        sage: T.cartan_type()
        ['A', 3]

    Python

        >>> from sage.all import *
        >>> T = crystals.Tableaux(['A',Integer(3)], shape = [Integer(2),Integer(2)])
        >>> T.cartan_type()
        ['A', 3]

  module_generator(shape)

    This yields the module generator (or highest weight element) of a classical crystal of given shape. The module generator is the unique tableau with equal shape and content.

    EXAMPLES:

    Sage

        sage: T = crystals.Tableaux(['D',3], shape = [1,1])
        sage: T.module_generator([1,1])
        [[1], [2]]

        sage: T = crystals.Tableaux(['D',4],shape=[2,2,2,-2])
        sage: T.module_generator(tuple([2,2,2,-2]))
        [[1, 1], [2, 2], [3, 3], [-4, -4]]
        sage: T.cardinality()
        294
        sage: T = crystals.Tableaux(['D',4],shape=[2,2,2,2])
        sage: T.module_generator(tuple([2,2,2,2]))
        [[1, 1], [2, 2], [3, 3], [4, 4]]
        sage: T.cardinality()
        294

    Python

        >>> from sage.all import *
        >>> T = crystals.Tableaux(['D',Integer(3)], shape = [Integer(1),Integer(1)])
        >>> T.module_generator([Integer(1),Integer(1)])
        [[1], [2]]

        >>> T = crystals.Tableaux(['D',Integer(4)],shape=[Integer(2),Integer(2),Integer(2),-Integer(2)])
        >>> T.module_generator(tuple([Integer(2),Integer(2),Integer(2),-Integer(2)]))
        [[1, 1], [2, 2], [3, 3], [-4, -4]]
        >>> T.cardinality()
        294
        >>> T = crystals.Tableaux(['D',Integer(4)],shape=[Integer(2),Integer(2),Integer(2),Integer(2)])
        >>> T.module_generator(tuple([Integer(2),Integer(2),Integer(2),Integer(2)]))
        [[1, 1], [2, 2], [3, 3], [4, 4]]
        >>> T.cardinality()
        294

class sage.combinat.crystals.tensor_product.CrystalOfWords

  Bases: `UniqueRepresentation`, `Parent`

  Auxiliary class to provide a call method to create tensor product elements. This class is shared with several tensor product classes and is also used in `CrystalOfTableaux` to allow tableaux of different tensor product structures in column-reading (and hence different shapes) to be considered elements in the same crystal.

  class Element

    Bases: `TensorProductOfCrystalsElement`

class sage.combinat.crystals.tensor_product.FullTensorProductOfCrystals(crystals, **options)

  Bases: `TensorProductOfCrystals`

  Full tensor product of crystals.

  Todo

  Merge this into `TensorProductOfCrystals`.

  cardinality()

    Return the cardinality of `self`.

    EXAMPLES:

    Sage

        sage: C = crystals.Letters(['A',2])
        sage: T = crystals.TensorProduct(C,C)
        sage: T.cardinality()
        9

    Python

        >>> from sage.all import *
        >>> C = crystals.Letters(['A',Integer(2)])
        >>> T = crystals.TensorProduct(C,C)
        >>> T.cardinality()
        9

  weight_lattice_realization()

    Return the weight lattice realization used to express weights.

    The weight lattice realization is the common parent which all weight lattice realizations of the crystals of `self` coerce into.

    EXAMPLES:

    Sage

        sage: B = crystals.elementary.B(['A',4], 2)
        sage: B.weight_lattice_realization()
        Root lattice of the Root system of type ['A', 4]
        sage: T = crystals.infinity.Tableaux(['A',4])
        sage: T.weight_lattice_realization()
        Ambient space of the Root system of type ['A', 4]
        sage: TP = crystals.TensorProduct(B, T)
        sage: TP.weight_lattice_realization()
        Ambient space of the Root system of type ['A', 4]

    Python

        >>> from sage.all import *
        >>> B = crystals.elementary.B(['A',Integer(4)], Integer(2))
        >>> B.weight_lattice_realization()
        Root lattice of the Root system of type ['A', 4]
        >>> T = crystals.infinity.Tableaux(['A',Integer(4)])
        >>> T.weight_lattice_realization()
        Ambient space of the Root system of type ['A', 4]
        >>> TP = crystals.TensorProduct(B, T)
        >>> TP.weight_lattice_realization()
        Ambient space of the Root system of type ['A', 4]

class sage.combinat.crystals.tensor_product.FullTensorProductOfQueerSuperCrystals(crystals, **options)

  Bases: `FullTensorProductOfCrystals`, `QueerSuperCrystalsMixin`

  Tensor product of queer super crystals.

  class Element

    Bases: `TensorProductOfQueerSuperCrystalsElement`

class sage.combinat.crystals.tensor_product.FullTensorProductOfRegularCrystals(crystals, **options)

  Bases: `FullTensorProductOfCrystals`

  Full tensor product of regular crystals.

  class Element

    Bases: `TensorProductOfRegularCrystalsElement`

class sage.combinat.crystals.tensor_product.FullTensorProductOfSuperCrystals(crystals, **options)

  Bases: `FullTensorProductOfCrystals`

  Tensor product of super crystals.

  EXAMPLES:

  Sage

      sage: L = crystals.Letters(['A', [1,1]])
      sage: T = tensor([L,L,L])
      sage: T.cardinality()
      64

  Python

      >>> from sage.all import *
      >>> L = crystals.Letters(['A', [Integer(1),Integer(1)]])
      >>> T = tensor([L,L,L])
      >>> T.cardinality()
      64

  class Element

    Bases: `TensorProductOfSuperCrystalsElement`

class sage.combinat.crystals.tensor_product.QueerSuperCrystalsMixin

  Bases: `object`

  Mixin class with methods for a finite queer supercrystal.

  index_set()

    Return the enlarged index set.

    EXAMPLES:

    Sage

        sage: Q = crystals.Letters(['Q',3])
        sage: T = tensor([Q,Q])
        sage: T.index_set()
        (-4, -3, -2, -1, 1, 2)

    Python

        >>> from sage.all import *
        >>> Q = crystals.Letters(['Q',Integer(3)])
        >>> T = tensor([Q,Q])
        >>> T.index_set()
        (-4, -3, -2, -1, 1, 2)

class sage.combinat.crystals.tensor_product.TensorProductOfCrystals

  Bases: `CrystalOfWords`

  Tensor product of crystals.

  Given two crystals \(B\) and \(B'\) of the same Cartan type, one can form the tensor product \(B \otimes B^{\prime}\). As a set \(B \otimes B^{\prime}\) is the Cartesian product \(B \times B^{\prime}\). The crystal operators \(f_i\) and \(e_i\) act on \(b \otimes b^{\prime} \in B \otimes B^{\prime}\) as follows:

  \[\begin{split}f_i(b \otimes b^{\prime}) = \begin{cases} f_i(b) \otimes b^{\prime} & \text{if } \varepsilon_i(b) \geq \varphi_i(b^{\prime}) \\ b \otimes f_i(b^{\prime}) & \text{otherwise} \end{cases}\end{split}\]

  and

  \[\begin{split}e_i(b \otimes b') = \begin{cases} e_i(b) \otimes b' & \text{if } \varepsilon_i(b) > \varphi_i(b') \\ b \otimes e_i(b') & \text{otherwise.} \end{cases}\end{split}\]

  We also define:

  \[\begin{split}\begin{aligned} \varphi_i(b \otimes b') & = \max\left( \varphi_i(b), \varphi_i(b') + \langle \alpha_i^{\vee}, \mathrm{wt}(b) \rangle \right), \\ \varepsilon_i(b \otimes b') & = \max\left( \varepsilon_i(b'), \varepsilon_i(b) - \langle \alpha_i^{\vee}, \mathrm{wt}(b') \rangle \right). \end{aligned}\end{split}\]

  Note

  This is the opposite of Kashiwara’s convention for tensor products of crystals.

  Since tensor products are associative \((\mathcal{B} \otimes \mathcal{C}) \otimes \mathcal{D} \cong \mathcal{B} \otimes (\mathcal{C} \otimes \mathcal{D})\) via the natural isomorphism \((b \otimes c) \otimes d \mapsto b \otimes (c \otimes d)\), we can generalizing this to arbitrary tensor products. Thus consider \(B_N \otimes \cdots \otimes B_1\), where each \(B_k\) is an abstract crystal. The underlying set of the tensor product is \(B_N \times \cdots \times B_1\), while the crystal structure is given as follows. Let \(I\) be the index set, and fix some \(i \in I\) and \(b_N \otimes \cdots \otimes b_1 \in B_N \otimes \cdots \otimes B_1\). Define

  \[a_i(k) := \varepsilon_i(b_k) - \sum_{j=1}^{k-1} \langle \alpha_i^{\vee}, \mathrm{wt}(b_j) \rangle.\]

  Then

  \[\begin{split}\begin{aligned} \mathrm{wt}(b_N \otimes \cdots \otimes b_1) &= \mathrm{wt}(b_N) + \cdots + \mathrm{wt}(b_1), \\ \varepsilon_i(b_N \otimes \cdots \otimes b_1) &= \max_{1 \leq k \leq n}\left( \sum_{j=1}^k \varepsilon_i(b_j) - \sum_{j=1}^{k-1} \varphi_i(b_j) \right) \\ & = \max_{1 \leq k \leq N}\bigl( a_i(k) \bigr), \\ \varphi_i(b_N \otimes \cdots \otimes b_1) &= \max_{1 \leq k \leq N} \left( \varphi_i(b_N) + \sum_{j=k}^{N-1} \big( \varphi_i(b_j) - \varepsilon_i(b_{j+1}) \big) \right) \\ & = \max_{1 \leq k \leq N}\bigl( \lambda_i + a_i(k) \bigr) \end{aligned}\end{split}\]

  where \(\lambda_i = \langle \alpha_i^{\vee}, \mathrm{wt}(b_N \otimes \cdots \otimes b_1) \rangle\). Then for \(k = 1, \ldots, N\) the action of the Kashiwara operators is determined as follows.

  - If \(a_i(k) > a_i(j)\) for \(1 \leq j < k\) and \(a_i(k) \geq a_i(j)\) for \(k < j \leq N\):

    \[e_i(b_N \otimes \cdots \otimes b_1) = b_N \otimes \cdots \otimes e_i b_k \otimes \cdots \otimes b_1.\]

  - If \(a_i(k) \geq a_i(j)\) for \(1 \leq j < k\) and \(a_i(k) > a_i(j)\) for \(k < j \leq N\):

    \[f_i(b_N \otimes \cdots \otimes b_1) = b_N \otimes \cdots \otimes f_i b_k \otimes \cdots \otimes b_1.\]

  Note that this is just recursively applying the definition of the tensor product on two crystals. Recall that \(\langle \alpha_i^{\vee}, \mathrm{wt}(b_j) \rangle = \varphi_i(b_j) - \varepsilon_i(b_j)\) by the definition of a crystal.

  Regular crystals

  Now if all crystals \(B_k\) are regular crystals, all \(\varepsilon_i\) and \(\varphi_i\) are nonnegative and we can define tensor product by the signature rule. We start by writing a word in \(+\) and \(-\) as follows:

  \[\underbrace{- \cdots -}_{\varphi_i(b_N) \text{ times}} \quad \underbrace{+ \cdots +}_{\varepsilon_i(b_N) \text{ times}} \quad \cdots \quad \underbrace{- \cdots -}_{\varphi_i(b_1) \text{ times}} \quad \underbrace{+ \cdots +}_{\varepsilon_i(b_1) \text{ times}},\]

  and then canceling ordered pairs of \(+-\) until the word is in the reduced form:

  \[\underbrace{- \cdots -}_{\varphi_i \text{ times}} \quad \underbrace{+ \cdots +}_{\varepsilon_i \text{ times}}.\]

  Here \(e_i\) acts on the factor corresponding to the leftmost \(+\) and \(f_i\) on the factor corresponding to the rightmost \(-\). If there is no \(+\) or \(-\) respectively, then the result is \(0\) (`None`).

  EXAMPLES:

  We construct the type \(A_2\)-crystal generated by \(2 \otimes 1 \otimes 1\):

  Sage

      sage: C = crystals.Letters(['A',2])
      sage: T = crystals.TensorProduct(C,C,C,generators=[[C(2),C(1),C(1)]])

  Python

      >>> from sage.all import *
      >>> C = crystals.Letters(['A',Integer(2)])
      >>> T = crystals.TensorProduct(C,C,C,generators=[[C(Integer(2)),C(Integer(1)),C(Integer(1))]])

  It has \(8\) elements:

  Sage

      sage: T.list()
      [[2, 1, 1], [2, 1, 2], [2, 1, 3], [3, 1, 3],
       [3, 2, 3], [3, 1, 1], [3, 1, 2], [3, 2, 2]]

  [Python]

      >>> from sage.all import *
      >>> T.list()
      [[2, 1, 1], [2, 1, 2], [2, 1, 3], [3, 1, 3],
       [3, 2, 3], [3, 1, 1], [3, 1, 2], [3, 2, 2]]

  One can also check the Cartan type of the crystal:

  Sage

      sage: T.cartan_type()
      ['A', 2]

  Python

      >>> from sage.all import *
      >>> T.cartan_type()
      ['A', 2]

  Other examples include crystals of tableaux (which internally are represented as tensor products obtained by reading the tableaux columnwise):

  Sage

      sage: C = crystals.Tableaux(['A',3], shape=[1,1,0])
      sage: D = crystals.Tableaux(['A',3], shape=[1,0,0])
      sage: T = crystals.TensorProduct(C,D, generators=[[C(rows=[[1], [2]]), D(rows=[[1]])], [C(rows=[[2], [3]]), D(rows=[[1]])]])
      sage: T.cardinality()
      24
      sage: TestSuite(T).run()
      sage: T.module_generators
      ([[[1], [2]], [[1]]], [[[2], [3]], [[1]]])
      sage: [x.weight() for x in T.module_generators]
      [(2, 1, 0, 0), (1, 1, 1, 0)]

  [Python]

      >>> from sage.all import *
      >>> C = crystals.Tableaux(['A',Integer(3)], shape=[Integer(1),Integer(1),Integer(0)])
      >>> D = crystals.Tableaux(['A',Integer(3)], shape=[Integer(1),Integer(0),Integer(0)])
      >>> T = crystals.TensorProduct(C,D, generators=[[C(rows=[[Integer(1)], [Integer(2)]]), D(rows=[[Integer(1)]])], [C(rows=[[Integer(2)], [Integer(3)]]), D(rows=[[Integer(1)]])]])
      >>> T.cardinality()
      24
      >>> TestSuite(T).run()
      >>> T.module_generators
      ([[[1], [2]], [[1]]], [[[2], [3]], [[1]]])
      >>> [x.weight() for x in T.module_generators]
      [(2, 1, 0, 0), (1, 1, 1, 0)]

  If no module generators are specified, we obtain the full tensor product:

  Sage

      sage: C = crystals.Letters(['A',2])
      sage: T = crystals.TensorProduct(C,C)
      sage: T.list()
      [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
      sage: T.cardinality()
      9

  Python

      >>> from sage.all import *
      >>> C = crystals.Letters(['A',Integer(2)])
      >>> T = crystals.TensorProduct(C,C)
      >>> T.list()
      [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
      >>> T.cardinality()
      9

  For a tensor product of crystals without module generators, the default implementation of `module_generators` contains all elements in the tensor product of the crystals. If there is a subset of elements in the tensor product that still generates the crystal, this needs to be implemented for the specific crystal separately:

  Sage

      sage: T.module_generators.list()
      [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]

  [Python]

      >>> from sage.all import *
      >>> T.module_generators.list()
      [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]

  For classical highest weight crystals, it is also possible to list all highest weight elements:

  Sage

      sage: C = crystals.Letters(['A',2])
      sage: T = crystals.TensorProduct(C,C,C,generators=[[C(2),C(1),C(1)],[C(1),C(2),C(1)]])
      sage: T.highest_weight_vectors()
      ([2, 1, 1], [1, 2, 1])

  Python

      >>> from sage.all import *
      >>> C = crystals.Letters(['A',Integer(2)])
      >>> T = crystals.TensorProduct(C,C,C,generators=[[C(Integer(2)),C(Integer(1)),C(Integer(1))],[C(Integer(1)),C(Integer(2)),C(Integer(1))]])
      >>> T.highest_weight_vectors()
      ([2, 1, 1], [1, 2, 1])

  Examples with non-regular and infinite crystals (these did not work before Issue #14402):

  Sage

      sage: B = crystals.infinity.Tableaux(['D',10])
      sage: T = crystals.TensorProduct(B,B)
      sage: T
      Full tensor product of the crystals
      [The infinity crystal of tableaux of type ['D', 10],
       The infinity crystal of tableaux of type ['D', 10]]

      sage: B = crystals.infinity.GeneralizedYoungWalls(15)
      sage: T = crystals.TensorProduct(B,B,B)
      sage: T
      Full tensor product of the crystals
      [Crystal of generalized Young walls of type ['A', 15, 1],
       Crystal of generalized Young walls of type ['A', 15, 1],
       Crystal of generalized Young walls of type ['A', 15, 1]]

      sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
      sage: B = crystals.GeneralizedYoungWalls(2,La[0]+La[1])
      sage: C = crystals.GeneralizedYoungWalls(2,2*La[2])
      sage: D = crystals.GeneralizedYoungWalls(2,3*La[0]+La[2])
      sage: T = crystals.TensorProduct(B,C,D)
      sage: T
      Full tensor product of the crystals
      [Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight Lambda[0] + Lambda[1],
       Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight 2*Lambda[2],
       Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight 3*Lambda[0] + Lambda[2]]

  [Python]

      >>> from sage.all import *
      >>> B = crystals.infinity.Tableaux(['D',Integer(10)])
      >>> T = crystals.TensorProduct(B,B)
      >>> T
      Full tensor product of the crystals
      [The infinity crystal of tableaux of type ['D', 10],
       The infinity crystal of tableaux of type ['D', 10]]

      >>> B = crystals.infinity.GeneralizedYoungWalls(Integer(15))
      >>> T = crystals.TensorProduct(B,B,B)
      >>> T
      Full tensor product of the crystals
      [Crystal of generalized Young walls of type ['A', 15, 1],
       Crystal of generalized Young walls of type ['A', 15, 1],
       Crystal of generalized Young walls of type ['A', 15, 1]]

      >>> La = RootSystem(['A',Integer(2),Integer(1)]).weight_lattice(extended=True).fundamental_weights()
      >>> B = crystals.GeneralizedYoungWalls(Integer(2),La[Integer(0)]+La[Integer(1)])
      >>> C = crystals.GeneralizedYoungWalls(Integer(2),Integer(2)*La[Integer(2)])
      >>> D = crystals.GeneralizedYoungWalls(Integer(2),Integer(3)*La[Integer(0)]+La[Integer(2)])
      >>> T = crystals.TensorProduct(B,C,D)
      >>> T
      Full tensor product of the crystals
      [Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight Lambda[0] + Lambda[1],
       Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight 2*Lambda[2],
       Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] and highest weight 3*Lambda[0] + Lambda[2]]

  There is also a global option for setting the convention (by default Sage uses anti-Kashiwara):

  Sage

      sage: C = crystals.Letters(['A',2])
      sage: T = crystals.TensorProduct(C,C)
      sage: elt = T(C(1), C(2)); elt
      [1, 2]
      sage: crystals.TensorProduct.options.convention = "Kashiwara"
      sage: elt
      [2, 1]
      sage: crystals.TensorProduct.options._reset()

  Python

      >>> from sage.all import *
      >>> C = crystals.Letters(['A',Integer(2)])
      >>> T = crystals.TensorProduct(C,C)
      >>> elt = T(C(Integer(1)), C(Integer(2))); elt
      [1, 2]
      >>> crystals.TensorProduct.options.convention = "Kashiwara"
      >>> elt
      [2, 1]
      >>> crystals.TensorProduct.options._reset()

  options = Current options for TensorProductOfCrystals - convention: antiKashiwara

class sage.combinat.crystals.tensor_product.TensorProductOfCrystalsWithGenerators(crystals, generators, cartan_type)

  Bases: `TensorProductOfCrystals`

  Tensor product of crystals with a generating set.

  Todo

  Deprecate this class in favor of using `subcrystal()`.

class sage.combinat.crystals.tensor_product.TensorProductOfRegularCrystalsWithGenerators(crystals, generators, cartan_type)

  Bases: `TensorProductOfCrystalsWithGenerators`

  Tensor product of regular crystals with a generating set.

  class Element

    Bases: `TensorProductOfRegularCrystalsElement`