Induced Crystals¶
We construct a crystal structure on a set induced by a bijection \(\Phi\).
AUTHORS:
- Travis Scrimshaw (2014-05-15): Initial implementation 
- class sage.combinat.crystals.induced_structure.InducedCrystal(X, phi, inverse)[source]¶
- Bases: - UniqueRepresentation,- Parent- A crystal induced from an injection. - Let \(X\) be a set and let \(C\) be crystal and consider any injection \(\Phi : X \to C\). We induce a crystal structure on \(X\) by considering \(\Phi\) to be a crystal morphism. - Alternatively we can induce a crystal structure on some (sub)set of \(X\) by considering an injection \(\Phi : C \to X\) considered as a crystal morphism. This form is also useful when the set \(X\) is not explicitly known. - INPUT: - X– the base set
- phi– the map \(\Phi\)
- inverse– (optional) the inverse map \(\Phi^{-1}\)
- from_crystal– boolean (default:- False); if the induced structure is of the second type \(\Phi : C \to X\)
 - EXAMPLES: - We construct a crystal structure of Gelfand-Tsetlin patterns by going through their bijection with semistandard tableaux: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,3)) sage: G = GelfandTsetlinPatterns(4, 3) sage: phi = lambda x: D(x.to_tableau()) sage: phi_inv = lambda x: G(x.to_tableau()) sage: I = crystals.Induced(G, phi, phi_inv) sage: I.digraph().is_isomorphic(D.digraph(), edge_labels=True) True - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(3))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(3)) >>> phi = lambda x: D(x.to_tableau()) >>> phi_inv = lambda x: G(x.to_tableau()) >>> I = crystals.Induced(G, phi, phi_inv) >>> I.digraph().is_isomorphic(D.digraph(), edge_labels=True) True - Now we construct the above example but inducing the structure going the other way (from tableaux to Gelfand-Tsetlin patterns). This can also give us more information coming from the crystal. - sage: D2 = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,1)) sage: G2 = GelfandTsetlinPatterns(4, 1) sage: phi2 = lambda x: D2(x.to_tableau()) sage: phi2_inv = lambda x: G2(x.to_tableau()) sage: I2 = crystals.Induced(D2, phi2_inv, phi2, from_crystal=True) sage: I2.module_generators ([[0, 0, 0, 0], [0, 0, 0], [0, 0], [0]], [[1, 0, 0, 0], [1, 0, 0], [1, 0], [1]], [[1, 1, 0, 0], [1, 1, 0], [1, 1], [1]], [[1, 1, 1, 0], [1, 1, 1], [1, 1], [1]], [[1, 1, 1, 1], [1, 1, 1], [1, 1], [1]]) - >>> from sage.all import * >>> D2 = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(1))) >>> G2 = GelfandTsetlinPatterns(Integer(4), Integer(1)) >>> phi2 = lambda x: D2(x.to_tableau()) >>> phi2_inv = lambda x: G2(x.to_tableau()) >>> I2 = crystals.Induced(D2, phi2_inv, phi2, from_crystal=True) >>> I2.module_generators ([[0, 0, 0, 0], [0, 0, 0], [0, 0], [0]], [[1, 0, 0, 0], [1, 0, 0], [1, 0], [1]], [[1, 1, 0, 0], [1, 1, 0], [1, 1], [1]], [[1, 1, 1, 0], [1, 1, 1], [1, 1], [1]], [[1, 1, 1, 1], [1, 1, 1], [1, 1], [1]]) - We check an example when the codomain is larger than the domain (although here the crystal structure is trivial): - sage: P = Permutations(4) sage: D = crystals.Tableaux(['A',3], shapes=Partitions(4)) sage: T = crystals.TensorProduct(D, D) sage: phi = lambda p: T(D(RSK(p)[0]), D(RSK(p)[1])) sage: phi_inv = lambda d: RSK_inverse(d[0].to_tableau(), d[1].to_tableau(), output='permutation') sage: all(phi_inv(phi(p)) == p for p in P) # Check it really is the inverse True sage: I = crystals.Induced(P, phi, phi_inv) sage: I.digraph() Digraph on 24 vertices - >>> from sage.all import * >>> P = Permutations(Integer(4)) >>> D = crystals.Tableaux(['A',Integer(3)], shapes=Partitions(Integer(4))) >>> T = crystals.TensorProduct(D, D) >>> phi = lambda p: T(D(RSK(p)[Integer(0)]), D(RSK(p)[Integer(1)])) >>> phi_inv = lambda d: RSK_inverse(d[Integer(0)].to_tableau(), d[Integer(1)].to_tableau(), output='permutation') >>> all(phi_inv(phi(p)) == p for p in P) # Check it really is the inverse True >>> I = crystals.Induced(P, phi, phi_inv) >>> I.digraph() Digraph on 24 vertices - We construct an example without a specified inverse map: - sage: X = Words(2,4) sage: L = crystals.Letters(['A',1]) sage: T = crystals.TensorProduct(*[L]*4) sage: Phi = lambda x : T(*[L(i) for i in x]) sage: I = crystals.Induced(X, Phi) sage: I.digraph() Digraph on 16 vertices - >>> from sage.all import * >>> X = Words(Integer(2),Integer(4)) >>> L = crystals.Letters(['A',Integer(1)]) >>> T = crystals.TensorProduct(*[L]*Integer(4)) >>> Phi = lambda x : T(*[L(i) for i in x]) >>> I = crystals.Induced(X, Phi) >>> I.digraph() Digraph on 16 vertices - class Element[source]¶
