AUTHORS:
Special thanks to: Nicolas Borie, Anne Schilling, Travis Scrimshaw, and Nicolas Thiery.
Bases: sage.structure.unique_representation.UniqueRepresentation, sage.structure.parent.Parent
Crystal of alcove paths generated from a “straight-line” path to the negative of a given dominant weight.
INPUT:
cartan_type – Cartan type of a finite or affine untwisted root system.
weight – dominant weight as a list of (integral) coefficients of the fundamental weights.
highest_weight_crystal – (Default: True) If True
returns the highest weight crystal. If False returns an
object which is close to being isomorphic to the tensor product
of Kirillov-Reshetikhin crystals of column shape in the
following sense: We get all the vertices, but only some of the
edges. We’ll call the included edges pseudo-Demazure. They are
all non-zero edges and the 0-edges not at the end of a 0-string
of edges, i.e. not those with with
. (Whereas Demazure 0-edges are those that
are not at the beginning of a zero string) In this case the
weight
represents
.
Note
If highest_weight_crystal = False, since we do not get the full crystal, TestSuite will fail on the Stembridge axioms.
See also
EXAMPLES:
The following example appears in Figure 2 of [LP2008]:
sage: C = CrystalOfAlcovePaths(['G',2],[0,1])
sage: G = C.digraph()
sage: GG = DiGraph({
... () : {(0) : 2 },
... (0) : {(0,8) : 1 },
... (0,1) : {(0,1,7) : 2 },
... (0,1,2) : {(0,1,2,9) : 1 },
... (0,1,2,3) : {(0,1,2,3,4) : 2 },
... (0,1,2,6) : {(0,1,2,3) : 1 },
... (0,1,2,9) : {(0,1,2,6) : 1 },
... (0,1,7) : {(0,1,2) : 2 },
... (0,1,7,9) : {(0,1,2,9) : 2 },
... (0,5) : {(0,1) : 1, (0,5,7) : 2 },
... (0,5,7) : {(0,5,7,9) : 1 },
... (0,5,7,9) : {(0,1,7,9) : 1 },
... (0,8) : {(0,5) : 1 },
... })
sage: G.is_isomorphic(GG)
True
sage: for (u,v,i) in G.edges(): print (u.integer_sequence() , v.integer_sequence(), i)
([], [0], 2)
([0], [0, 8], 1)
([0, 1], [0, 1, 7], 2)
([0, 1, 2], [0, 1, 2, 9], 1)
([0, 1, 2, 3], [0, 1, 2, 3, 4], 2)
([0, 1, 2, 6], [0, 1, 2, 3], 1)
([0, 1, 2, 9], [0, 1, 2, 6], 1)
([0, 1, 7], [0, 1, 2], 2)
([0, 1, 7, 9], [0, 1, 2, 9], 2)
([0, 5], [0, 1], 1)
([0, 5], [0, 5, 7], 2)
([0, 5, 7], [0, 5, 7, 9], 1)
([0, 5, 7, 9], [0, 1, 7, 9], 1)
([0, 8], [0, 5], 1)
Alcove path crystals are a discrete version of Littelmann paths. We verify that the alcove path crystal is isomorphic to the LS path crystal:
sage: C1 = CrystalOfAlcovePaths(['C',3],[2,1,0])
sage: g1 = C1.digraph() #long time
sage: C2 = CrystalOfLSPaths(['C',3],[2,1,0])
sage: g2 = C2.digraph() #long time
sage: g1.is_isomorphic(g2, edge_labels=True) #long time
True
The preferred initialization method is via explicit weights rather than a Cartan type and the coefficients of the fundamental weights:
sage: R = RootSystem(['C',3])
sage: P = R.weight_lattice()
sage: La = P.fundamental_weights()
sage: C = CrystalOfAlcovePaths(2*La[1]+La[2]); C
Highest weight crystal of alcove paths of type ['C', 3] and weight 2*Lambda[1] + Lambda[2]
sage: C1==C
True
We now explain the data structure:
sage: C = CrystalOfAlcovePaths(['A',2],[2,0]) ; C
Highest weight crystal of alcove paths of type ['A', 2] and weight 2*Lambda[1]
sage: C._R.lambda_chain()
[(alpha[1], 0), (alpha[1] + alpha[2], 0), (alpha[1], 1), (alpha[1] + alpha[2], 1)]
The previous list gives the initial “straight line” path from the
fundamental alcove to its translation
where
in this example. The initial path for weight
is called the
-chain. This path is constructed from
the ordered pairs
, by crossing the hyperplane orthogonal to
at height
. We can view a plot of this path as follows:
sage: x=C( () )
sage: x.plot() # not tested - outputs a pdf
An element of the crystal is given by a subset of the -chain.
This subset indicates the hyperplanes where the initial path should be
folded. The highest weight element is given by the empty subset.
sage: x
()
sage: x.f(1).f(2)
((alpha[1], 1), (alpha[1] + alpha[2], 1))
sage: x.f(1).f(2).integer_sequence()
[2, 3]
sage: C([2,3])
((alpha[1], 1), (alpha[1] + alpha[2], 1))
sage: C([2,3]).is_admissible() #check if a valid vertex
True
sage: C([1,3]).is_admissible() #check if a valid vertex
False
Alcove path crystals now works in affine type (trac ticket #14143):
sage: C = CrystalOfAlcovePaths(['A',2,1],[1,0,0]) ; C
Highest weight crystal of alcove paths of type ['A', 2, 1] and weight Lambda[0]
sage: x=C( () )
sage: x.f(0)
((alpha[0], 0),)
sage: C.R
Root system of type ['A', 2, 1]
sage: C.weight
Lambda[0]
Test that the tensor products of Kirillov-Reshetikhin crystals minus non-pseudo-Demazure arrows is in bijection with alcove path construction:
sage: K = KirillovReshetikhinCrystal(['B',3,1],2,1)
sage: T = TensorProductOfCrystals(K,K)
sage: g = T.digraph() #long time
sage: for e in g.edges(): #long time
....: if e[0].phi(0) == 1 and e[2] == 0: #long time
....: g.delete_edge(e) #long time
sage: C = CrystalOfAlcovePaths(['B',3,1],[0,2,0], highest_weight_crystal=False)
sage: g2 = C.digraph_fast() #long time
sage: g.is_isomorphic(g2, edge_labels = True) #long time
True
Note
In type , the Kirillov-Reshetikhin crystal is not connected
when restricted to pseudo-Demazure arrows, hence the previous example will
fail for type
crystals.
sage: R = RootSystem(['B',3])
sage: P = R.weight_lattice()
sage: La = P.fundamental_weights()
sage: D = CrystalOfAlcovePaths(2*La[2], highest_weight_crystal=False)
sage: C == D
True
Warning
Weights from finite root systems index non-highest weight crystals.
REFERENCES:
[LP2008] | C. Lenart and A. Postnikov. A combinatorial model for crystals of Kac-Moody algebras. Trans. Amer. Math. Soc. 360 (2008), 4349-4381. |
alias of CrystalOfAlcovePathsElement
Return the crystal graph with maximum depth depth deep starting at the module generator. Significant speed up for highest_weight_crystals of affine type.
EXAMPLES:
sage: CrystalOfAlcovePaths(['A',2], [1,1]).digraph_fast(depth=3)
Digraph on 7 vertices
TESTS:
The following example demonstrates the speed improvement. The speedup in non-affine types is small however:
sage: cartan_type = ['A',2,1] #long time
sage: weight = [1,1,0] #long time
sage: depth = 5 #long time
sage: C = CrystalOfAlcovePaths(cartan_type, weight) #long time
sage: %timeit C.digraph_fast(depth) # not tested
10 loops, best of 3: 171 ms per loop
sage: %timeit C.digraph(subset=C.subcrystal(max_depth=depth, direction='lower')) #not tested
1 loops, best of 3: 19.7 s per loop
sage: G1 = C.digraph_fast(depth) #long time
sage: G2 = C.digraph(subset=C.subcrystal(max_depth=depth, direction='lower')) #long time
sage: G1.is_isomorphic(G2, edge_labels=True) #long time
True
Return a list of all the vertices of the crystal.
The vertices are represented as lists of integers recording the folding positions.
One can compute all vertices of the crystal by finding all the
admissible subsets of the -chain (see method
is_admissible, for definition). We use the breath first
search algorithm.
Warning
This method is (currently) only useful for the case when highest_weight_crystal = False, where you cannot always reach all vertices of the crystal using crystal operators, starting from the highest weight vertex. This method is typically slower than generating the crystal graph using crystal operators.
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['C',2],[1,0])
sage: C.vertices()
[[], [0], [0, 1], [0, 1, 2]]
sage: C = CrystalOfAlcovePaths(['C',2,1],[2,1],False)
sage: len(C.vertices())
80
The number of elements reachable using the crystal operators from the module generator:
sage: len(list(C))
55
Bases: sage.structure.element_wrapper.ElementWrapper
Crystal of alcove paths element.
INPUT:
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['A',2],[3,2])
sage: x = C ( () )
sage: x.f(1).f(2)
((alpha[1], 2), (alpha[1] + alpha[2], 4))
sage: x.f(1).f(2).integer_sequence()
[8, 9]
sage: C([8,9])
((alpha[1], 2), (alpha[1] + alpha[2], 4))
Return the -th crystal raising operator on self.
INPUT:
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['A',2],[2,0]); C
Highest weight crystal of alcove paths of type ['A', 2] and weight 2*Lambda[1]
sage: x = C( () )
sage: x.e(1)
sage: x.f(1) == x.f(1).f(2).e(2)
True
Return the distance to the start of the -string.
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['A',2],[1,1])
sage: [c.epsilon(1) for c in C]
[0, 0, 1, 1, 0, 2, 0, 1]
sage: [c.epsilon(2) for c in C]
[0, 1, 0, 0, 1, 0, 2, 1]
Returns the -th crystal lowering operator on self.
INPUT:
EXAMPLES:
sage: C=CrystalOfAlcovePaths(['B',2],[1,1])
sage: x=C( () )
sage: x.f(1)
((alpha[1], 0),)
sage: x.f(1).f(2)
((alpha[1], 0), (alpha[1] + alpha[2], 2))
Return a list of integers corresponding to positions in
the -chain where it is folded.
Todo
Incorporate this method into the _repr_ for finite Cartan type.
Note
Only works for finite Cartan types and indexing starts at 0.
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['A',2],[3,2])
sage: x = C( () )
sage: x.f(1).f(2).integer_sequence()
[8, 9]
Diagnostic test to check if self is a valid element of the crystal.
If self.value is given by
for highest weight crystals this checks if the sequence
is a path in the Bruhat graph. If highest_weight_crystal=False, then the method checks if the above sequence is a path in the quantum Bruhat graph.
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['A',2],[1,1]); C
Highest weight crystal of alcove paths of type ['A', 2] and weight Lambda[1] + Lambda[2]
sage: roots = sorted(list(C._R._root_lattice.positive_roots())); roots
[alpha[1], alpha[1] + alpha[2], alpha[2]]
sage: r1 = C._R(roots[0],0); r1
(alpha[1], 0)
sage: r2 = C._R(roots[2],0); r2
(alpha[2], 0)
sage: r3 = C._R(roots[1],1); r3
(alpha[1] + alpha[2], 1)
sage: x = C( ( r1,r2) )
sage: x.is_admissible()
True
sage: x = C( (r3,) ); x
((alpha[1] + alpha[2], 1),)
sage: x.is_admissible()
False
sage: C = CrystalOfAlcovePaths(['C',2,1],[2,1],False)
sage: C([7,8]).is_admissible()
True
sage: C = CrystalOfAlcovePaths(['A',2],[3,2])
sage: C([2,3]).is_admissible()
True
Todo
Better doctest
Return the distance to the end of the -string.
This method overrides the generic implementation in the category of crystals since this computation is more efficient.
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['A',2],[1,1])
sage: [c.phi(1) for c in C]
[1, 2, 0, 1, 0, 0, 1, 0]
sage: [c.phi(2) for c in C]
[1, 0, 2, 0, 1, 1, 0, 0]
Return a plot self.
Note
Currently only implemented for types ,
, and
.
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['A',2],[2,0])
sage: x = C( () ).f(1).f(2)
sage: x.plot() # Not tested - creates a pdf
Returns the weight of self.
EXAMPLES:
sage: C = CrystalOfAlcovePaths(['A',2],[2,0])
sage: for i in C: i.weight()
2*Lambda[1]
Lambda[2]
Lambda[1] - Lambda[2]
-2*Lambda[1] + 2*Lambda[2]
-Lambda[1]
-2*Lambda[2]
Bases: sage.structure.unique_representation.UniqueRepresentation, sage.structure.parent.Parent
Data structure of the ordered pairs ,
where
is a positive root and
is a non-negative integer. A total
order is implemented on this set, and depends on the weight.
INPUT:
EXAMPLES:
sage: from sage.combinat.crystals.alcove_path import RootsWithHeight
sage: R = RootsWithHeight(['A',2],[1,1]); R
Roots with height of cartan type ['A', 2] and dominant weight Lambda[1] + Lambda[2]
sage: r1 = R._root_lattice.from_vector(vector([1,0])); r1
alpha[1]
sage: r2 = R._root_lattice.from_vector(vector([1,1])); r2
alpha[1] + alpha[2]
sage: x = R(r1,0); x
(alpha[1], 0)
sage: y = R(r2,1); y
(alpha[1] + alpha[2], 1)
sage: x < y
True
alias of RootsWithHeightElement
Return the unfolded -chain.
Note
Only works in root systems of finite type.
EXAMPLES:
sage: from sage.combinat.crystals.alcove_path import RootsWithHeight
sage: R = RootsWithHeight(['A',2],[1,1]); R
Roots with height of cartan type ['A', 2] and dominant weight Lambda[1] + Lambda[2]
sage: R.lambda_chain()
[(alpha[2], 0), (alpha[1] + alpha[2], 0), (alpha[1], 0), (alpha[1] + alpha[2], 1)]
Gives the initial alcove path (-chain) in terms of simple
roots. Used for plotting the path.
Note
Currently only implemented for finite Cartan types.
EXAMPLES:
sage: from sage.combinat.crystals.alcove_path import RootsWithHeight
sage: R = RootsWithHeight(['A',2],[3,2])
sage: R.word()
[2, 1, 2, 0, 1, 2, 1, 0, 1, 2]
Bases: sage.structure.element.Element
Element of RootsWithHeight.
INPUT:
EXAMPLES:
sage: from sage.combinat.crystals.alcove_path import RootsWithHeight
sage: rl = RootSystem(['A',2]).root_lattice()
sage: x = rl.from_vector(vector([1,1])); x
alpha[1] + alpha[2]
sage: R = RootsWithHeight(['A',2],[1,1]); R
Roots with height of cartan type ['A', 2] and dominant weight Lambda[1] + Lambda[2]
sage: y = R(x, 1); y
(alpha[1] + alpha[2], 1)
Compare two edge-labeled graphs obtained from Crystal.digraph(), starting from the root nodes of each graph.
Traverse g1 starting at node1 and compare this graph with the one obtained by traversing g2 starting with node2. If the graphs match (including labels) then return True. Return False otherwise.
EXAMPLES:
sage: from sage.combinat.crystals.alcove_path import compare_graphs
sage: G1 = sage.combinat.crystals.all.CrystalOfTableaux(['A',3], shape=[1,1]).digraph()
sage: C = CrystalOfAlcovePaths(['A',3],[0,1,0])
sage: G2 = C.digraph()
sage: compare_graphs(G1, G2, C( () ), G2.vertices()[0])
True