Virtual crystals

These are the crystals that are subsets of a larger ambient crystal with virtual crystal operators.

AUTHORS:

  • Travis Scrimshaw (2013-10-16): initial implementation

class sage.combinat.crystals.virtual_crystal.VirtualCrystal(ambient, virtualization, scaling_factors, contained, generators, cartan_type, index_set, category)[source]

Bases: Subcrystal

A virtual crystal \(V\) of an ambient crystal \(\widehat{B}\) is a crystal formed by taking a subset of \(\widehat{B}\) and whose crystal structure is given by

\[e_i = \prod_{j \in \sigma_i} \widehat{e}_j^{\gamma_i}, \quad f_i = \prod_{j \in \sigma_i} \widehat{f}_j^{\gamma_i},\]
\[\varepsilon_i = \frac{\widehat{\varepsilon}_j}{\gamma_j}, \quad \varphi_i = \frac{\widehat{\varphi}_j}{\gamma_j}, \quad \operatorname{wt} = \Psi^{-1} \circ \widehat{\operatorname{wt}}\]

where \(\sigma_i\) is a subset of the index set of \(B\), \(\gamma_i \in \ZZ\) are the scaling factors, and \(\Psi : P \to \widehat{P}\) is an embedding of the weight lattices. We note that for the crystal to be well-defined, we must have

\[\widehat{\varepsilon}_j = \widehat{\varepsilon|j^{\prime}}, \quad \widehat{\varphi}_j = \widehat{\varphi}_{j^{\prime}}\]

for all \(j, j^{\prime} \in \sigma_i\) and that the order that the Kashiwara operators in the ambient space are applied does not affect the result.

INPUT:

  • ambient – the ambient crystal

  • virtualization – dictionary whose key \(i\) corresponds to the set \(\sigma_i\)

  • scaling_factors – dictionary whose key \(i\) corresponds to the scaling factor \(\gamma_i\)

  • contained – (optional) a set (or function) which specifies when an element is contained in the subcrystal; the default is everything possible is included

  • generators – (optional) the generators for the virtual crystal; the default is the generators for the ambient crystal

  • cartan_type – (optional) the Cartan type for the virtual crystal; the default is the Cartan type for the ambient crystal

  • index_set – (optional) the index set for the virtual crystal; the default is the index set for the Cartan type

  • category – (optional) the category for the virtual crystal; the default is the Crystals category

EXAMPLES:

We construct an example from a natural virtualization map of type \(C_n\) in type \(A_{2n-1}\):

sage: C = crystals.Tableaux(['C',2], shape=[1])
sage: A = crystals.Tableaux(['A',3], shape=[2,1,1])
sage: psi = C.crystal_morphism(A.module_generators)
sage: V = psi.image()
sage: list(V)
[[[1, 1], [2], [3]],
 [[1, 2], [2], [4]],
 [[1, 3], [3], [4]],
 [[2, 4], [3], [4]]]
sage: V.digraph().is_isomorphic(C.digraph(), edge_labels=True)
True
>>> from sage.all import *
>>> C = crystals.Tableaux(['C',Integer(2)], shape=[Integer(1)])
>>> A = crystals.Tableaux(['A',Integer(3)], shape=[Integer(2),Integer(1),Integer(1)])
>>> psi = C.crystal_morphism(A.module_generators)
>>> V = psi.image()
>>> list(V)
[[[1, 1], [2], [3]],
 [[1, 2], [2], [4]],
 [[1, 3], [3], [4]],
 [[2, 4], [3], [4]]]
>>> V.digraph().is_isomorphic(C.digraph(), edge_labels=True)
True