- Bases: - ElementWrapper- An element of an induced crystal. - e(i)[source]¶
- Return \(e_i\) of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,3)) sage: G = GelfandTsetlinPatterns(4, 3) sage: phi = lambda x: D(x.to_tableau()) sage: phi_inv = lambda x: G(x.to_tableau()) sage: I = crystals.Induced(G, phi, phi_inv) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: elt.e(1) sage: elt.e(2) [[1, 1, 0, 0], [1, 1, 0], [1, 1], [1]] sage: elt.e(3) - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(3))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(3)) >>> phi = lambda x: D(x.to_tableau()) >>> phi_inv = lambda x: G(x.to_tableau()) >>> I = crystals.Induced(G, phi, phi_inv) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> elt.e(Integer(1)) >>> elt.e(Integer(2)) [[1, 1, 0, 0], [1, 1, 0], [1, 1], [1]] >>> elt.e(Integer(3)) 
 - epsilon(i)[source]¶
- Return \(\varepsilon_i\) of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,3)) sage: G = GelfandTsetlinPatterns(4, 3) sage: phi = lambda x: D(x.to_tableau()) sage: phi_inv = lambda x: G(x.to_tableau()) sage: I = crystals.Induced(G, phi, phi_inv) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: [elt.epsilon(i) for i in I.index_set()] [0, 1, 0] - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(3))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(3)) >>> phi = lambda x: D(x.to_tableau()) >>> phi_inv = lambda x: G(x.to_tableau()) >>> I = crystals.Induced(G, phi, phi_inv) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> [elt.epsilon(i) for i in I.index_set()] [0, 1, 0] 
 - f(i)[source]¶
- Return \(f_i\) of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,3)) sage: G = GelfandTsetlinPatterns(4, 3) sage: phi = lambda x: D(x.to_tableau()) sage: phi_inv = lambda x: G(x.to_tableau()) sage: I = crystals.Induced(G, phi, phi_inv) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: elt.f(1) [[1, 1, 0, 0], [1, 1, 0], [1, 0], [0]] sage: elt.f(2) sage: elt.f(3) [[1, 1, 0, 0], [1, 0, 0], [1, 0], [1]] - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(3))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(3)) >>> phi = lambda x: D(x.to_tableau()) >>> phi_inv = lambda x: G(x.to_tableau()) >>> I = crystals.Induced(G, phi, phi_inv) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> elt.f(Integer(1)) [[1, 1, 0, 0], [1, 1, 0], [1, 0], [0]] >>> elt.f(Integer(2)) >>> elt.f(Integer(3)) [[1, 1, 0, 0], [1, 0, 0], [1, 0], [1]] 
 - phi(i)[source]¶
- Return \(\varphi_i\) of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,3)) sage: G = GelfandTsetlinPatterns(4, 3) sage: phi = lambda x: D(x.to_tableau()) sage: phi_inv = lambda x: G(x.to_tableau()) sage: I = crystals.Induced(G, phi, phi_inv) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: [elt.phi(i) for i in I.index_set()] [1, 0, 1] - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(3))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(3)) >>> phi = lambda x: D(x.to_tableau()) >>> phi_inv = lambda x: G(x.to_tableau()) >>> I = crystals.Induced(G, phi, phi_inv) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> [elt.phi(i) for i in I.index_set()] [1, 0, 1] 
 - weight()[source]¶
