Crystals

class sage.categories.crystals.CrystalHomset(X, Y, category=None)

Bases: sage.categories.homset.Homset

The set of crystal morphisms from one crystal to another.

An \(U_q(\mathfrak{g})\) \(I\)-crystal morphism \(\Psi : B \to C\) is a map \(\Psi : B \cup \{ 0 \} \to C \cup \{ 0 \}\) such that:

  • \(\Psi(0) = 0\).
  • If \(b \in B\) and \(\Psi(b) \in C\), then \(\mathrm{wt}(\Psi(b)) = \mathrm{wt}(b)\), \(\varepsilon_i(\Psi(b)) = \varepsilon_i(b)\), and \(\varphi_i(\Psi(b)) = \varphi_i(b)\) for all \(i \in I\).
  • If \(b, b^{\prime} \in B\), \(\Psi(b), \Psi(b^{\prime}) \in C\) and \(f_i b = b^{\prime}\), then \(f_i \Psi(b) = \Psi(b^{\prime})\) and \(\Psi(b) = e_i \Psi(b^{\prime})\) for all \(i \in I\).

If the Cartan type is unambiguous, it is surpressed from the notation.

We can also generalize the definition of a crystal morphism by considering a map of \(\sigma\) of the (now possibly different) Dynkin diagrams corresponding to \(B\) and \(C\) along with scaling factors \(\gamma_i \in \ZZ\) for \(i \in I\). Let \(\sigma_i\) denote the orbit of \(i\) under \(\sigma\). We write objects for \(B\) as \(X\) with corresponding objects of \(C\) as \(\widehat{X}\). Then a virtual crystal morphism \(\Psi\) is a map such that the following holds:

  • \(\Psi(0) = 0\).
  • If \(b \in B\) and \(\Psi(b) \in C\), then for all \(j \in \sigma_i\):
\[\varepsilon_i(b) = \frac{1}{\gamma_j} \widehat{\varepsilon}_j(\Psi(b)), \quad \varphi_i(b) = \frac{1}{\gamma_j} \widehat{\varphi}_j(\Psi(b)), \quad \mathrm{wt}(\Psi(b)) = \sum_i c_i \sum_{j \in \sigma_i} \gamma_j \widehat{\Lambda}_j,\]

where \(\mathrm{wt}(b) = \sum_i c_i \Lambda_i\).

  • If \(b, b^{\prime} \in B\), \(\Psi(b), \Psi(b^{\prime}) \in C\) and \(f_i b = b^{\prime}\), then independent of the ordering of \(\sigma_i\) we have:

    \[\Psi(b^{\prime}) = e_i \Psi(b) = \prod_{j \in \sigma_i} \widehat{e}_j^{\gamma_i} \Psi(b), \quad \Psi(b^{\prime}) = f_i \Psi(b) = \prod_{j \in \sigma_i} \widehat{f}_j^{\gamma_i} \Psi(b).\]

If \(\gamma_i = 1\) for all \(i \in I\) and the Dynkin diagrams are the same, then we call \(\Psi\) a twisted crystal morphism.

INPUT:

  • X – the domain
  • Y – the codomain
  • category – (optional) the category of the crystal morphisms

See also

For the construction of an element of the homset, see CrystalMorphismByGenerators and crystal_morphism().

EXAMPLES:

We begin with the natural embedding of \(B(2\Lambda_1)\) into \(B(\Lambda_1) \otimes B(\Lambda_1)\) in type \(A_1\):

sage: B = crystals.Tableaux(['A',1], shape=[2])
sage: F = crystals.Tableaux(['A',1], shape=[1])
sage: T = crystals.TensorProduct(F, F)
sage: v = T.highest_weight_vectors()[0]; v
[[[1]], [[1]]]
sage: H = Hom(B, T)
sage: psi = H([v])
sage: b = B.highest_weight_vector(); b
[[1, 1]]
sage: psi(b)
[[[1]], [[1]]]
sage: b.f(1)
[[1, 2]]
sage: psi(b.f(1))
[[[1]], [[2]]]

We now look at the decomposition of \(B(\Lambda_1) \otimes B(\Lambda_1)\) into \(B(2\Lambda_1) \oplus B(0)\):

sage: B0 = crystals.Tableaux(['A',1], shape=[])
sage: D = crystals.DirectSum([B, B0])
sage: H = Hom(T, D)
sage: psi = H(D.module_generators)
sage: psi
['A', 1] Crystal morphism:
  From: Full tensor product of the crystals
   [The crystal of tableaux of type ['A', 1] and shape(s) [[1]],
    The crystal of tableaux of type ['A', 1] and shape(s) [[1]]]
  To:   Direct sum of the crystals Family
   (The crystal of tableaux of type ['A', 1] and shape(s) [[2]],
    The crystal of tableaux of type ['A', 1] and shape(s) [[]])
  Defn: [[[1]], [[1]]] |--> [[1, 1]]
        [[[2]], [[1]]] |--> []