We construct the virtualization of a \(U_q'(\mathfrak{g})\)-crystal \(B^{r,s}\) of type \(C_n^{(1)}\) in type \(A_{2n+1}^{(2)}\). Here it is not a default folding known to Sage, so we have to explicitly state the folding (since the scaling factors are not specified, they are all assumed to be 1):

sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,1)
sage: VK = crystals.KirillovReshetikhin(['A',5,2], 1,1)
sage: target = VK.module_generator().f(1); target
[[2]]
sage: psi = K.crystal_morphism({K.module_generator(): target},
....:                          virtualization={0:[0,1], 1:[2], 2:[3]})
sage: V = psi.image()
sage: list(V)
[[[2]], [[3]], [[-2]], [[-3]]]
sage: V.digraph().is_isomorphic(K.digraph(), edge_labels=True)
True
>>> from sage.all import *
>>> K = crystals.KirillovReshetikhin(['C',Integer(2),Integer(1)], Integer(1),Integer(1))
>>> VK = crystals.KirillovReshetikhin(['A',Integer(5),Integer(2)], Integer(1),Integer(1))
>>> target = VK.module_generator().f(Integer(1)); target
[[2]]
>>> psi = K.crystal_morphism({K.module_generator(): target},
...                          virtualization={Integer(0):[Integer(0),Integer(1)], Integer(1):[Integer(2)], Integer(2):[Integer(3)]})
>>> V = psi.image()
>>> list(V)
[[[2]], [[3]], [[-2]], [[-3]]]
>>> V.digraph().is_isomorphic(K.digraph(), edge_labels=True)
True

We create an example of \(B(\Lambda_n)\) of type \(B_n\) inside of \(B(2\Lambda_n)\) using the doubling map through the (virtual) subcrystal method:

sage: BB = crystals.Tableaux(['B',3], shape=[1,1,1])
sage: S = BB.subcrystal(scaling_factors={1:2, 2:2, 3:2})
sage: B = crystals.Tableaux(['B',3], shape=[1/2,1/2,1/2])
sage: S.digraph().is_isomorphic(B.digraph(), edge_labels=True)
True
>>> from sage.all import *
>>> BB = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1),Integer(1),Integer(1)])
>>> S = BB.subcrystal(scaling_factors={Integer(1):Integer(2), Integer(2):Integer(2), Integer(3):Integer(2)})
>>> B = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1)/Integer(2),Integer(1)/Integer(2),Integer(1)/Integer(2)])
>>> S.digraph().is_isomorphic(B.digraph(), edge_labels=True)
True

We can also directly construct a virtual crystal using VirtualCrystal (however it is recommended to use either crystal_morphism() or subcrystal()):

sage: from sage.combinat.crystals.virtual_crystal import VirtualCrystal
sage: A = crystals.Tableaux(['A',3], shape=[2,1,1])
sage: V = VirtualCrystal(A, {1:(1,3), 2:(2,)}, {1:1, 2:2}, cartan_type=['C',2])
sage: G = crystals.Tableaux(['C',2], shape=[1]).digraph()
sage: V.digraph().is_isomorphic(G, edge_labels=True)
True

sage: C1 = crystals.Tableaux(['A',3], shape=[1])
sage: C2 = crystals.Tableaux(['A',3], shape=[1,1,1])
sage: T = C1.tensor(C2)
sage: mg = T(C1.module_generators[0], C2.module_generators[0])
sage: V = VirtualCrystal(A, {1:(1,3), 2:(2,)}, {1:1, 2:2},
....:                    cartan_type=['C',2], generators=[mg])
sage: V.digraph().is_isomorphic(G, edge_labels=True)
True
>>> from sage.all import *
>>> from sage.combinat.crystals.virtual_crystal import VirtualCrystal
>>> A = crystals.Tableaux(['A',Integer(3)], shape=[Integer(2),Integer(1),Integer(1)])
>>> V = VirtualCrystal(A, {Integer(1):(Integer(1),Integer(3)), Integer(2):(Integer(2),)}, {Integer(1):Integer(1), Integer(2):Integer(2)}, cartan_type=['C',Integer(2)])
>>> G = crystals.Tableaux(['C',Integer(2)], shape=[Integer(1)]).digraph()
>>> V.digraph().is_isomorphic(G, edge_labels=True)
True

>>> C1 = crystals.Tableaux(['A',Integer(3)], shape=[Integer(1)])
>>> C2 = crystals.Tableaux(['A',Integer(3)], shape=[Integer(1),Integer(1),Integer(1)])
>>> T = C1.tensor(C2)
>>> mg = T(C1.module_generators[Integer(0)], C2.module_generators[Integer(0)])
>>> V = VirtualCrystal(A, {Integer(1):(Integer(1),Integer(3)), Integer(2):(Integer(2),)}, {Integer(1):Integer(1), Integer(2):Integer(2)},
...                    cartan_type=['C',Integer(2)], generators=[mg])
>>> V.digraph().is_isomorphic(G, edge_labels=True)
True

REFERENCES:

class Element[source]

Bases: Element