- Return the weight of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,3)) sage: G = GelfandTsetlinPatterns(4, 3) sage: phi = lambda x: D(x.to_tableau()) sage: phi_inv = lambda x: G(x.to_tableau()) sage: I = crystals.Induced(G, phi, phi_inv) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: elt.weight() (1, 0, 1, 0) - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(3))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(3)) >>> phi = lambda x: D(x.to_tableau()) >>> phi_inv = lambda x: G(x.to_tableau()) >>> I = crystals.Induced(G, phi, phi_inv) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> elt.weight() (1, 0, 1, 0) 
 
 - cardinality()[source]¶
- Return the cardinality of - self.- EXAMPLES: - sage: P = Permutations(4) sage: D = crystals.Tableaux(['A',3], shapes=Partitions(4)) sage: T = crystals.TensorProduct(D, D) sage: phi = lambda p: T(D(RSK(p)[0]), D(RSK(p)[1])) sage: phi_inv = lambda d: RSK_inverse(d[0].to_tableau(), d[1].to_tableau(), output='permutation') sage: I = crystals.Induced(P, phi, phi_inv) sage: I.cardinality() == factorial(4) True - >>> from sage.all import * >>> P = Permutations(Integer(4)) >>> D = crystals.Tableaux(['A',Integer(3)], shapes=Partitions(Integer(4))) >>> T = crystals.TensorProduct(D, D) >>> phi = lambda p: T(D(RSK(p)[Integer(0)]), D(RSK(p)[Integer(1)])) >>> phi_inv = lambda d: RSK_inverse(d[Integer(0)].to_tableau(), d[Integer(1)].to_tableau(), output='permutation') >>> I = crystals.Induced(P, phi, phi_inv) >>> I.cardinality() == factorial(Integer(4)) True 
 
- class sage.combinat.crystals.induced_structure.InducedFromCrystal(X, phi, inverse)[source]¶
- Bases: - UniqueRepresentation,- Parent- A crystal induced from an injection. - Alternatively we can induce a crystal structure on some (sub)set of \(X\) by considering an injection \(\Phi : C \to X\) considered as a crystal morphism. - See also - INPUT: - X– the base set
- phi– the map \(\Phi\)
- inverse– (optional) the inverse map \(\Phi^{-1}\)
 - EXAMPLES: - We construct a crystal structure on generalized permutations with a fixed first row by using RSK: - sage: C = crystals.Tableaux(['A',3], shape=[2,1]) sage: def psi(x): ....: ret = RSK_inverse(x.to_tableau(), Tableau([[1,1],[2]])) ....: return (tuple(ret[0]), tuple(ret[1])) sage: psi_inv = lambda x: C(RSK(*x)[0]) sage: I = crystals.Induced(C, psi, psi_inv, from_crystal=True) - >>> from sage.all import * >>> C = crystals.Tableaux(['A',Integer(3)], shape=[Integer(2),Integer(1)]) >>> def psi(x): ... ret = RSK_inverse(x.to_tableau(), Tableau([[Integer(1),Integer(1)],[Integer(2)]])) ... return (tuple(ret[Integer(0)]), tuple(ret[Integer(1)])) >>> psi_inv = lambda x: C(RSK(*x)[Integer(0)]) >>> I = crystals.Induced(C, psi, psi_inv, from_crystal=True) - class Element[source]¶
- Bases: - ElementWrapper- An element of an induced crystal. - e(i)[source]¶
- Return \(e_i\) of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,1)) sage: G = GelfandTsetlinPatterns(4, 1) sage: def phi(x): return G(x.to_tableau()) sage: def phi_inv(x): return D(G(x).to_tableau()) sage: I = crystals.Induced(D, phi, phi_inv, from_crystal=True) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: elt.e(1) sage: elt.e(2) [[1, 1, 0, 0], [1, 1, 0], [1, 1], [1]] sage: elt.e(3) - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(1))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(1)) >>> def phi(x): return G(x.to_tableau()) >>> def phi_inv(x): return D(G(x).to_tableau()) >>> I = crystals.Induced(D, phi, phi_inv, from_crystal=True) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> elt.e(Integer(1)) >>> elt.e(Integer(2)) [[1, 1, 0, 0], [1, 1, 0], [1, 1], [1]] >>> elt.e(Integer(3)) 
 - epsilon(i)[source]¶