sage: psi.is_isomorphism()
True

We can always construct the trivial morphism which sends everything to \(0\):

sage: Binf = crystals.infinity.Tableaux(['B', 2])
sage: B = crystals.Tableaux(['B',2], shape=[1])
sage: H = Hom(Binf, B)
sage: psi = H(lambda x: None)
sage: psi(Binf.highest_weight_vector())

For Kirillov-Reshetikhin crystals, we consider the map to the corresponding classical crystal:

sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,1)
sage: B = K.classical_decomposition()
sage: H = Hom(K, B)
sage: psi = H(lambda x: x.lift(), cartan_type=['D',4])
sage: L = [psi(mg) for mg in K.module_generators]; L
[[], [[1], [2]]]
sage: all(x.parent() == B for x in L)
True

Next we consider a type \(D_4\) crystal morphism where we twist by \(3 \leftrightarrow 4\):

sage: B = crystals.Tableaux(['D',4], shape=[1])
sage: H = Hom(B, B)
sage: d = {1:1, 2:2, 3:4, 4:3}
sage: psi = H(B.module_generators, automorphism=d)
sage: b = B.highest_weight_vector()
sage: b.f_string([1,2,3])
[[4]]
sage: b.f_string([1,2,4])
[[-4]]
sage: psi(b.f_string([1,2,3]))
[[-4]]
sage: psi(b.f_string([1,2,4]))
[[4]]

We construct the natural virtual embedding of a type \(B_3\) into a type \(D_4\) crystal:

sage: B = crystals.Tableaux(['B',3], shape=[1])
sage: C = crystals.Tableaux(['D',4], shape=[2])
sage: H = Hom(B, C)
sage: psi = H(C.module_generators)
sage: psi
['B', 3] -> ['D', 4] Virtual Crystal morphism:
  From: The crystal of tableaux of type ['B', 3] and shape(s) [[1]]
  To:   The crystal of tableaux of type ['D', 4] and shape(s) [[2]]
  Defn: [[1]] |--> [[1, 1]]
sage: for b in B: print("{} |--> {}".format(b, psi(b)))
[[1]] |--> [[1, 1]]
[[2]] |--> [[2, 2]]
[[3]] |--> [[3, 3]]
[[0]] |--> [[3, -3]]
[[-3]] |--> [[-3, -3]]
[[-2]] |--> [[-2, -2]]
[[-1]] |--> [[-1, -1]]
Element

alias of CrystalMorphismByGenerators

class sage.categories.crystals.CrystalMorphism(parent, cartan_type=None, virtualization=None, scaling_factors=None)

Bases: sage.categories.morphism.Morphism

A crystal morphism.

INPUT:

  • parent – a homset
  • cartan_type – (optional) a Cartan type; the default is the Cartan type of the domain
  • virtualization – (optional) a dictionary whose keys are in the index set of the domain and whose values are lists of entries in the index set of the codomain
  • scaling_factors – (optional) a dictionary whose keys are in the index set of the domain and whose values are scaling factors for the weight, \(\varepsilon\) and \(\varphi\)
cartan_type()

Return the Cartan type of self.

EXAMPLES:

sage: B = crystals.Tableaux(['A',2], shape=[2,1])
sage: psi = Hom(B, B).an_element()
sage: psi.cartan_type()
['A', 2]
is_injective()

Return if self is an injective crystal morphism.

EXAMPLES:

sage: B = crystals.Tableaux(['A',2], shape=[2,1])
sage: psi = Hom(B, B).an_element()
sage: psi.is_injective()
False
is_surjective()

Check if self is a surjective crystal morphism.

EXAMPLES:

sage: B = crystals.Tableaux(['C',2], shape=[1,1])
sage: C = crystals.Tableaux(['C',2], ([2,1], [1,1]))
sage: psi = B.crystal_morphism(C.module_generators[1:], codomain=C)
sage: psi.is_surjective()
False
sage: im_gens = [None, B.module_generators[0]]
sage: psi = C.crystal_morphism(im_gens, codomain=B)
sage: psi.is_surjective()
True

sage: C = crystals.Tableaux(['A',2], shape=[2,1])
sage: B = crystals.infinity.Tableaux(['A',2])
sage: La = RootSystem(['A',2]).weight_lattice().fundamental_weights()
sage: W = crystals.elementary.T(['A',2], La[1]+La[2])
sage: T = W.tensor(B)
sage: mg = T(W.module_generators[0], B.module_generators[0])
sage: psi = Hom(C,T)([mg])
sage: psi.is_surjective()
False
scaling_factors()

