AUTHORS:
Bases: sage.structure.unique_representation.UniqueRepresentation, sage.structure.parent.Parent
Crystal graph of LS paths generated from the straight-line path to a given weight.
INPUT:
The crystal class of piecewise linear paths in the weight space, generated from a straight-line path from the origin to a given element of the weight lattice.
OUTPUT:
EXAMPLES:
sage: R = RootSystem(['A',2,1])
sage: La = R.weight_space(extended = True).basis()
sage: B = crystals.LSPaths(La[2]-La[0]); B
The crystal of LS paths of type ['A', 2, 1] and weight -Lambda[0] + Lambda[2]
sage: C = crystals.LSPaths(['A',2,1],[-1,0,1]); C
The crystal of LS paths of type ['A', 2, 1] and weight -Lambda[0] + Lambda[2]
sage: B == C
True
sage: c = C.module_generators[0]; c
(-Lambda[0] + Lambda[2],)
sage: [c.f(i) for i in C.index_set()]
[None, None, (Lambda[1] - Lambda[2],)]
sage: R = C.R; R
Root system of type ['A', 2, 1]
sage: Lambda = R.weight_space().basis(); Lambda
Finite family {0: Lambda[0], 1: Lambda[1], 2: Lambda[2]}
sage: b=C(tuple([-Lambda[0]+Lambda[2]]))
sage: b==c
True
sage: b.f(2)
(Lambda[1] - Lambda[2],)
For classical highest weight crystals we can also compare the results with the tableaux implementation:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: sorted(C, key=str)
[(-2*Lambda[1] + Lambda[2],), (-Lambda[1] + 1/2*Lambda[2], Lambda[1] - 1/2*Lambda[2]),
(-Lambda[1] + 2*Lambda[2],), (-Lambda[1] - Lambda[2],),
(1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2]), (2*Lambda[1] - Lambda[2],),
(Lambda[1] + Lambda[2],), (Lambda[1] - 2*Lambda[2],)]
sage: C.cardinality()
8
sage: B = crystals.Tableaux(['A',2],shape=[2,1])
sage: B.cardinality()
8
sage: B.digraph().is_isomorphic(C.digraph())
True
Make sure you use the weight space and not the weight lattice for your weights:
sage: R = RootSystem(['A',2,1])
sage: La = R.weight_lattice(extended = True).basis()
sage: B = crystals.LSPaths(La[2]); B
Traceback (most recent call last):
...
ValueError: Please use the weight space, rather than weight lattice for your weights
REFERENCES:
[Littelmann95] | P. Littelmann, Paths and root operators in representation theory. Ann. of Math. (2) 142 (1995), no. 3, 499-525. |
Bases: sage.structure.element_wrapper.ElementWrapper
TESTS:
sage: C = crystals.LSPaths(['E',6],[1,0,0,0,0,0])
sage: c=C.an_element()
sage: TestSuite(c).run()
Merges consecutive positively parallel steps present in the path.
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: Lambda = C.R.weight_space().fundamental_weights(); Lambda
Finite family {1: Lambda[1], 2: Lambda[2]}
sage: c = C(tuple([1/2*Lambda[1]+1/2*Lambda[2], 1/2*Lambda[1]+1/2*Lambda[2]]))
sage: c.compress()
(Lambda[1] + Lambda[2],)
Returns dualized path.
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: for c in C:
... print c, c.dualize()
...
(Lambda[1] + Lambda[2],) (-Lambda[1] - Lambda[2],)
(-Lambda[1] + 2*Lambda[2],) (Lambda[1] - 2*Lambda[2],)
(1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2]) (1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2])
(Lambda[1] - 2*Lambda[2],) (-Lambda[1] + 2*Lambda[2],)
(-Lambda[1] - Lambda[2],) (Lambda[1] + Lambda[2],)
(2*Lambda[1] - Lambda[2],) (-2*Lambda[1] + Lambda[2],)
(-Lambda[1] + 1/2*Lambda[2], Lambda[1] - 1/2*Lambda[2]) (-Lambda[1] + 1/2*Lambda[2], Lambda[1] - 1/2*Lambda[2])
(-2*Lambda[1] + Lambda[2],) (2*Lambda[1] - Lambda[2],)
Returns the -th crystal raising operator on self.
INPUT:
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: c = C[2]; c
(1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2])
sage: c.e(1)
sage: c.e(2)
(-Lambda[1] + 2*Lambda[2],)
sage: c.e(2,to_string_end=True)
(-Lambda[1] + 2*Lambda[2],)
sage: c.e(1,to_string_end=True)
(1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2])
sage: c.e(1,length_only=True)
0
Computes the endpoint of the path.
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: b = C.module_generators[0]
sage: b.endpoint()
Lambda[1] + Lambda[2]
sage: b.f_string([1,2,2,1])
(-Lambda[1] - Lambda[2],)
sage: b.f_string([1,2,2,1]).endpoint()
-Lambda[1] - Lambda[2]
sage: b.f_string([1,2])
(1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2])
sage: b.f_string([1,2]).endpoint()
0
sage: b = C([])
sage: b.endpoint()
0
Returns the distance to the beginning of the -string.
This method overrides the generic implementation in the category of crystals since this computation is more efficient.
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: [c.epsilon(1) for c in C]
[0, 1, 0, 0, 1, 0, 1, 2]
sage: [c.epsilon(2) for c in C]
[0, 0, 1, 2, 1, 1, 0, 0]
Returns the -th crystal lowering operator on self.
INPUT:
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: c = C.module_generators[0]
sage: c.f(1)
(-Lambda[1] + 2*Lambda[2],)
sage: c.f(1,power=2)
sage: c.f(2)
(2*Lambda[1] - Lambda[2],)
sage: c.f(2,to_string_end=True)
(2*Lambda[1] - Lambda[2],)
sage: c.f(2,length_only=True)
1
sage: C = crystals.LSPaths(['A',2,1],[-1,-1,2])
sage: c = C.module_generators[0]
sage: c.f(2,power=2)
(Lambda[0] + Lambda[1] - 2*Lambda[2],)
Returns 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 = crystals.LSPaths(['A',2],[1,1])
sage: [c.phi(1) for c in C]
[1, 0, 0, 1, 0, 2, 1, 0]
sage: [c.phi(2) for c in C]
[1, 2, 1, 0, 0, 0, 0, 1]
Apply the -th simple reflection to the indicated step in self.
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: b = C.module_generators[0]
sage: b.reflect_step(0,1)
(-Lambda[1] + 2*Lambda[2],)
sage: b.reflect_step(0,2)
(2*Lambda[1] - Lambda[2],)
Computes the reflection of self along the -string.
This method is more efficient than the generic implementation since it uses
powers of and
in the Littelmann model directly.
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: c = C.module_generators[0]
sage: c.s(1)
(-Lambda[1] + 2*Lambda[2],)
sage: c.s(2)
(2*Lambda[1] - Lambda[2],)
sage: C = crystals.LSPaths(['A',2,1],[-1,0,1])
sage: c = C.module_generators[0]; c
(-Lambda[0] + Lambda[2],)
sage: c.s(2)
(Lambda[1] - Lambda[2],)
sage: c.s(1)
(-Lambda[0] + Lambda[2],)
sage: c.f(2).s(1)
(Lambda[0] - Lambda[1],)
Splits indicated step into two parallel steps of relative lengths and
.
INPUT:
EXAMPLES:
sage: C = crystals.LSPaths(['A',2],[1,1])
sage: b = C.module_generators[0]
sage: b.split_step(0,1/3)
(1/3*Lambda[1] + 1/3*Lambda[2], 2/3*Lambda[1] + 2/3*Lambda[2])
Bases: sage.combinat.crystals.littelmann_path.CrystalOfLSPaths
Crystal of projected level zero LS paths.
INPUT:
When weight is just a single fundamental weight , this crystal is
isomorphic to a Kirillov-Reshetikhin (KR) crystal, see also
sage.combinat.crystals.kirillov_reshetikhin.crystals.KirillovReshetikhinFromLSPaths().
For general weights, it is isomorphic to a tensor product of single-column KR crystals.
EXAMPLES:
sage: R = RootSystem(['C',3,1])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[3])
sage: LS.cardinality()
84
sage: GLS = LS.digraph()
sage: K1 = crystals.KirillovReshetikhin(['C',3,1],1,1)
sage: K3 = crystals.KirillovReshetikhin(['C',3,1],3,1)
sage: T = crystals.TensorProduct(K3,K1)
sage: T.cardinality()
84
sage: GT = T.digraph() # long time
sage: GLS.is_isomorphic(GT, edge_labels = True) # long time
True
TESTS:
sage: ct = CartanType(['A',4,2]).dual()
sage: P = RootSystem(ct).weight_space()
sage: La = P.fundamental_weights()
sage: C = crystals.ProjectedLevelZeroLSPaths(La[1])
sage: sorted(C, key=str)
[(-Lambda[0] + Lambda[1],),
(-Lambda[1] + 2*Lambda[2],),
(1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2]),
(Lambda[0] - Lambda[1],),
(Lambda[1] - 2*Lambda[2],)]
Bases: sage.combinat.crystals.littelmann_path.CrystalOfLSPaths.Element
Element of a crystal of projected level zero LS paths.
Return the energy function of self.
The energy function of the level zero LS path
requires a series of definitions; for simplicity the root system is assumed to be untwisted affine.
The LS path is a piecewise linear map from the unit interval
to the weight lattice.
It is specified by “times”
and “direction vectors”
where
for
, and
is the
stabilizer of
in the finite Weyl group
. Precisely,
for and
.
For any let
be a shortest directed path in the parabolic quantum Bruhat graph. Define
It can be shown that depends only on
;
call its value
. The energy function
is defined by
For more information, see [LNSSS2013].
REFERENCES:
[LNSSS2013] | (1, 2) C. Lenart, S. Naito, D. Sagaki, A. Schilling, M. Shimozono, A uniform model for Kirillov-Reshetikhin crystals. Extended abstract. DMTCS proc, to appear ( {{{Arxiv 1211.6019}}} ) |
Note
In the dual-of-untwisted case the parabolic quantum Bruhat graph that is used is obtained by
exchanging the roles of roots and coroots. Moreover, in the computation of the
pairing the short roots must be doubled (or tripled for type ). This factor
is determined by the translation factor of the corresponding root.
Type
is viewed as untwisted type, whereas the dual of
is viewed as twisted.
Except for the untwisted cases, these formulas are currently still conjectural.
EXAMPLES:
sage: R = RootSystem(['C',3,1])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[3])
sage: b = LS.module_generators[0]
sage: c = b.f(1).f(3).f(2)
sage: c.energy_function()
0
sage: c=b.e(0)
sage: c.energy_function()
1
sage: R = RootSystem(['A',2,1])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1])
sage: b = LS.module_generators[0]
sage: c = b.e(0)
sage: c.energy_function()
1
sage: for c in sorted(LS, key=str): print c,c.energy_function()
(-2*Lambda[0] + 2*Lambda[1],) 0
(-2*Lambda[1] + 2*Lambda[2],) 0
(-Lambda[0] + Lambda[1], -Lambda[1] + Lambda[2]) 1
(-Lambda[0] + Lambda[1], Lambda[0] - Lambda[2]) 1
(-Lambda[1] + Lambda[2], -Lambda[0] + Lambda[1]) 0
(-Lambda[1] + Lambda[2], Lambda[0] - Lambda[2]) 1
(2*Lambda[0] - 2*Lambda[2],) 0
(Lambda[0] - Lambda[2], -Lambda[0] + Lambda[1]) 0
(Lambda[0] - Lambda[2], -Lambda[1] + Lambda[2]) 0
The next test checks that the energy function is constant on classically connected components:
sage: R = RootSystem(['A',2,1])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1]+La[2])
sage: G = LS.digraph(index_set=[1,2])
sage: C = G.connected_components()
sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C]
[True, True, True, True]
sage: R = RootSystem(['D',4,2])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[2])
sage: J = R.cartan_type().classical().index_set()
sage: hw = [x for x in LS if x.is_highest_weight(J)]
sage: [(x.weight(), x.energy_function()) for x in hw]
[(-2*Lambda[0] + Lambda[2], 0), (-2*Lambda[0] + Lambda[1], 1), (0, 2)]
sage: G = LS.digraph(index_set=J)
sage: C = G.connected_components()
sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C]
[True, True, True]
sage: R = RootSystem(CartanType(['G',2,1]).dual())
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[2])
sage: G = LS.digraph(index_set=[1,2])
sage: C = G.connected_components()
sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] # long time
[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
sage: ct = CartanType(['BC',2,2]).dual()
sage: R = RootSystem(ct)
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1]+La[2])
sage: G = LS.digraph(index_set=R.cartan_type().classical().index_set())
sage: C = G.connected_components()
sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] # long time
[True, True, True, True, True, True, True, True, True, True, True]
sage: R = RootSystem(['BC',2,2])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1]+La[2])
sage: G = LS.digraph(index_set=R.cartan_type().classical().index_set())
sage: C = G.connected_components()
sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] # long time
[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
Obtain the scalar factors for self.
Each LS path (or self) can be written as a piecewise linear map
for and
and
.
This method returns the tuple of
.
EXAMPLES:
sage: R = RootSystem(['C',3,1])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[3])
sage: b = LS.module_generators[0]
sage: b.scalar_factors()
[1]
sage: c = b.f(1).f(3).f(2)
sage: c.scalar_factors()
[1/3, 1]
Transforms the weights in the LS path self to elements in the Weyl group.
Each LS path can be written as the piecewise linear map:
for and
and
.
Each weight
is also associated to a Weyl group element. This method returns the list
of Weyl group elements associated to the
for
.
EXAMPLES:
sage: R = RootSystem(['C',3,1])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[3])
sage: b = LS.module_generators[0]
sage: c = b.f(1).f(3).f(2)
sage: c.weyl_group_representation()
[s2*s3*s1, s3*s1]
Checks whether the crystal self is perfect (of level level).
INPUT:
A crystal is perfect of level
if:
Points (1)-(3) are known to hold. This method checks points (4) and (5).
EXAMPLES:
sage: C = CartanType(['C',2,1])
sage: R = RootSystem(C)
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1])
sage: LS.is_perfect()
False
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[2])
sage: LS.is_perfect()
True
sage: C = CartanType(['E',6,1])
sage: R = RootSystem(C)
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1])
sage: LS.is_perfect()
True
sage: LS.is_perfect(2)
False
sage: C = CartanType(['D',4,1])
sage: R = RootSystem(C)
sage: La = R.weight_space().basis()
sage: all(crystals.ProjectedLevelZeroLSPaths(La[i]).is_perfect() for i in [1,2,3,4])
True
sage: C = CartanType(['A',6,2])
sage: R = RootSystem(C)
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[2])
sage: LS.is_perfect()
True
sage: LS.is_perfect(2)
False
Compute the one-dimensional configuration sum.
INPUT:
The one-dimensional configuration sum is the sum of the weights of all elements in the crystal weighted by the energy function. For untwisted types it uses the parabolic quantum Bruhat graph, see [LNSSS2013]. In the dual-of-untwisted case, the parabolic quantum Bruhat graph is defined by exchanging the roles of roots and coroots (which is still conjectural at this point).
EXAMPLES:
sage: R = RootSystem(['A',2,1])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1])
sage: LS.one_dimensional_configuration_sum() # long time
B[-2*Lambda[1] + 2*Lambda[2]] + (q+1)*B[-Lambda[1]]
+ (q+1)*B[Lambda[1] - Lambda[2]] + B[2*Lambda[1]] + B[-2*Lambda[2]] + (q+1)*B[Lambda[2]]
sage: R.<t> = ZZ[]
sage: LS.one_dimensional_configuration_sum(t, False) # long time
B[-2*Lambda[1] + 2*Lambda[2]] + (t+1)*B[-Lambda[1]] + (t+1)*B[Lambda[1] - Lambda[2]]
+ B[2*Lambda[1]] + B[-2*Lambda[2]] + (t+1)*B[Lambda[2]]
TESTS:
sage: R = RootSystem(['B',3,1])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[2])
sage: LS.one_dimensional_configuration_sum() == LS.one_dimensional_configuration_sum(group_components=False) # long time
True
sage: K1 = crystals.KirillovReshetikhin(['B',3,1],1,1)
sage: K2 = crystals.KirillovReshetikhin(['B',3,1],2,1)
sage: T = crystals.TensorProduct(K2,K1)
sage: T.one_dimensional_configuration_sum() == LS.one_dimensional_configuration_sum() # long time
True
sage: R = RootSystem(['D',4,2])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[2])
sage: K1 = crystals.KirillovReshetikhin(['D',4,2],1,1)
sage: K2 = crystals.KirillovReshetikhin(['D',4,2],2,1)
sage: T = crystals.TensorProduct(K2,K1)
sage: T.one_dimensional_configuration_sum() == LS.one_dimensional_configuration_sum() # long time
True
sage: R = RootSystem(['A',5,2])
sage: La = R.weight_space().basis()
sage: LS = crystals.ProjectedLevelZeroLSPaths(3*La[1])
sage: K1 = crystals.KirillovReshetikhin(['A',5,2],1,1)
sage: T = crystals.TensorProduct(K1,K1,K1)
sage: T.one_dimensional_configuration_sum() == LS.one_dimensional_configuration_sum() # long time
True