- Return \(\varepsilon_i\) of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,1)) sage: G = GelfandTsetlinPatterns(4, 1) sage: def phi(x): return G(x.to_tableau()) sage: def phi_inv(x): return D(G(x).to_tableau()) sage: I = crystals.Induced(D, phi, phi_inv, from_crystal=True) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: [elt.epsilon(i) for i in I.index_set()] [0, 1, 0] - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(1))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(1)) >>> def phi(x): return G(x.to_tableau()) >>> def phi_inv(x): return D(G(x).to_tableau()) >>> I = crystals.Induced(D, phi, phi_inv, from_crystal=True) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> [elt.epsilon(i) for i in I.index_set()] [0, 1, 0] 
 - f(i)[source]¶
- Return \(f_i\) of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,1)) sage: G = GelfandTsetlinPatterns(4, 1) sage: def phi(x): return G(x.to_tableau()) sage: def phi_inv(x): return D(G(x).to_tableau()) sage: I = crystals.Induced(D, phi, phi_inv, from_crystal=True) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: elt.f(1) [[1, 1, 0, 0], [1, 1, 0], [1, 0], [0]] sage: elt.f(2) sage: elt.f(3) [[1, 1, 0, 0], [1, 0, 0], [1, 0], [1]] - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(1))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(1)) >>> def phi(x): return G(x.to_tableau()) >>> def phi_inv(x): return D(G(x).to_tableau()) >>> I = crystals.Induced(D, phi, phi_inv, from_crystal=True) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> elt.f(Integer(1)) [[1, 1, 0, 0], [1, 1, 0], [1, 0], [0]] >>> elt.f(Integer(2)) >>> elt.f(Integer(3)) [[1, 1, 0, 0], [1, 0, 0], [1, 0], [1]] 
 - phi(i)[source]¶
- Return \(\varphi_i\) of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,1)) sage: G = GelfandTsetlinPatterns(4, 1) sage: def phi(x): return G(x.to_tableau()) sage: def phi_inv(x): return D(G(x).to_tableau()) sage: I = crystals.Induced(D, phi, phi_inv, from_crystal=True) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: [elt.epsilon(i) for i in I.index_set()] [0, 1, 0] - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(1))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(1)) >>> def phi(x): return G(x.to_tableau()) >>> def phi_inv(x): return D(G(x).to_tableau()) >>> I = crystals.Induced(D, phi, phi_inv, from_crystal=True) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> [elt.epsilon(i) for i in I.index_set()] [0, 1, 0] 
 - weight()[source]¶
- Return the weight of - self.- EXAMPLES: - sage: D = crystals.Tableaux(['A',3], shapes=PartitionsInBox(4,1)) sage: G = GelfandTsetlinPatterns(4, 1) sage: def phi(x): return G(x.to_tableau()) sage: def phi_inv(x): return D(G(x).to_tableau()) sage: I = crystals.Induced(D, phi, phi_inv, from_crystal=True) sage: elt = I([[1, 1, 0, 0], [1, 1, 0], [1, 0], [1]]) sage: elt.weight() (1, 0, 1, 0) - >>> from sage.all import * >>> D = crystals.Tableaux(['A',Integer(3)], shapes=PartitionsInBox(Integer(4),Integer(1))) >>> G = GelfandTsetlinPatterns(Integer(4), Integer(1)) >>> def phi(x): return G(x.to_tableau()) >>> def phi_inv(x): return D(G(x).to_tableau()) >>> I = crystals.Induced(D, phi, phi_inv, from_crystal=True) >>> elt = I([[Integer(1), Integer(1), Integer(0), Integer(0)], [Integer(1), Integer(1), Integer(0)], [Integer(1), Integer(0)], [Integer(1)]]) >>> elt.weight() (1, 0, 1, 0) 
 
 - cardinality()[source]¶
- Return the cardinality of - self.- EXAMPLES: - sage: C = crystals.Tableaux(['A',3], shape=[2,1]) sage: def psi(x): ....: ret = RSK_inverse(x.to_tableau(), Tableau([[1,1],[2]])) ....: return (tuple(ret[0]), tuple(ret[1])) sage: psi_inv = lambda x: C(RSK(*x)[0]) sage: I = crystals.Induced(C, psi, psi_inv, from_crystal=True) sage: I.cardinality() == C.cardinality() True - >>> from sage.all import * >>> C = crystals.Tableaux(['A',Integer(3)], shape=[Integer(2),Integer(1)]) >>> def psi(x): ... ret = RSK_inverse(x.to_tableau(), Tableau([[Integer(1),Integer(1)],[Integer(2)]])) ... return (tuple(ret[Integer(0)]), tuple(ret[Integer(1)])) >>> psi_inv = lambda x: C(RSK(*x)[Integer(0)]) >>> I = crystals.Induced(C, psi, psi_inv, from_crystal=True) >>> I.cardinality() == C.cardinality() True