Return the scaling factors \(\gamma_i\).

EXAMPLES:

sage: B = crystals.Tableaux(['B',3], shape=[1])
sage: C = crystals.Tableaux(['D',4], shape=[2])
sage: psi = B.crystal_morphism(C.module_generators)
sage: psi.scaling_factors()
Finite family {1: 2, 2: 2, 3: 1}
virtualization()

Return the virtualization sets \(\sigma_i\).

EXAMPLES:

sage: B = crystals.Tableaux(['B',3], shape=[1])
sage: C = crystals.Tableaux(['D',4], shape=[2])
sage: psi = B.crystal_morphism(C.module_generators)
sage: psi.virtualization()
Finite family {1: (1,), 2: (2,), 3: (3, 4)}
class sage.categories.crystals.CrystalMorphismByGenerators(parent, on_gens, cartan_type=None, virtualization=None, scaling_factors=None, gens=None, check=True)

Bases: sage.categories.crystals.CrystalMorphism

A crystal morphism defined by a set of generators which create a virtual crystal inside the codomain.

INPUT:

  • parent – a homset
  • on_gens – a function or list that determines the image of the generators (if given a list, then this uses the order of the generators of the domain) of the domain under self
  • cartan_type – (optional) a Cartan type; the default is the Cartan type of the domain
  • virtualization – (optional) a dictionary whose keys are in the index set of the domain and whose values are lists of entries in the index set of the codomain
  • scaling_factors – (optional) a dictionary whose keys are in the index set of the domain and whose values are scaling factors for the weight, \(\varepsilon\) and \(\varphi\)
  • gens – (optional) a finite list of generators to define the morphism; the default is to use the highest weight vectors of the crystal
  • check – (default: True) check if the crystal morphism is valid

See also

sage.categories.crystals.Crystals.ParentMethods.crystal_morphism()

im_gens()

Return the image of the generators of self as a tuple.

EXAMPLES:

sage: B = crystals.Tableaux(['A',2], shape=[2,1])
sage: F = crystals.Tableaux(['A',2], shape=[1])
sage: T = crystals.TensorProduct(F, F, F)
sage: H = Hom(T, B)
sage: b = B.highest_weight_vector()
sage: psi = H((None, b, b, None), generators=T.highest_weight_vectors())
sage: psi.im_gens()
(None, [[1, 1], [2]], [[1, 1], [2]], None)
image()

Return the image of self in the codomain as a Subcrystal.

Warning

This assumes that self is a strict crystal morphism.

EXAMPLES:

sage: B = crystals.Tableaux(['B',3], shape=[1])
sage: C = crystals.Tableaux(['D',4], shape=[2])
sage: H = Hom(B, C)
sage: psi = H(C.module_generators)
sage: psi.image()
Virtual crystal of The crystal of tableaux of type ['D', 4] and shape(s) [[2]] of type ['B', 3]
to_module_generator(x)

Return a generator mg and a path of \(e_i\) and \(f_i\) operations to mg.

OUTPUT:

A tuple consisting of:

  • a module generator,
  • a list of 'e' and 'f' to denote which operation, and
  • a list of matching indices.

EXAMPLES:

sage: B = crystals.elementary.Elementary(['A',2], 2)
sage: psi = B.crystal_morphism(B.module_generators)
sage: psi.to_module_generator(B(4))
(0, ['f', 'f', 'f', 'f'], [2, 2, 2, 2])
sage: psi.to_module_generator(B(-2))
(0, ['e', 'e'], [2, 2])
sage.categories.crystals.Crystals

The category of crystals.

See sage.combinat.crystals.crystals for an introduction to crystals.

EXAMPLES:

sage: C = Crystals()
sage: C
Category of crystals
sage: C.super_categories()
[Category of... enumerated sets]
sage: C.example()
Highest weight crystal of type A_3 of highest weight omega_1

Parents in this category should implement the following methods:

  • either an attribute _cartan_type or a method cartan_type
  • module_generators: a list (or container) of distinct elements which generate the crystal using \(f_i\)

Furthermore, their elements x should implement the following methods:

  • x.e(i) (returning \(e_i(x)\))
  • x.f(i) (returning \(f_i(x)\))
  • x.epsilon(i) (returning \(\varepsilon_i(x)\))
  • x.phi(i) (returning \(\varphi_i(x)\))

EXAMPLES:

sage: from sage.misc.abstract_method import abstract_methods_of_class
sage: abstract_methods_of_class(Crystals().element_class)
{'optional': [], 'required': ['e', 'epsilon', 'f', 'phi', 'weight']}