An element of a virtual (sub)crystal. Wraps an element in the ambient crystal.

e(i)[source]

Return \(e_i\) of self.

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: V = psi.image()
sage: mg = V.module_generators[0]
sage: mg.e(1)
sage: b = psi(B.module_generators[0].f(1))
sage: V(b).e(1)
[[1, 1]]
>>> from sage.all import *
>>> B = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1)])
>>> C = crystals.Tableaux(['D',Integer(4)], shape=[Integer(2)])
>>> psi = B.crystal_morphism(C.module_generators)
>>> V = psi.image()
>>> mg = V.module_generators[Integer(0)]
>>> mg.e(Integer(1))
>>> b = psi(B.module_generators[Integer(0)].f(Integer(1)))
>>> V(b).e(Integer(1))
[[1, 1]]
epsilon(i)[source]

Return \(\varepsilon_i\) of self.

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: V = psi.image()
sage: mg = V.module_generators[0]
sage: mg.epsilon(2)
0
sage: mg.f(1).epsilon(1)
1
>>> from sage.all import *
>>> B = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1)])
>>> C = crystals.Tableaux(['D',Integer(4)], shape=[Integer(2)])
>>> psi = B.crystal_morphism(C.module_generators)
>>> V = psi.image()
>>> mg = V.module_generators[Integer(0)]
>>> mg.epsilon(Integer(2))
0
>>> mg.f(Integer(1)).epsilon(Integer(1))
1
f(i)[source]

Return \(f_i\) of self.

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: V = psi.image()
sage: mg = V.module_generators[0]
sage: mg.f(1)
[[2, 2]]
sage: mg.f(2)
>>> from sage.all import *
>>> B = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1)])
>>> C = crystals.Tableaux(['D',Integer(4)], shape=[Integer(2)])
>>> psi = B.crystal_morphism(C.module_generators)
>>> V = psi.image()
>>> mg = V.module_generators[Integer(0)]
>>> mg.f(Integer(1))
[[2, 2]]
>>> mg.f(Integer(2))
phi(i)[source]

Return \(\varphi_i\) of self.

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: V = psi.image()
sage: mg = V.module_generators[0]
sage: mg.phi(1)
1
sage: mg.phi(2)
0
>>> from sage.all import *
>>> B = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1)])
>>> C = crystals.Tableaux(['D',Integer(4)], shape=[Integer(2)])
>>> psi = B.crystal_morphism(C.module_generators)
>>> V = psi.image()
>>> mg = V.module_generators[Integer(0)]
>>> mg.phi(Integer(1))
1
>>> mg.phi(Integer(2))
0
weight()[source]

Return the weight of self.

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: V = psi.image()
sage: mg = V.module_generators[0]
sage: mg.weight()
(1, 0, 0)
sage: mg.f(1).weight()
(0, 1, 0)
sage: all(V(psi(x)).weight() == x.weight() for x in B)
True
>>> from sage.all import *
>>> B = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1)])
>>> C = crystals.Tableaux(['D',Integer(4)], shape=[Integer(2)])
>>> psi = B.crystal_morphism(C.module_generators)
>>> V = psi.image()
>>> mg = V.module_generators[Integer(0)]
>>> mg.weight()
(1, 0, 0)
>>> mg.f(Integer(1)).weight()
(0, 1, 0)
>>> all(V(psi(x)).weight() == x.weight() for x in B)
True
scaling_factors()[source]

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: V = psi.image()
sage: V.scaling_factors()
Finite family {1: 2, 2: 2, 3: 1}
>>> from sage.all import *
>>> B = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1)])
>>> C = crystals.Tableaux(['D',Integer(4)], shape=[Integer(2)])
>>> psi = B.crystal_morphism(C.module_generators)
>>> V = psi.image()
>>> V.scaling_factors()
Finite family {1: 2, 2: 2, 3: 1}
virtualization()[source]

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: V = psi.image()
sage: V.virtualization()
Finite family {1: (1,), 2: (2,), 3: (3, 4)}
>>> from sage.all import *
>>> B = crystals.Tableaux(['B',Integer(3)], shape=[Integer(1)])
>>> C = crystals.Tableaux(['D',Integer(4)], shape=[Integer(2)])
>>> psi = B.crystal_morphism(C.module_generators)
>>> V = psi.image()
>>> V.virtualization()
Finite family {1: (1,), 2: (2,), 3: (3, 4)}