From 365b5201a63a1d03ee2e0669fb6e82661f2bc2f3 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 20 Dec 2013 22:47:41 -0800 Subject: [PATCH 01/16] Added methods to RC's. --- .../rigged_configurations/bij_type_B.py | 2 +- .../rigged_configuration_element.py | 101 ++++++++++++++++-- 2 files changed, 93 insertions(+), 10 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index ab436141679..db7334ab9e3 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -580,7 +580,7 @@ def run(self, verbose=False): self.cur_partitions[-1].rigging, self.cur_partitions[-1].vacancy_numbers) - bij = RCToKRTBijectionTypeA2Odd(RC(*self.cur_partitions)) + bij = RCToKRTBijectionTypeA2Odd(RC(*self.cur_partitions, use_vacancy_numbers=True)) for i in range(len(self.cur_dims)): if bij.cur_dims[i][0] != self.n: bij.cur_dims[i][1] *= 2 diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 9b5d7c4c868..6eb853c5cda 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -226,15 +226,17 @@ def __init__(self, parent, rigged_partitions=[], **options): for partition_data in data: nu.append(RiggedPartition(tuple(partition_data))) elif parent._cartan_type.classical().rank() == len(rigged_partitions) and \ - isinstance(rigged_partitions[0], RiggedPartition): - # The isinstance check is to make sure we are not in the n == 1 special case because - # Parent's __call__ always passes at least 1 argument to the element constructor - - # Special display case - if parent.cartan_type().type() == 'B': - rigged_partitions[-1] = RiggedPartitionTypeB(rigged_partitions[-1]) - ClonableArray.__init__(self, parent, rigged_partitions) - return + isinstance(rigged_partitions[0], RiggedPartition): + if options.get('use_vacancy_numbers', False): + # The isinstance check is to make sure we are not in the n == 1 special case because + # Parent's __call__ always passes at least 1 argument to the element constructor + + # Special display case + if parent.cartan_type().type() == 'B': + rigged_partitions[-1] = RiggedPartitionTypeB(rigged_partitions[-1]) + ClonableArray.__init__(self, parent, rigged_partitions) + return + nu = rigged_partitions else: # Otherwise we did not receive any info, create a size n array of # empty rigged partitions @@ -510,6 +512,87 @@ def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False kr_tab = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps) return kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals() + def left_split(self): + r""" + Return the image of ``self`` under the left column splitting + map `\beta`. + + Consider the map `\beta : RC(B^{r,s} \otimes B) \to RC(B^{r,1} + \otimes B^{r,s-1} \otimes B)` for `s > 1` which is a natural classical + crystal injection. On rigged configurations, the map `\beta` does + nothing (except possibly changing the vacancy numbers). + + EXAMPLES:: + + sage: RC = RiggedConfigurations(['C',4,1], [[3,3]]) + sage: mg = RC.module_generators[-1] + sage: ascii_art(mg) + 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ]0 + sage: ascii_art(mg.left_split()) + 0[ ][ ]0 0[ ][ ]0 1[ ][ ]0 0[ ]0 + 0[ ][ ]0 1[ ][ ]0 0[ ]0 + 1[ ][ ]0 0[ ]0 + """ + P = self.parent() + B = list(P.dims) + if B[0][1] == 1: + raise ValueError("cannot split a single column") + B[0] = (B[0][0], B[0][1] - 1) + B.insert(0, (B[0][0], 1)) + from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations + RC = RiggedConfigurations(P._cartan_type, B) + return RC(*self) + + def delta(self, return_b=False): + r""" + Return the image of ``self`` under the map basic map `\delta`. If the + left-most factor is not a single column, then this also performs a + :meth:`left_split()`. + + The map `\delta : RC(B^{r,1} \otimes B) \to RC(B^{r-1,1} + \otimes B)` (if `r = 1`, then we remove the left-most factor) is the + basic map in the bijection `\Phi` between rigged configurations and + tensor products of Kirillov-Reshetikhin tableaux. For more + information, see + :meth:`to_tensor_product_of_kirillov_reshetikhin_tableaux()`. + + INPUT: + + - ``return_b`` -- return the resulting letter from `\delta` + + EXAMPLES:: + + sage: RC = RiggedConfigurations(['C',4,1], [[3,2]]) + sage: mg = RC.module_generators[-1] + sage: ascii_art(mg) + 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ]0 + sage: ascii_art(mg.delta()) + 0[ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ]0 0[ ][ ]0 0[ ]0 + sage: x,b = mg.delta(True) + sage: b + -1 + """ + from sage.combinat.rigged_configurations.bijection import RCToKRTBijection + rc = self + if self.parent().dims[0][1] != 1: + rc = self.left_split() + bij = RCToKRTBijection(rc) + bij.cur_dims[0][0] -= 1 # This takes care of the indexing + b = bij.next_state(bij.cur_dims[0][0]) + if bij.cur_dims[0][0] == 0: + bij.cur_dims.pop(0) + from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations + RC = RiggedConfigurations(self.parent()._cartan_type, bij.cur_dims) + rc = RC(*bij.cur_partitions) + if return_b: + return (rc, b) + return rc + def nu(self): r""" Return the list `\nu` of rigged partitions of this rigged From 0050d2e4bbeb579248437feaaf363d210a92a83f Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 22 Dec 2013 12:39:48 -0800 Subject: [PATCH 02/16] Forbade spinor cases. --- .../rigged_configuration_element.py | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 6eb853c5cda..abdfb87dced 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -558,10 +558,21 @@ def delta(self, return_b=False): information, see :meth:`to_tensor_product_of_kirillov_reshetikhin_tableaux()`. + .. NOTE:: + + Due to the special nature of the bijection for the spinor cases in + types `D_n^{(1)}`, `B_n^{(1)}`, and `A_{2n-1}^{(2)}`, this map is + not defined in these cases. + INPUT: - ``return_b`` -- return the resulting letter from `\delta` + OUTPUT: + + The resulting rigged configuration or if ``return_b`` is ``True``, + then a tuple of the resulting rigged configuration and the letter. + EXAMPLES:: sage: RC = RiggedConfigurations(['C',4,1], [[3,2]]) @@ -577,9 +588,19 @@ def delta(self, return_b=False): sage: b -1 """ + # Don't do spinor cases + P = self.parent() + ct = P.cartan_type() + if ct.type() == 'D': + if P.dims[0][0] >= ct.rank() - 2: + raise ValueError("only for non-spinor cases") + elif ct.type() == 'B' or ct.dual().type() == 'B': + if P.dims[0][0] == ct.rank() - 1: + raise ValueError("only for non-spinor cases") + from sage.combinat.rigged_configurations.bijection import RCToKRTBijection rc = self - if self.parent().dims[0][1] != 1: + if P.dims[0][1] != 1: rc = self.left_split() bij = RCToKRTBijection(rc) bij.cur_dims[0][0] -= 1 # This takes care of the indexing @@ -587,7 +608,7 @@ def delta(self, return_b=False): if bij.cur_dims[0][0] == 0: bij.cur_dims.pop(0) from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations - RC = RiggedConfigurations(self.parent()._cartan_type, bij.cur_dims) + RC = RiggedConfigurations(ct, bij.cur_dims) rc = RC(*bij.cur_partitions) if return_b: return (rc, b) From 4695e88357ba2edac6f10127d8e4c7c6bb8c5d4a Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 18 Mar 2014 08:48:15 -0700 Subject: [PATCH 03/16] Implemented changes Anne and I discussed. --- .../rigged_configuration_element.py | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index abdfb87dced..b1f78af6660 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -51,11 +51,15 @@ class RiggedConfigurationElement(ClonableArray): - ``rigged_partitions`` -- a list of rigged partitions There are two optional arguments to explicitly construct a rigged - configuration. The first is **partition_list** which gives a list of - partitions, and the second is **rigging_list** which is a list of + configuration. The first is ``partition_list`` which gives a list of + partitions, and the second is ``rigging_list`` which is a list of corresponding lists of riggings. If only partition_list is specified, then it sets the rigging equal to the calculated vacancy numbers. + If we are construction a rigged configuration from a rigged configuration + (say of another type) and we don't want to recompute the vacancy numbers, + we can use the ``use_vacancy_numbers`` to avoid the recomputation. + EXAMPLES: Type `A_n^{(1)}` examples:: @@ -100,7 +104,7 @@ class RiggedConfigurationElement(ClonableArray): -1[ ][ ][ ]-1 - sage: RC = RiggedConfigurations(['D', 4, 1], [[1,1], [2, 1]]) + sage: RC = RiggedConfigurations(['D', 4, 1], [[1, 1], [2, 1]]) sage: RC(partition_list=[[1], [1,1], [1], [1]]) 1[ ]1 @@ -112,7 +116,7 @@ class RiggedConfigurationElement(ClonableArray): 0[ ]0 - sage: RC(partition_list=[[1], [1,1], [1], [1]], rigging_list=[[0], [0,0], [0], [0]]) + sage: elt = RC(partition_list=[[1], [1,1], [1], [1]], rigging_list=[[0], [0,0], [0], [0]]); elt 1[ ]0 @@ -124,6 +128,16 @@ class RiggedConfigurationElement(ClonableArray): 0[ ]0 + sage: from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition + sage: RC2 = RiggedConfigurations(['D', 5, 1], [[2, 1], [3, 1]]) + sage: l = [RiggedPartition()] + list(elt) + sage: ascii_art(RC2(*l)) + (/) 1[ ]0 0[ ]0 0[ ]0 0[ ]0 + 0[ ]0 + sage: ascii_art(RC2(*l, use_vacancy_numbers=True)) + (/) 1[ ]0 0[ ]0 0[ ]0 0[ ]0 + 0[ ]0 + We can go between :class:`tensor products of KR tableaux` and tensor products of @@ -227,10 +241,10 @@ def __init__(self, parent, rigged_partitions=[], **options): nu.append(RiggedPartition(tuple(partition_data))) elif parent._cartan_type.classical().rank() == len(rigged_partitions) and \ isinstance(rigged_partitions[0], RiggedPartition): - if options.get('use_vacancy_numbers', False): # The isinstance check is to make sure we are not in the n == 1 special case because # Parent's __call__ always passes at least 1 argument to the element constructor + if options.get('use_vacancy_numbers', False): # Special display case if parent.cartan_type().type() == 'B': rigged_partitions[-1] = RiggedPartitionTypeB(rigged_partitions[-1]) @@ -547,9 +561,7 @@ def left_split(self): def delta(self, return_b=False): r""" - Return the image of ``self`` under the map basic map `\delta`. If the - left-most factor is not a single column, then this also performs a - :meth:`left_split()`. + Return the image of ``self`` under the map basic map `\delta`. The map `\delta : RC(B^{r,1} \otimes B) \to RC(B^{r-1,1} \otimes B)` (if `r = 1`, then we remove the left-most factor) is the @@ -557,6 +569,8 @@ def delta(self, return_b=False): tensor products of Kirillov-Reshetikhin tableaux. For more information, see :meth:`to_tensor_product_of_kirillov_reshetikhin_tableaux()`. + We can extend `\delta` when tthe left-most factor is not a single + column by precomposing with a :meth:`left_split()`. .. NOTE:: @@ -566,7 +580,8 @@ def delta(self, return_b=False): INPUT: - - ``return_b`` -- return the resulting letter from `\delta` + - ``return_b`` -- (default: ``False``) whether to return the + resulting letter from `\delta` OUTPUT: From 47964729d4aa5db565eacf94c3ee2ae3ef89fb46 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 23 Mar 2014 11:40:51 -0700 Subject: [PATCH 04/16] Made additional changes as per Anne's comments. - Moved opposition_automorphism() to Cartan type. - Added left/right split maps to (tensor product of) KR tableaux. --- src/sage/categories/classical_crystals.py | 41 ++----- .../combinat/crystals/kirillov_reshetikhin.py | 15 +++ .../rigged_configurations/kr_tableaux.py | 112 ++++++++++++++++++ .../rigged_configuration_element.py | 78 +++++++++++- .../tensor_product_kr_tableaux_element.py | 78 ++++++++++++ src/sage/combinat/root_system/cartan_type.py | 36 ++++++ 6 files changed, 326 insertions(+), 34 deletions(-) diff --git a/src/sage/categories/classical_crystals.py b/src/sage/categories/classical_crystals.py index 404ff61f938..3ca1cf9f930 100644 --- a/src/sage/categories/classical_crystals.py +++ b/src/sage/categories/classical_crystals.py @@ -87,41 +87,24 @@ def example(self, n = 3): class ParentMethods: - @cached_method def opposition_automorphism(self): r""" - Returns the opposition automorphism - - The *opposition automorphism* is the automorphism - `i \mapsto i^*` of the vertices Dynkin diagram such that, - for `w_0` the longest element of the Weyl group, and any - simple root `\alpha_i`, one has `\alpha_{i^*} = -w_0(\alpha_i)`. - - The automorphism is returned as a dictionary. + Deprecated in :trac:`15560`. Use the corresponding method in + Cartan type. EXAMPLES:: sage: T = CrystalOfTableaux(['A',5],shape=[1]) sage: T.opposition_automorphism() - {1: 5, 2: 4, 3: 3, 4: 2, 5: 1} - - sage: T = CrystalOfTableaux(['D',4],shape=[1]) - sage: T.opposition_automorphism() - {1: 1, 2: 2, 3: 3, 4: 4} - - sage: T = CrystalOfTableaux(['D',5],shape=[1]) - sage: T.opposition_automorphism() - {1: 1, 2: 2, 3: 3, 4: 5, 5: 4} - - sage: T = CrystalOfTableaux(['C',4],shape=[1]) - sage: T.opposition_automorphism() - {1: 1, 2: 2, 3: 3, 4: 4} + doctest:...: DeprecationWarning: opposition_automorphism is deprecated. + Use opposition_automorphism from the Cartan type instead. + See http://trac.sagemath.org/15560 for details. + Finite family {1: 5, 2: 4, 3: 3, 4: 2, 5: 1} """ - L = self.cartan_type().root_system().root_lattice() - W = L.weyl_group() - w0 = W.long_element() - alpha = L.simple_roots() - return dict( (i, (w0.action(alpha[i])).leading_support()) for i in self.index_set() ) + from sage.misc.superseded import deprecation + deprecation(15560, 'opposition_automorphism is deprecated. Use' + ' opposition_automorphism from the Cartan type instead.') + return self.cartan_type().opposition_automorphism() def demazure_character(self, w, f = None): r""" @@ -460,6 +443,6 @@ def lusztig_involution(self): """ hw = self.to_highest_weight()[1] hw.reverse() - hw = [self.parent().opposition_automorphism()[i] for i in hw] - return self.to_lowest_weight()[0].e_string(hw) + aut = self.parent().cartan_type().opposition_automorphism() + return self.to_lowest_weight()[0].e_string(aut[i] for i in hw) diff --git a/src/sage/combinat/crystals/kirillov_reshetikhin.py b/src/sage/combinat/crystals/kirillov_reshetikhin.py index a990bd62664..e947bef8c7e 100644 --- a/src/sage/combinat/crystals/kirillov_reshetikhin.py +++ b/src/sage/combinat/crystals/kirillov_reshetikhin.py @@ -657,6 +657,21 @@ def to_kirillov_reshetikhin_tableau(self): """ return self.parent().kirillov_reshetikhin_tableaux()(self) + def lusztig_involution(self): + """ + Return the classical Lusztig involution on ``self``. + + EXAMPLES:: + + sage: KRC = KirillovReshetikhinCrystal(['D',4,1], 2,2) + sage: elt = KRC(-1,2); elt + [[2], [-1]] + sage: elt.lusztig_involution() + [[1], [-2]] + """ + li = self.lift().lusztig_involution() + return self.parent().retract(li) + KirillovReshetikhinGenericCrystal.Element = KirillovReshetikhinGenericCrystalElement class KirillovReshetikhinCrystalFromPromotion(KirillovReshetikhinGenericCrystal, diff --git a/src/sage/combinat/rigged_configurations/kr_tableaux.py b/src/sage/combinat/rigged_configurations/kr_tableaux.py index 1fc0e71268a..4ef2a2bfcf1 100644 --- a/src/sage/combinat/rigged_configurations/kr_tableaux.py +++ b/src/sage/combinat/rigged_configurations/kr_tableaux.py @@ -473,6 +473,17 @@ def kirillov_reshetikhin_crystal(self): """ return KirillovReshetikhinCrystal(self._cartan_type, self._r, self._s) + def classical_decomposition(self): + """ + Return the classical crystal decomposition of ``self``. + + EXAMPLES:: + + sage: KirillovReshetikhinTableaux(['D', 4, 1], 2, 2).classical_decomposition() + The crystal of tableaux of type ['D', 4] and shape(s) [[], [1, 1], [2, 2]] + """ + return self.kirillov_reshetikhin_crystal().classical_decomposition() + class KRTableauxRectangle(KirillovReshetikhinTableaux): r""" Kirillov-Reshetkhin tableaux `B^{r,s}` whose module generator is a single @@ -1291,6 +1302,78 @@ def phi(self, i): return self.to_kirillov_reshetikhin_crystal().phi0() return TensorProductOfRegularCrystalsElement.phi(self, i) + def lusztig_involution(self): + r""" + Return the result of the classical Lusztig involution on ``self``. + + EXAMPLES:: + + sage: KRT = KirillovReshetikhinTableaux(['D',4,1], 2,3) + sage: mg = KRT.module_generators[1] + sage: mg.lusztig_involution() + [[-2, -2, 1], [-1, -1, 2]] + sage: elt = mg.f_string([2,1,3,2]); elt + [[3, -2, 1], [4, -1, 2]] + sage: elt.lusztig_involtion() + [[-4, -2, 1], [-3, -1, 2]] + """ + Cl = self.parent().cartan_type().classical() + I = Cl.index_set() + aut = Cl.opposition_automorphism() + hw = self.to_highest_weight(I)[1] + hw.reverse() + return self.to_lowest_weight(I)[0].e_string(aut[i] for i in hw) + + def left_split(self): + r""" + Return the image of ``self`` under the left column splitting map. + + EXAMPLES:: + + sage: KRT = KirillovReshetikhinTableaux(['D',4,1], 2,3) + sage: mg = KRT.module_generators[1]; mg.pp() + 1 -2 1 + 2 -1 2 + sage: ls = mg.left_split(); ls.pp() + 1 (X) -2 1 + 2 -1 2 + sage: ls.parent() + Tensor product of Kirillov-Reshetikhin tableaux of type ['D', 4, 1] and factor(s) ((2, 1), (2, 2)) + """ + P = self.parent() + if P._s == 1: + raise ValueError("cannot split a single column") + from sage.combinat.rigged_configurations.tensor_product_kr_tableaux import \ + TensorProductOfKirillovReshetikhinTableaux + r = P._r + TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, [[r, 1], [r, P._s-1]]) + lf = TP.crystals[0](*(self[:r])) + rf = TP.crystals[1](*(self[r:])) + return TP(lf, rf) + + def right_split(self): + r""" + Return the image of ``self`` under the right column splitting map. + + Let `\ast` denote the :meth:`Lusztig involution`, + and `\mathrm{ls}` as the :meth:`left splitting map`. + The right splitting map is defined as + \mathrm{rs} := \ast \circ \mathrm{ls} \circ \ast`. + + EXAMPLES:: + + sage: KRT = KirillovReshetikhinTableaux(['D',4,1], 2,3) + sage: mg = KRT.module_generators[1]; mg.pp() + 1 -2 1 + 2 -1 2 + sage: ls = mg.right_split(); ls.pp() + 1 -2 (X) 1 + 2 -1 2 + sage: ls.parent() + Tensor product of Kirillov-Reshetikhin tableaux of type ['D', 4, 1] and factor(s) ((2, 1), (2, 2)) + """ + return self.lusztig_involution().left_split().lusztig_involution() + KirillovReshetikhinTableaux.Element = KirillovReshetikhinTableauxElement class KRTableauxSpinElement(KirillovReshetikhinTableauxElement): @@ -1429,6 +1512,35 @@ def to_array(self, rows=True): return ret_list + def left_split(self): + """ + Return the image of ``self`` under the left column splitting map. + + EXAMPLES:: + + sage: KRT = KirillovReshetikhinTableaux(['D', 4, 1], 4, 3) + sage: elt = KRT(-3,-4,2,1,-3,-4,2,1,-2,-4,3,1); elt.pp() + 1 1 1 + 2 2 3 + -4 -4 -4 + -3 -3 -2 + sage: elt.left_split().pp() + 1 (X) 1 1 + 2 2 3 + -4 -4 -4 + -3 -3 -2 + """ + P = self.parent() + if P._s == 1: + raise ValueError("cannot split a single column") + from sage.combinat.rigged_configurations.tensor_product_kr_tableaux import \ + TensorProductOfKirillovReshetikhinTableaux + h = P._cartan_type.classical().rank() + TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, [[P._r, 1], [P._r, P._s-1]]) + lf = TP.crystals[0](*(self[:h])) + rf = TP.crystals[1](*(self[h:])) + return TP(lf, rf) + KRTableauxBn.Element = KRTableauxSpinElement KRTableauxSpin.Element = KRTableauxSpinElement diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index b1f78af6660..0ce4b1bbad7 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -56,7 +56,7 @@ class RiggedConfigurationElement(ClonableArray): corresponding lists of riggings. If only partition_list is specified, then it sets the rigging equal to the calculated vacancy numbers. - If we are construction a rigged configuration from a rigged configuration + If we are constructing a rigged configuration from a rigged configuration (say of another type) and we don't want to recompute the vacancy numbers, we can use the ``use_vacancy_numbers`` to avoid the recomputation. @@ -526,6 +526,39 @@ def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False kr_tab = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps) return kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals() + def lusztig_involution(self): + """ + Return the result of the classical Lusztig involution on ``self``. + + EXAMPLES:: + + sage: RC = RiggedConfigurations(['D',4,1], [[2,2]]) + sage: mg = RC.module_generators[1] + sage: ascii_art(mg.lusztig_involution()) + 0[ ][ ][ ]0 -1[ ][ ][ ]-1 0[ ][ ][ ]0 0[ ][ ][ ]0 + -1[ ][ ][ ]-1 + sage: elt = mg.f_string([2,1,3,2]) + sage: ascii_art(elt.lusztig_involtion()) + 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 -2[ ][ ][ ]-2 + 0[ ][ ]0 + + We check that the Lusztig involution commutes with the bijection:: + + sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2], [1,2]]) + sage: all(b.to_rigged_configuration().lusztig_involution() + ....: == b.lusztig_involution().to_rigged_configuration() for b in KRT) + True + """ + P = self.parent() + Cl = P.cartan_type().classical() + I = Cl.index_set() + aut = Cl.opposition_automorphism() + hw = self.to_highest_weight(I)[1] + hw.reverse() + from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations + RC = RiggedConfigurations(P._cartan_type, reversed(P.dims)) + return RC(*self, use_vacancy_numbers=True).to_lowest_weight(I)[0].e_string(aut[i] for i in hw) + def left_split(self): r""" Return the image of ``self`` under the left column splitting @@ -550,15 +583,50 @@ def left_split(self): 1[ ][ ]0 0[ ]0 """ P = self.parent() - B = list(P.dims) - if B[0][1] == 1: + if P.dims[0][1] == 1: raise ValueError("cannot split a single column") - B[0] = (B[0][0], B[0][1] - 1) - B.insert(0, (B[0][0], 1)) + r,s = P.dims[0] + B = [[r,1], [r,s-1]] + B.extend(P.dims[1:]) from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations RC = RiggedConfigurations(P._cartan_type, B) return RC(*self) + def right_split(self): + r""" + Return the image of ``self`` under the right column splitting + map `\beta^*`. + + Let `\ast` denote the :meth:`Lsztig involution` + and `\beta` denote the :meth:`left splitting map`, we + define the right splitting map by + `\beta^* := \ast \circ \beta \circ \ast`. + + EXAMPLES:: + + sage: RC = RiggedConfigurations(['C',4,1], [[3,3]]) + sage: mg = RC.module_generators[-1] + sage: ascii_art(mg) + 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ]0 + sage: ascii_art(mg.right_split()) + 0[ ][ ]0 0[ ][ ]0 1[ ][ ]0 0[ ]0 + 0[ ][ ]0 1[ ][ ]0 0[ ]0 + 1[ ][ ]0 0[ ]0 + + sage: RC = RiggedConfigurations(['D',4,1], [[2,2],[1,2]]) + sage: ascii_art(elt) + -1[ ][ ][ ]-1 0[ ][ ]0 -1[ ][ ]-1 1[ ][ ]1 + 0[ ]0 0[ ][ ]0 -1[ ]-1 + 0[ ]0 + sage: ascii_art(elt.right_split()) + -1[ ][ ][ ]-1 0[ ][ ]0 -1[ ][ ]-1 1[ ][ ]1 + 1[ ]0 0[ ][ ]0 -1[ ]-1 + 0[ ]0 + """ + return self.lusztig_involution().left_split().lusztig_involution() + def delta(self, return_b=False): r""" Return the image of ``self`` under the map basic map `\delta`. diff --git a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py index adc044e7e96..3f69c32b3bd 100644 --- a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +++ b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py @@ -229,6 +229,84 @@ def classical_weight(self): """ return sum([x.classical_weight() for x in self]) + def lusztig_involution(self): + r""" + Return the result of the classical Lusztig involution on ``self``. + + EXAMPLES:: + + sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) + sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]]) + sage: li = elt.lusztig_involution(); li + [[1, 1, 4]] (X) [[2, 3], [3, 4]] + sage: li.parent() + Tensor product of Kirillov-Reshetikhin tableaux of type ['A', 3, 1] and factor(s) ((1, 3), (2, 2)) + """ + from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ + import TensorProductOfKirillovReshetikhinTableaux + P = self.parent() + P = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, reversed(P.dims)) + return P(*[x.lusztig_involution() for x in reversed(self)]) + + def left_split(self): + r""" + Return the image of ``self`` under the left column splitting map. + + EXAMPLES:: + + sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) + sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]]); elt.pp() + 1 2 (X) 1 4 4 + 2 3 + sage: elt.left_split().pp() + 1 (X) 2 (X) 1 4 4 + 2 3 + """ + P = self.parent() + if P.dims[0][1] == 1: + raise ValueError("cannot split a single column") + r,s = P.dims[0] + B = [[r,1], [r,s-1]] + B.extend(P.dims[1:]) + from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ + import TensorProductOfKirillovReshetikhinTableaux + TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, B) + x = self[0].left_split() + return TP(*(list(x) + self[1:])) + + def right_split(self): + r""" + Return the image of ``self`` under the right column splitting map. + + EXAMPLES:: + + sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) + sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]]); elt.pp() + 1 2 (X) 1 4 4 + 2 3 + sage: elt.right_split().pp() + 1 2 (X) 1 4 (X) 4 + 2 3 + + Let `\ast` denote the :meth:`Lusztig involution`, + we check that `\ast \circ \mathrm{ls} \circ \ast = \mathrm{rs}`:: + + sage: all(x.lusztig_involution().left_split().lusztig_involution() == x.right_split() for x in KRT) + True + """ + P = self.parent() + if P.dims[-1][1] == 1: + raise ValueError("cannot split a single column") + r,s = P.dims[-1] + B = list(P.dims[:-1]) + B.append([r, s-1]) + B.append([r, 1]) + from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ + import TensorProductOfKirillovReshetikhinTableaux + TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, B) + x = self[-1].right_split() + return TP(*(self[:-1] + list(x))) + def to_rigged_configuration(self, display_steps=False): r""" Perform the bijection from ``self`` to a diff --git a/src/sage/combinat/root_system/cartan_type.py b/src/sage/combinat/root_system/cartan_type.py index 9121757aca3..078eeb57fd9 100644 --- a/src/sage/combinat/root_system/cartan_type.py +++ b/src/sage/combinat/root_system/cartan_type.py @@ -2261,6 +2261,42 @@ def type(self): """ return self.letter + @cached_method + def opposition_automorphism(self): + r""" + Returns the opposition automorphism + + The *opposition automorphism* is the automorphism + `i \mapsto i^*` of the vertices Dynkin diagram such that, + for `w_0` the longest element of the Weyl group, and any + simple root `\alpha_i`, one has `\alpha_{i^*} = -w_0(\alpha_i)`. + + The automorphism is returned as a :class:`Family`. + + EXAMPLES:: + + sage: ct = CartanType(['A', 5]) + sage: ct.opposition_automorphism() + Finite family {1: 5, 2: 4, 3: 3, 4: 2, 5: 1} + + sage: ct = CartanType(['D', 4]) + sage: ct.opposition_automorphism() + Finite family {1: 1, 2: 2, 3: 3, 4: 4} + + sage: ct = CartanType(['D', 5]) + sage: ct.opposition_automorphism() + Finite family {1: 1, 2: 2, 3: 3, 4: 5, 5: 4} + + sage: ct = CartanType(['C', 4]) + sage: ct.opposition_automorphism() + Finite family {1: 1, 2: 2, 3: 3, 4: 4} + """ + Q = self.root_system().root_lattice() + W = Q.weyl_group() + w0 = W.long_element() + alpha = Q.simple_roots() + d = {i: (w0.action(alpha[i])).leading_support() for i in self.index_set()} + return Family(d) ########################################################################## class CartanType_standard_affine(UniqueRepresentation, SageObject, CartanType_affine): From df3a9ebd23841479e05cd11b6a84d6807dfa3e4a Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 23 Mar 2014 12:23:58 -0700 Subject: [PATCH 05/16] Some doctest fixes. --- .../rigged_configurations/kr_tableaux.py | 18 +++++++++--------- .../rigged_configuration_element.py | 6 ++++-- .../tensor_product_kr_tableaux_element.py | 8 ++++---- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/kr_tableaux.py b/src/sage/combinat/rigged_configurations/kr_tableaux.py index 861354e1173..be52f8ff984 100644 --- a/src/sage/combinat/rigged_configurations/kr_tableaux.py +++ b/src/sage/combinat/rigged_configurations/kr_tableaux.py @@ -485,7 +485,7 @@ def classical_decomposition(self): EXAMPLES:: - sage: KirillovReshetikhinTableaux(['D', 4, 1], 2, 2).classical_decomposition() + sage: crystals.KirillovReshetikhin(['D', 4, 1], 2, 2, model='KR').classical_decomposition() The crystal of tableaux of type ['D', 4] and shape(s) [[], [1, 1], [2, 2]] """ return self.kirillov_reshetikhin_crystal().classical_decomposition() @@ -1319,13 +1319,13 @@ def lusztig_involution(self): EXAMPLES:: - sage: KRT = KirillovReshetikhinTableaux(['D',4,1], 2,3) + sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 2, 3, model='KR') sage: mg = KRT.module_generators[1] sage: mg.lusztig_involution() [[-2, -2, 1], [-1, -1, 2]] sage: elt = mg.f_string([2,1,3,2]); elt [[3, -2, 1], [4, -1, 2]] - sage: elt.lusztig_involtion() + sage: elt.lusztig_involution() [[-4, -2, 1], [-3, -1, 2]] """ Cl = self.parent().cartan_type().classical() @@ -1341,7 +1341,7 @@ def left_split(self): EXAMPLES:: - sage: KRT = KirillovReshetikhinTableaux(['D',4,1], 2,3) + sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 2, 3, model='KR') sage: mg = KRT.module_generators[1]; mg.pp() 1 -2 1 2 -1 2 @@ -1373,15 +1373,15 @@ def right_split(self): EXAMPLES:: - sage: KRT = KirillovReshetikhinTableaux(['D',4,1], 2,3) + sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 2, 3, model='KR') sage: mg = KRT.module_generators[1]; mg.pp() 1 -2 1 2 -1 2 sage: ls = mg.right_split(); ls.pp() - 1 -2 (X) 1 - 2 -1 2 + -2 1 (X) 1 + -1 2 2 sage: ls.parent() - Tensor product of Kirillov-Reshetikhin tableaux of type ['D', 4, 1] and factor(s) ((2, 1), (2, 2)) + Tensor product of Kirillov-Reshetikhin tableaux of type ['D', 4, 1] and factor(s) ((2, 2), (2, 1)) """ return self.lusztig_involution().left_split().lusztig_involution() @@ -1529,7 +1529,7 @@ def left_split(self): EXAMPLES:: - sage: KRT = KirillovReshetikhinTableaux(['D', 4, 1], 4, 3) + sage: KRT = crystals.KirillovReshetikhin(['D', 4, 1], 4, 3, model='KR') sage: elt = KRT(-3,-4,2,1,-3,-4,2,1,-2,-4,3,1); elt.pp() 1 1 1 2 2 3 diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index a3ae57167ab..ac777cb4edb 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -252,7 +252,8 @@ def __init__(self, parent, rigged_partitions=[], **options): rigged_partitions[-1] = RiggedPartitionTypeB(rigged_partitions[-1]) ClonableArray.__init__(self, parent, rigged_partitions) return - nu = rigged_partitions + # Make a (deep)copy in case we change the vacancy numbers + nu = [nu._clone() for nu in rigged_partitions] else: # Otherwise we did not receive any info, create a size n array of # empty rigged partitions @@ -540,7 +541,7 @@ def lusztig_involution(self): 0[ ][ ][ ]0 -1[ ][ ][ ]-1 0[ ][ ][ ]0 0[ ][ ][ ]0 -1[ ][ ][ ]-1 sage: elt = mg.f_string([2,1,3,2]) - sage: ascii_art(elt.lusztig_involtion()) + sage: ascii_art(elt.lusztig_involution()) 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 -2[ ][ ][ ]-2 0[ ][ ]0 @@ -618,6 +619,7 @@ def right_split(self): 1[ ][ ]0 0[ ]0 sage: RC = RiggedConfigurations(['D',4,1], [[2,2],[1,2]]) + sage: elt = RC(partition_list=[[3,1], [2,2,1], [2,1], [2]]) sage: ascii_art(elt) -1[ ][ ][ ]-1 0[ ][ ]0 -1[ ][ ]-1 1[ ][ ]1 0[ ]0 0[ ][ ]0 -1[ ]-1 diff --git a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py index a893930b6f0..3027dd2d42f 100644 --- a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +++ b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py @@ -235,7 +235,7 @@ def lusztig_involution(self): EXAMPLES:: - sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) + sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]]) sage: li = elt.lusztig_involution(); li [[1, 1, 4]] (X) [[2, 3], [3, 4]] @@ -254,13 +254,13 @@ def left_split(self): EXAMPLES:: - sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) + sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]]); elt.pp() 1 2 (X) 1 4 4 2 3 sage: elt.left_split().pp() 1 (X) 2 (X) 1 4 4 - 2 3 + 2 3 """ P = self.parent() if P.dims[0][1] == 1: @@ -280,7 +280,7 @@ def right_split(self): EXAMPLES:: - sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) + sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]]) sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]]); elt.pp() 1 2 (X) 1 4 4 2 3 From 46a0d0af4c422f8fd7b11f334d6a814b8f1a16fb Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 14 Apr 2014 08:09:47 -0700 Subject: [PATCH 06/16] Fixes for lusztig involution. --- src/sage/categories/classical_crystals.py | 24 +++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/sage/categories/classical_crystals.py b/src/sage/categories/classical_crystals.py index 92ab776467e..33a879b63e2 100644 --- a/src/sage/categories/classical_crystals.py +++ b/src/sage/categories/classical_crystals.py @@ -94,10 +94,10 @@ def opposition_automorphism(self): EXAMPLES:: - sage: T = CrystalOfTableaux(['A',5],shape=[1]) + sage: T = crystals.Tableaux(['A',5],shape=[1]) sage: T.opposition_automorphism() doctest:...: DeprecationWarning: opposition_automorphism is deprecated. - Use opposition_automorphism from the Cartan type instead. + Use opposition_automorphism from the Cartan type instead. See http://trac.sagemath.org/15560 for details. Finite family {1: 5, 2: 4, 3: 3, 4: 2, 5: 1} """ @@ -406,11 +406,14 @@ class ElementMethods: def lusztig_involution(self): r""" - Returns the Lusztig involution on the classical highest weight crystal self. - - The Lusztig involution on a finite-dimensional highest weight crystal `B(\lambda)` of highest weight `\lambda` - maps the highest weight vector to the lowest weight vector and the Kashiwara operator `f_i` to - `e_{i^*}`, where `i^*` is defined as `\alpha_{i^*} = -w_0(\alpha_i)`. Here `w_0` is the longest element + Return the Lusztig involution on the classical highest weight + crystal ``self``. + + The Lusztig involution on a finite-dimensional highest weight + crystal `B(\lambda)` of highest weight `\lambda` maps the + highest weight vector to the lowest weight vector and the + Kashiwara operator `f_i` to `e_{i^*}`, where `i^*` is defined as + `\alpha_{i^*} = -w_0(\alpha_i)`. Here `w_0` is the longest element of the Weyl group acting on the `i`-th simple root `\alpha_i`. EXAMPLES:: @@ -435,8 +438,8 @@ def lusztig_involution(self): [[[[1]], [[-1]]], [[[2]], [[-2]]], [[[3]], [[3]]], [[[-3]], [[-3]]], [[[-2]], [[2]]], [[[-1]], [[1]]]] - sage: C=CartanType(['E',6]) - sage: La=C.root_system().weight_lattice().fundamental_weights() + sage: C = CartanType(['E',6]) + sage: La = C.root_system().weight_lattice().fundamental_weights() sage: T = crystals.HighestWeight(La[1]) sage: t = T[3]; t [(-4, 2, 5)] @@ -445,6 +448,7 @@ def lusztig_involution(self): """ hw = self.to_highest_weight()[1] hw.reverse() - hw = [self.parent().opposition_automorphism()[i] for i in hw] + A = self.parent().cartan_type().opposition_automorphism() + hw = [A[i] for i in hw] return self.to_lowest_weight()[0].e_string(hw) From 695b0d9859d579d142b36551cc83fb04fd2c5585 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 15 May 2014 07:52:39 -0700 Subject: [PATCH 07/16] Fixed issue with type B bijection. --- src/sage/combinat/rigged_configurations/bij_type_B.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index b02ba765e08..a1c6fa028cb 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -114,7 +114,7 @@ def run(self, verbose=False): self.ret_rig_con[-1].rigging, self.ret_rig_con[-1].vacancy_numbers) bij = KRTToRCBijectionTypeA2Odd(KRT.module_generators[0]) # Placeholder element - bij.ret_rig_con = KRT.rigged_configurations()(*self.ret_rig_con) + bij.ret_rig_con = KRT.rigged_configurations()(*self.ret_rig_con, use_vacancy_numbers=True) bij.cur_path = self.cur_path bij.cur_dims = self.cur_dims for i in range(len(self.cur_dims)): From c821bde63537e1233fdf2f51c9cba75b47747f27 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 17 May 2014 00:02:53 -0700 Subject: [PATCH 08/16] Initial graph viewing. Only for type D and types w/o special run() methods. --- .../bij_abstract_class.py | 29 ++++++++++++++-- .../rigged_configurations/bij_type_D.py | 33 ++++++++++++++++++- .../rigged_configuration_element.py | 6 ++-- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index 0f84c64b6dd..30a15a631be 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -311,6 +311,11 @@ def __init__(self, RC_element): # TODO: Convert from cur_partitions to rigged_con self.cur_partitions = deepcopy(list(self.rigged_con)[:]) + # This is a dummy edge to start the process + cp = RC_element.__copy__() + cp.set_immutable() + self._graph = [ [[], (cp, 0)] ] + # Compute the current L matrix # self.L = {} # for dim in self.rigged_con.parent().dims: @@ -341,15 +346,17 @@ def __eq__(self, rhs): """ return isinstance(rhs, RCToKRTBijectionAbstract) - def run(self, verbose=False): + def run(self, verbose=False, display_graph=False): """ Run the bijection from rigged configurations to tensor product of KR tableaux. INPUT: - - ``verbose`` -- (Default: ``False``) Display each step in the + - ``verbose`` -- (default: ``False``) display each step in the bijection + - ``display_graph`` -- (default: ``False``) build the graph of each + step in the bijection EXAMPLES:: @@ -390,6 +397,10 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_numbers(a) + if display_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) + while self.cur_dims[0][0] > 0: if verbose: print("====================") @@ -404,8 +415,22 @@ def run(self, verbose=False): # Make sure we have a crystal letter ret_crystal_path[-1].append(letters(b)) # Append the rank + if display_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) + self.cur_dims.pop(0) # Pop off the leading column + if display_graph: + self._graph.pop(0) # Remove the dummy at the start + from sage.graphs.digraph import DiGraph + from sage.graphs.dot2tex_utils import have_dot2tex + from sage.misc.latex import view + self._graph = DiGraph(self._graph) + if have_dot2tex(): + self._graph.set_latex_options(format="dot2tex", edge_labels=True) + view(self._graph, tightpage=True) + # Basic check to make sure we end with the empty configuration #tot_len = sum([len(rp) for rp in self.cur_partitions]) #if tot_len != 0: diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index 4da88876953..8009cfb7e64 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -414,7 +414,7 @@ class RCToKRTBijectionTypeD(RCToKRTBijectionTypeA): r""" Specific implementation of the bijection from rigged configurations to tensor products of KR tableaux for type `D_n^{(1)}`. """ - def run(self, verbose=False): + def run(self, verbose=False, display_graph=False): """ Run the bijection from rigged configurations to tensor product of KR tableaux for type `D_n^{(1)}`. @@ -455,6 +455,10 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_numbers(a) + if display_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) + # Check to see if we are a spinor if dim[0] >= self.n - 1: if verbose: @@ -465,6 +469,10 @@ def run(self, verbose=False): print("--------------------\n") print("Applying doubling map") self.doubling_map() + if display_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) + if dim[0] == self.n - 1: if verbose: print("====================") @@ -477,6 +485,10 @@ def run(self, verbose=False): b = -self.n ret_crystal_path[-1].append(letters(b)) # Append the rank + if display_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) + while self.cur_dims[0][0] > 0: if verbose: print("====================") @@ -496,6 +508,10 @@ def run(self, verbose=False): # Make sure we have a crystal letter ret_crystal_path[-1].append(letters(b)) # Append the rank + if display_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) + self.cur_dims.pop(0) # Pop off the leading column # Check to see if we were a spinor @@ -508,6 +524,21 @@ def run(self, verbose=False): print("--------------------\n") print("Applying halving map") self.halving_map() + + if display_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), '1/2x']) + + if display_graph: + self._graph.pop(0) # Remove the dummy at the start + from sage.graphs.digraph import DiGraph + from sage.graphs.dot2tex_utils import have_dot2tex + from sage.misc.latex import view + self._graph = DiGraph(self._graph) + if have_dot2tex(): + self._graph.set_latex_options(format="dot2tex", edge_labels=True) + view(self._graph, tightpage=True) + return self.KRT(pathlist=ret_crystal_path) def next_state(self, height): diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 20940407b89..8d15dfbeddd 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -476,7 +476,7 @@ def check(self): if vac_num < partition.rigging[i]: raise ValueError("rigging can be at most the vacancy number") - def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False): + def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False, display_graph=False): r""" Perform the bijection from this rigged configuration to a tensor product of Kirillov-Reshetikhin tableaux given in [RigConBijection]_ @@ -493,6 +493,8 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False - ``display_steps`` -- (default: ``False``) boolean which indicates if we want to output each step in the algorithm + - ``display_graph` -- (default: ``False``) boolean which indicates + if we want to construct and display a graph of the bijection OUTPUT: @@ -527,7 +529,7 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False True """ from sage.combinat.rigged_configurations.bijection import RCToKRTBijection - return RCToKRTBijection(self).run(display_steps) + return RCToKRTBijection(self).run(display_steps, display_graph) def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False): r""" From e8011bd22537d067bafcc80340da4d771e487ba5 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 26 May 2014 10:37:54 -0700 Subject: [PATCH 09/16] Changed input method and added constructions to other types. --- .../bij_abstract_class.py | 12 +++--- .../rigged_configurations/bij_type_B.py | 38 ++++++++++++++++++- .../rigged_configurations/bij_type_D.py | 21 +++++----- .../bij_type_D_twisted.py | 31 ++++++++++++++- .../rigged_configuration_element.py | 12 ++++-- 5 files changed, 89 insertions(+), 25 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index cf217cf3705..30292da22ee 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -346,7 +346,7 @@ def __eq__(self, rhs): """ return isinstance(rhs, RCToKRTBijectionAbstract) - def run(self, verbose=False, display_graph=False): + def run(self, verbose=False, build_graph=False): """ Run the bijection from rigged configurations to tensor product of KR tableaux. @@ -355,7 +355,7 @@ def run(self, verbose=False, display_graph=False): - ``verbose`` -- (default: ``False``) display each step in the bijection - - ``display_graph`` -- (default: ``False``) build the graph of each + - ``build_graph`` -- (default: ``False``) build the graph of each step in the bijection EXAMPLES:: @@ -397,7 +397,7 @@ def run(self, verbose=False, display_graph=False): for a in range(self.n): self._update_vacancy_numbers(a) - if display_graph: + if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) @@ -415,21 +415,19 @@ def run(self, verbose=False, display_graph=False): # Make sure we have a crystal letter ret_crystal_path[-1].append(letters(b)) # Append the rank - if display_graph: + if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) self.cur_dims.pop(0) # Pop off the leading column - if display_graph: + if build_graph: self._graph.pop(0) # Remove the dummy at the start from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex - from sage.misc.latex import view self._graph = DiGraph(self._graph) if have_dot2tex(): self._graph.set_latex_options(format="dot2tex", edge_labels=True) - view(self._graph, tightpage=True) # Basic check to make sure we end with the empty configuration #tot_len = sum([len(rp) for rp in self.cur_partitions]) diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index 284f1b78cf6..1c0775939ad 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -524,15 +524,17 @@ class RCToKRTBijectionTypeB(RCToKRTBijectionTypeC): Specific implementation of the bijection from rigged configurations to tensor products of KR tableaux for type `B_n^{(1)}`. """ - def run(self, verbose=False): + def run(self, verbose=False, build_graph=False): """ Run the bijection from rigged configurations to tensor product of KR tableaux for type `B_n^{(1)}`. INPUT: - - ``verbose`` -- (Default: ``False``) Display each step in the + - ``verbose`` -- (default: ``False``) display each step in the bijection + - ``build_graph`` -- (default: ``False``) build the graph of each + step in the bijection EXAMPLES:: @@ -589,6 +591,10 @@ def run(self, verbose=False): bij.cur_partitions[i]._list[j] *= 2 bij.cur_partitions[i].rigging[j] *= 2 bij.cur_partitions[i].vacancy_numbers[j] *= 2 + + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) # Perform the type A_{2n-1}^{(2)} bijection @@ -603,6 +609,10 @@ def run(self, verbose=False): # All it does is update the vacancy numbers on the RC side for a in range(self.n): bij._update_vacancy_numbers(a) + + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) while bij.cur_dims[0][0] > 0: if verbose: @@ -617,6 +627,10 @@ def run(self, verbose=False): # Make sure we have a crystal letter ret_crystal_path[-1].append(letters(b)) # Append the rank + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) + bij.cur_dims.pop(0) # Pop off the leading column self.cur_dims.pop(0) # Pop off the spin rectangle @@ -639,6 +653,10 @@ def run(self, verbose=False): self.cur_partitions[i]._list[j] //= 2 self.cur_partitions[i].rigging[j] //= 2 self.cur_partitions[i].vacancy_numbers[j] //= 2 + + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), '1/2x']) else: # Perform the regular type B_n^{(1)} bijection @@ -662,6 +680,10 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_numbers(a) + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) + while self.cur_dims[0][0] > 0: if verbose: print("====================") @@ -676,8 +698,20 @@ def run(self, verbose=False): # Make sure we have a crystal letter ret_crystal_path[-1].append(letters(b)) # Append the rank + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) + self.cur_dims.pop(0) # Pop off the leading column + if build_graph: + self._graph.pop(0) # Remove the dummy at the start + from sage.graphs.digraph import DiGraph + from sage.graphs.dot2tex_utils import have_dot2tex + self._graph = DiGraph(self._graph) + if have_dot2tex(): + self._graph.set_latex_options(format="dot2tex", edge_labels=True) + return self.KRT(pathlist=ret_crystal_path) def next_state(self, height): diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index 8009cfb7e64..f8b1a19cd4f 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -414,15 +414,17 @@ class RCToKRTBijectionTypeD(RCToKRTBijectionTypeA): r""" Specific implementation of the bijection from rigged configurations to tensor products of KR tableaux for type `D_n^{(1)}`. """ - def run(self, verbose=False, display_graph=False): + def run(self, verbose=False, build_graph=False): """ Run the bijection from rigged configurations to tensor product of KR tableaux for type `D_n^{(1)}`. INPUT: - - ``verbose`` -- (Default: ``False``) Display each step in the + - ``verbose`` -- (default: ``False``) display each step in the bijection + - ``build_graph`` -- (default: ``False``) build the graph of each + step in the bijection EXAMPLES:: @@ -455,7 +457,7 @@ def run(self, verbose=False, display_graph=False): for a in range(self.n): self._update_vacancy_numbers(a) - if display_graph: + if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) @@ -469,7 +471,8 @@ def run(self, verbose=False, display_graph=False): print("--------------------\n") print("Applying doubling map") self.doubling_map() - if display_graph: + + if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) @@ -485,7 +488,7 @@ def run(self, verbose=False, display_graph=False): b = -self.n ret_crystal_path[-1].append(letters(b)) # Append the rank - if display_graph: + if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) @@ -508,7 +511,7 @@ def run(self, verbose=False, display_graph=False): # Make sure we have a crystal letter ret_crystal_path[-1].append(letters(b)) # Append the rank - if display_graph: + if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) @@ -525,19 +528,17 @@ def run(self, verbose=False, display_graph=False): print("Applying halving map") self.halving_map() - if display_graph: + if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '1/2x']) - if display_graph: + if build_graph: self._graph.pop(0) # Remove the dummy at the start from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex - from sage.misc.latex import view self._graph = DiGraph(self._graph) if have_dot2tex(): self._graph.set_latex_options(format="dot2tex", edge_labels=True) - view(self._graph, tightpage=True) return self.KRT(pathlist=ret_crystal_path) diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py index 0796a8f6819..accf74e60bc 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py @@ -310,15 +310,17 @@ class RCToKRTBijectionTypeDTwisted(RCToKRTBijectionTypeD, RCToKRTBijectionTypeA2 Specific implementation of the bijection from rigged configurations to tensor products of KR tableaux for type `D_{n+1}^{(2)}`. """ - def run(self, verbose=False): + def run(self, verbose=False, build_graph=False): """ Run the bijection from rigged configurations to tensor product of KR tableaux for type `D_{n+1}^{(2)}`. INPUT: - - ``verbose`` -- (Default: ``False``) Display each step in the + - ``verbose`` -- (default: ``False``) display each step in the bijection + - ``build_graph`` -- (default: ``False``) build the graph of each + step in the bijection EXAMPLES:: @@ -351,6 +353,10 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_numbers(a) + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) + # Check to see if we are a spinor if dim[0] == self.n: if verbose: @@ -362,6 +368,10 @@ def run(self, verbose=False): print("Applying doubling map") self.doubling_map() + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) + while self.cur_dims[0][0] > 0: if verbose: print("====================") @@ -376,6 +386,10 @@ def run(self, verbose=False): # Make sure we have a crystal letter ret_crystal_path[-1].append(letters(b)) # Append the rank + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) + self.cur_dims.pop(0) # Pop off the leading column # Check to see if we were a spinor @@ -388,6 +402,19 @@ def run(self, verbose=False): print("--------------------\n") print("Applying halving map") self.halving_map() + + if build_graph: + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + self._graph.append([self._graph[-1][1], (y, len(self._graph)), '1/2x']) + + if build_graph: + self._graph.pop(0) # Remove the dummy at the start + from sage.graphs.digraph import DiGraph + from sage.graphs.dot2tex_utils import have_dot2tex + self._graph = DiGraph(self._graph) + if have_dot2tex(): + self._graph.set_latex_options(format="dot2tex", edge_labels=True) + return self.KRT(pathlist=ret_crystal_path) def next_state(self, height): diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 8d15dfbeddd..dda01bbdb0c 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -476,7 +476,7 @@ def check(self): if vac_num < partition.rigging[i]: raise ValueError("rigging can be at most the vacancy number") - def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False, display_graph=False): + def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False, build_graph=False): r""" Perform the bijection from this rigged configuration to a tensor product of Kirillov-Reshetikhin tableaux given in [RigConBijection]_ @@ -493,8 +493,8 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False - ``display_steps`` -- (default: ``False``) boolean which indicates if we want to output each step in the algorithm - - ``display_graph` -- (default: ``False``) boolean which indicates - if we want to construct and display a graph of the bijection + - ``build_graph` -- (default: ``False``) boolean which indicates + if we want to construct and return a graph of the bijection OUTPUT: @@ -529,7 +529,11 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False True """ from sage.combinat.rigged_configurations.bijection import RCToKRTBijection - return RCToKRTBijection(self).run(display_steps, display_graph) + bij = RCToKRTBijection(self) + ret = bij.run(display_steps, build_graph) + if build_graph: + return (ret, bij._graph) + return ret def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False): r""" From 56119bf15fc20943912a05c9155e5c54e5bc77df Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 20 Jul 2014 10:37:13 -0700 Subject: [PATCH 10/16] Added theta map, fixed bugs and expanded doc. Fixed vacancy number in verbose output from change in handling. Added tests for build_graph option to bijetions. The map theta is called complement(). Renamed delta map to left_box. --- .../bij_abstract_class.py | 16 +++- .../rigged_configurations/bij_type_B.py | 32 ++++--- .../rigged_configurations/bij_type_D.py | 26 ++++-- .../bij_type_D_twisted.py | 20 ++-- .../rigged_configuration_element.py | 92 +++++++++++++++++-- 5 files changed, 145 insertions(+), 41 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index 30292da22ee..a111e05dd36 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -361,9 +361,15 @@ def run(self, verbose=False, build_graph=False): EXAMPLES:: sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]]) + sage: x = RC(partition_list=[[1],[1],[1],[1]]) sage: from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA - sage: RCToKRTBijectionTypeA(RC(partition_list=[[1],[1],[1],[1]])).run() + sage: RCToKRTBijectionTypeA(x).run() [[2], [5]] + sage: bij = RCToKRTBijectionTypeA(x) + sage: bij.run(build_graph=True) + [[2], [5]] + sage: bij._graph + Digraph on 3 vertices """ from sage.combinat.crystals.letters import CrystalOfLetters letters = CrystalOfLetters(self.rigged_con.parent()._cartan_type.classical()) @@ -383,7 +389,7 @@ def run(self, verbose=False, build_graph=False): if self.cur_dims[0][1] > 1: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -398,13 +404,13 @@ def run(self, verbose=False, build_graph=False): self._update_vacancy_numbers(a) if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) while self.cur_dims[0][0] > 0: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -416,7 +422,7 @@ def run(self, verbose=False, build_graph=False): ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) self.cur_dims.pop(0) # Pop off the leading column diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index ea1e3ea0192..6bf3ff54975 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -542,10 +542,16 @@ def run(self, verbose=False, build_graph=False): sage: from sage.combinat.rigged_configurations.bij_type_B import RCToKRTBijectionTypeB sage: RCToKRTBijectionTypeB(RC(partition_list=[[1],[1,1],[1]])).run() [[3], [0]] + sage: RC = RiggedConfigurations(['B', 3, 1], [[3, 1]]) - sage: from sage.combinat.rigged_configurations.bij_type_B import RCToKRTBijectionTypeB - sage: RCToKRTBijectionTypeB(RC(partition_list=[[],[1],[1]])).run() + sage: x = RC(partition_list=[[],[1],[1]]) + sage: RCToKRTBijectionTypeB(x).run() + [[1], [3], [-2]] + sage: bij = RCToKRTBijectionTypeB(x) + sage: bij.run(build_graph=True) [[1], [3], [-2]] + sage: bij._graph + Digraph on 6 vertices """ from sage.combinat.crystals.letters import CrystalOfLetters letters = CrystalOfLetters(self.rigged_con.parent()._cartan_type.classical()) @@ -572,7 +578,7 @@ def run(self, verbose=False, build_graph=False): RC = RiggedConfigurations(['A', 2*self.n-1, 2], self.cur_dims) if verbose: print("====================") - print(repr(RC(*self.cur_partitions))) + print(repr(RC(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -593,7 +599,7 @@ def run(self, verbose=False, build_graph=False): bij.cur_partitions[i].vacancy_numbers[j] *= 2 if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) # Perform the type A_{2n-1}^{(2)} bijection @@ -611,13 +617,13 @@ def run(self, verbose=False, build_graph=False): bij._update_vacancy_numbers(a) if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) while bij.cur_dims[0][0] > 0: if verbose: print("====================") - print(repr(RC(*bij.cur_partitions))) + print(repr(RC(*bij.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -628,7 +634,7 @@ def run(self, verbose=False, build_graph=False): ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) bij.cur_dims.pop(0) # Pop off the leading column @@ -642,7 +648,7 @@ def run(self, verbose=False, build_graph=False): # Convert back to a type B_n^{(1)} if verbose: print("====================") - print(repr(self.rigged_con.parent()(*bij.cur_partitions))) + print(repr(self.rigged_con.parent()(*bij.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -655,7 +661,7 @@ def run(self, verbose=False, build_graph=False): self.cur_partitions[i].vacancy_numbers[j] //= 2 if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '1/2x']) else: # Perform the regular type B_n^{(1)} bijection @@ -666,7 +672,7 @@ def run(self, verbose=False, build_graph=False): if self.cur_dims[0][1] > 1: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -681,13 +687,13 @@ def run(self, verbose=False, build_graph=False): self._update_vacancy_numbers(a) if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) while self.cur_dims[0][0] > 0: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -699,7 +705,7 @@ def run(self, verbose=False, build_graph=False): ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) self.cur_dims.pop(0) # Pop off the leading column diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index f8b1a19cd4f..0ce409a51f8 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -429,9 +429,15 @@ def run(self, verbose=False, build_graph=False): EXAMPLES:: sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 1]]) + sage: x = RC(partition_list=[[1],[1],[1],[1]]) sage: from sage.combinat.rigged_configurations.bij_type_D import RCToKRTBijectionTypeD - sage: RCToKRTBijectionTypeD(RC(partition_list=[[1],[1],[1],[1]])).run() + sage: RCToKRTBijectionTypeD(x).run() [[2], [-3]] + sage: bij = RCToKRTBijectionTypeD(x) + sage: bij.run(build_graph=True) + [[2], [-3]] + sage: bij._graph + Digraph on 3 vertices """ from sage.combinat.crystals.letters import CrystalOfLetters letters = CrystalOfLetters(self.rigged_con.parent()._cartan_type.classical()) @@ -458,14 +464,14 @@ def run(self, verbose=False, build_graph=False): self._update_vacancy_numbers(a) if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) # Check to see if we are a spinor if dim[0] >= self.n - 1: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -473,13 +479,13 @@ def run(self, verbose=False, build_graph=False): self.doubling_map() if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) if dim[0] == self.n - 1: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -489,13 +495,13 @@ def run(self, verbose=False, build_graph=False): ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) while self.cur_dims[0][0] > 0: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -512,7 +518,7 @@ def run(self, verbose=False, build_graph=False): ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) self.cur_dims.pop(0) # Pop off the leading column @@ -521,7 +527,7 @@ def run(self, verbose=False, build_graph=False): if dim[0] >= self.n-1: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -529,7 +535,7 @@ def run(self, verbose=False, build_graph=False): self.halving_map() if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '1/2x']) if build_graph: diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py index accf74e60bc..df93f1d8b95 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py @@ -325,9 +325,15 @@ def run(self, verbose=False, build_graph=False): EXAMPLES:: sage: RC = RiggedConfigurations(['D', 4, 2], [[3, 1]]) + sage: x = RC(partition_list=[[],[1],[1]]) sage: from sage.combinat.rigged_configurations.bij_type_D_twisted import RCToKRTBijectionTypeDTwisted - sage: RCToKRTBijectionTypeDTwisted(RC(partition_list=[[],[1],[1]])).run() + sage: RCToKRTBijectionTypeDTwisted(x).run() [[1], [3], [-2]] + sage: bij = RCToKRTBijectionTypeDTwisted(x) + sage: bij.run(build_graph=True) + [[1], [3], [-2]] + sage: bij._graph + Digraph on 6 vertices """ from sage.combinat.crystals.letters import CrystalOfLetters letters = CrystalOfLetters(self.rigged_con.parent()._cartan_type.classical()) @@ -354,14 +360,14 @@ def run(self, verbose=False, build_graph=False): self._update_vacancy_numbers(a) if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) # Check to see if we are a spinor if dim[0] == self.n: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -369,13 +375,13 @@ def run(self, verbose=False, build_graph=False): self.doubling_map() if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) while self.cur_dims[0][0] > 0: if verbose: print("====================") - print(repr(self.rigged_con.parent()(*self.cur_partitions))) + print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) print("--------------------") print(ret_crystal_path) print("--------------------\n") @@ -387,7 +393,7 @@ def run(self, verbose=False, build_graph=False): ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) self.cur_dims.pop(0) # Pop off the leading column @@ -404,7 +410,7 @@ def run(self, verbose=False, build_graph=False): self.halving_map() if build_graph: - y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions]) + y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '1/2x']) if build_graph: diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 9e10c024da2..95d2d382621 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -511,7 +511,10 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False - ``display_steps`` -- (default: ``False``) boolean which indicates if we want to output each step in the algorithm - ``build_graph` -- (default: ``False``) boolean which indicates - if we want to construct and return a graph of the bijection + if we want to construct and return a graph of the bijection whose + vertices are rigged configurations obtained at each step and edges + are labeled by either the return value of `\delta` or the + doubling/halving map OUTPUT: @@ -544,6 +547,35 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False sage: elt == ret True + + To view the steps of the bijection in the output, run with + the ``display_steps=True`` option:: + + sage: elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(True) + ==================== + ... + ==================== + + 0[ ]0 + + -2[ ][ ]-2 + 0[ ]0 + + 0[ ]0 + + 0[ ]0 + + -------------------- + [[3, 2]] + -------------------- + ... + [[2, 3], [3, -2]] + + We can also construct and display a graph of the bijection + as follows:: + + sage: ret, G = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(build_graph=True) + sage: view(G, tightpage=True) # not tested """ from sage.combinat.rigged_configurations.bijection import RCToKRTBijection bij = RCToKRTBijection(self) @@ -624,6 +656,8 @@ def lusztig_involution(self): RC = RiggedConfigurations(P._cartan_type, reversed(P.dims)) return RC(*self, use_vacancy_numbers=True).to_lowest_weight(I)[0].e_string(aut[i] for i in hw) + # TODO: Move the morphisms to a lazy attribute of RiggedConfigurations + # once #15463 is done def left_split(self): r""" Return the image of ``self`` under the left column splitting @@ -662,7 +696,7 @@ def right_split(self): Return the image of ``self`` under the right column splitting map `\beta^*`. - Let `\ast` denote the :meth:`Lsztig involution` + Let `\ast` denote the :meth:`Lusztig involution` and `\beta` denote the :meth:`left splitting map`, we define the right splitting map by `\beta^* := \ast \circ \beta \circ \ast`. @@ -693,9 +727,9 @@ def right_split(self): """ return self.lusztig_involution().left_split().lusztig_involution() - def delta(self, return_b=False): + def left_box(self, return_b=False): r""" - Return the image of ``self`` under the map basic map `\delta`. + Return the image of ``self`` under the left box removal map `\delta`. The map `\delta : RC(B^{r,1} \otimes B) \to RC(B^{r-1,1} \otimes B)` (if `r = 1`, then we remove the left-most factor) is the @@ -730,10 +764,10 @@ def delta(self, return_b=False): 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 0[ ][ ]0 0[ ]0 - sage: ascii_art(mg.delta()) + sage: ascii_art(mg.left_box()) 0[ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 0[ ]0 0[ ][ ]0 0[ ]0 - sage: x,b = mg.delta(True) + sage: x,b = mg.left_box(True) sage: b -1 """ @@ -763,6 +797,52 @@ def delta(self, return_b=False): return (rc, b) return rc + delta = left_box + + def complement(self): + r""" + Apply the complement morphism `\theta` to ``self``. + + Consider a highest weight rigged configuration `(\nu, J)`, the + complement morphism `\theta : RC(L) \to RC(L)` is given by sending + `(\nu, J) \mapsto (\nu, J')`, where `J'` is obtained by taking the + coriggings `x' = p_i^{(a)} - x`, and then extending as a crystal + morphism. + + EXAMPLES:: + + sage: RC = RiggedConfigurations(['D',4,1], [[1,1],[2,2]]) + sage: mg = RC.module_generators[-1] + sage: ascii_art(mg) + 1[ ][ ]1 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 + 0[ ][ ]0 + sage: ascii_art(mg.complement()) + 1[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 + 0[ ][ ]0 + + sage: lw = mg.to_lowest_weight([1,2,3,4])[0] + sage: ascii_art(lw) + -1[ ][ ]-1 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 + -1[ ]-1 0[ ][ ]0 0[ ]0 0[ ]0 + -1[ ]-1 0[ ]0 + 0[ ]0 + sage: ascii_art(lw.complement()) + -1[ ][ ][ ]-1 0[ ][ ][ ]0 0[ ][ ][ ]0 0[ ][ ][ ]0 + -1[ ]-1 0[ ][ ][ ]0 + sage: lw.complement() == mg.complement().to_lowest_weight([1,2,3,4])[0] + True + """ + P = self.parent() + mg, e_str = self.to_highest_weight(P._cartan_type.classical().index_set()) + nu = [] + rig = [] + for a,p in enumerate(mg): + nu.append(list(p)) + vac_nums = mg.get_vacancy_numbers(a+1) + rig.append( [vac - p.rigging[i] for i,vac in enumerate(vac_nums)] ) + rc = P(partition_list=nu, rigging_list=rig) + return rc.f_string(reversed(e_str)) + def nu(self): r""" Return the list `\nu` of rigged partitions of this rigged From 2874083b12a083c3d644860e09079c1136915622 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 20 Jul 2014 10:40:01 -0700 Subject: [PATCH 11/16] Minor rewording of build_graph param in bijections. --- src/sage/combinat/rigged_configurations/bij_abstract_class.py | 2 +- src/sage/combinat/rigged_configurations/bij_type_B.py | 2 +- src/sage/combinat/rigged_configurations/bij_type_D.py | 2 +- src/sage/combinat/rigged_configurations/bij_type_D_twisted.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index a111e05dd36..121dc375ef7 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -356,7 +356,7 @@ def run(self, verbose=False, build_graph=False): - ``verbose`` -- (default: ``False``) display each step in the bijection - ``build_graph`` -- (default: ``False``) build the graph of each - step in the bijection + step of the bijection EXAMPLES:: diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index 6bf3ff54975..b9adefe8c37 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -534,7 +534,7 @@ def run(self, verbose=False, build_graph=False): - ``verbose`` -- (default: ``False``) display each step in the bijection - ``build_graph`` -- (default: ``False``) build the graph of each - step in the bijection + step of the bijection EXAMPLES:: diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index 0ce409a51f8..496bafcf06b 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -424,7 +424,7 @@ def run(self, verbose=False, build_graph=False): - ``verbose`` -- (default: ``False``) display each step in the bijection - ``build_graph`` -- (default: ``False``) build the graph of each - step in the bijection + step of the bijection EXAMPLES:: diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py index df93f1d8b95..a1fd32883d0 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py @@ -320,7 +320,7 @@ def run(self, verbose=False, build_graph=False): - ``verbose`` -- (default: ``False``) display each step in the bijection - ``build_graph`` -- (default: ``False``) build the graph of each - step in the bijection + step of the bijection EXAMPLES:: From 6552c617321b50a8cf2123e9c85e0e4eaa8d8714 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 21 Jul 2014 09:44:04 -0700 Subject: [PATCH 12/16] Fixed doc, added intertwining doctest, and added build_graph to to_*_crystals. --- .../rigged_configurations/kr_tableaux.py | 2 +- .../rigged_configuration_element.py | 34 +++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/kr_tableaux.py b/src/sage/combinat/rigged_configurations/kr_tableaux.py index 9e4abefb2e6..60358bcc367 100644 --- a/src/sage/combinat/rigged_configurations/kr_tableaux.py +++ b/src/sage/combinat/rigged_configurations/kr_tableaux.py @@ -1369,7 +1369,7 @@ def right_split(self): Let `\ast` denote the :meth:`Lusztig involution`, and `\mathrm{ls}` as the :meth:`left splitting map`. The right splitting map is defined as - \mathrm{rs} := \ast \circ \mathrm{ls} \circ \ast`. + `\mathrm{rs} := \ast \circ \mathrm{ls} \circ \ast`. EXAMPLES:: diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 95d2d382621..f4ae963ac3d 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -584,7 +584,7 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False return (ret, bij._graph) return ret - def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False): + def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False, build_graph=False): r""" Return the corresponding tensor product of Kirillov-Reshetikhin crystals. @@ -596,6 +596,11 @@ def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False - ``display_steps`` -- (default: ``False``) boolean which indicates if we want to output each step in the algorithm + - ``build_graph` -- (default: ``False``) boolean which indicates + if we want to construct and return a graph of the bijection whose + vertices are rigged configurations obtained at each step and edges + are labeled by either the return value of `\delta` or the + doubling/halving map EXAMPLES:: @@ -619,12 +624,21 @@ def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False sage: elt == ret True + + We can also construct and display a graph of the bijection + as follows:: + + sage: ret, G = elt.to_tensor_product_of_kirillov_reshetikhin_crystals(build_graph=True) + sage: view(G, tightpage=True) # not tested """ + if build_graph: + kr_tab, G = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps, build_graph) + return (kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals(), G) kr_tab = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps) return kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals() def lusztig_involution(self): - """ + r""" Return the result of the classical Lusztig involution on ``self``. EXAMPLES:: @@ -642,9 +656,23 @@ def lusztig_involution(self): We check that the Lusztig involution commutes with the bijection:: sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2], [1,2]]) - sage: all(b.to_rigged_configuration().lusztig_involution() + sage: all(b.to_rigged_configuration().lusztig_involution() # long time ....: == b.lusztig_involution().to_rigged_configuration() for b in KRT) True + + We check that the Lusztig involution (under the modification of also + mapping to the highest weight element) intertwines with the + complement map `\theta` (also modified to reverse the tensor factors) + under the bijection `\Phi`:: + + sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2], [2, 1], [1, 2]]) + sage: RCp = RiggedConfigurations(['D', 4, 1], [[1, 2], [2, 1], [2, 2]]) + sage: for mg in RC.module_generators: # long time + ....: y = mg.to_tensor_product_of_kirillov_reshetikhin_tableaux() + ....: hw = y.lusztig_involution().to_highest_weight([1,2,3,4])[0] + ....: c = RCp(*mg.complement()) + ....: hwc = c.to_tensor_product_of_kirillov_reshetikhin_tableaux() + ....: assert hw == hwc """ P = self.parent() Cl = P.cartan_type().classical() From a985081eb8bb47abb8e78546eaf7aa4638eddc77 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 21 Jul 2014 09:56:09 -0700 Subject: [PATCH 13/16] Tweaked wording of param display_steps doc. --- .../rigged_configurations/rigged_configuration_element.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index f4ae963ac3d..ecc218f554c 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -509,7 +509,7 @@ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False INPUT: - ``display_steps`` -- (default: ``False``) boolean which indicates - if we want to output each step in the algorithm + if we want to print each step in the algorithm - ``build_graph` -- (default: ``False``) boolean which indicates if we want to construct and return a graph of the bijection whose vertices are rigged configurations obtained at each step and edges @@ -595,7 +595,7 @@ def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False INPUT: - ``display_steps`` -- (default: ``False``) boolean which indicates - if we want to output each step in the algorithm + if we want to print each step in the algorithm - ``build_graph` -- (default: ``False``) boolean which indicates if we want to construct and return a graph of the bijection whose vertices are rigged configurations obtained at each step and edges From 51c8ba25219b7edf6c3fa69bd5cce931a12c799e Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 22 Jul 2014 19:18:37 -0700 Subject: [PATCH 14/16] Changed complement -> complement_rigging and fixed right_split on RC side. --- .../rigged_configuration_element.py | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index ecc218f554c..b7664dc7c2a 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -670,7 +670,7 @@ def lusztig_involution(self): sage: for mg in RC.module_generators: # long time ....: y = mg.to_tensor_product_of_kirillov_reshetikhin_tableaux() ....: hw = y.lusztig_involution().to_highest_weight([1,2,3,4])[0] - ....: c = RCp(*mg.complement()) + ....: c = RCp(*mg.complement_rigging()) ....: hwc = c.to_tensor_product_of_kirillov_reshetikhin_tableaux() ....: assert hw == hwc """ @@ -724,10 +724,11 @@ def right_split(self): Return the image of ``self`` under the right column splitting map `\beta^*`. - Let `\ast` denote the :meth:`Lusztig involution` + Let `\theta` denote the + :meth:`complement rigging map` and `\beta` denote the :meth:`left splitting map`, we define the right splitting map by - `\beta^* := \ast \circ \beta \circ \ast`. + `\beta^* := \theta \circ \beta \circ \theta`. EXAMPLES:: @@ -738,9 +739,9 @@ def right_split(self): 0[ ][ ]0 0[ ][ ]0 0[ ]0 0[ ][ ]0 0[ ]0 sage: ascii_art(mg.right_split()) - 0[ ][ ]0 0[ ][ ]0 1[ ][ ]0 0[ ]0 - 0[ ][ ]0 1[ ][ ]0 0[ ]0 - 1[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ][ ]0 1[ ][ ]1 0[ ]0 + 0[ ][ ]0 1[ ][ ]1 0[ ]0 + 1[ ][ ]1 0[ ]0 sage: RC = RiggedConfigurations(['D',4,1], [[2,2],[1,2]]) sage: elt = RC(partition_list=[[3,1], [2,2,1], [2,1], [2]]) @@ -752,8 +753,15 @@ def right_split(self): -1[ ][ ][ ]-1 0[ ][ ]0 -1[ ][ ]-1 1[ ][ ]1 1[ ]0 0[ ][ ]0 -1[ ]-1 0[ ]0 + + We check that this commutes with the right spliting map:: + + sage: RC = RiggedConfigurations(['A', 3, 1], [[1,1], [2,2]]) + sage: all(rc.right_split().to_tensor_product_of_kirillov_reshetikhin_tableaux() + ....: == rc.to_tensor_product_of_kirillov_reshetikhin_tableaux().right_split() for rc in RC) + True """ - return self.lusztig_involution().left_split().lusztig_involution() + return self.complement_rigging(True).left_split().complement_rigging(True) def left_box(self, return_b=False): r""" @@ -827,15 +835,22 @@ def left_box(self, return_b=False): delta = left_box - def complement(self): + def complement_rigging(self, reverse_factors=False): r""" - Apply the complement morphism `\theta` to ``self``. + Apply the complement rigging morphism `\theta` to ``self``. Consider a highest weight rigged configuration `(\nu, J)`, the - complement morphism `\theta : RC(L) \to RC(L)` is given by sending - `(\nu, J) \mapsto (\nu, J')`, where `J'` is obtained by taking the - coriggings `x' = p_i^{(a)} - x`, and then extending as a crystal - morphism. + complement rigging morphism `\theta : RC(L) \to RC(L)` is given by + sending `(\nu, J) \mapsto (\nu, J')`, where `J'` is obtained by + taking the coriggings `x' = p_i^{(a)} - x`, and then extending as + a crystal morphism. (The name comes from taking the complement + partition for the riggings in a `m_i^{(a)} \times p_i^{(a)}` box.) + + INPUT: + + - ``reverse_factors`` -- (default: ``False``) if ``True``, then this + returns an element in `RC(B')` where `B'` is the tensor factors + of ``self`` in reverse order EXAMPLES:: @@ -844,7 +859,7 @@ def complement(self): sage: ascii_art(mg) 1[ ][ ]1 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 - sage: ascii_art(mg.complement()) + sage: ascii_art(mg.complement_rigging()) 1[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 @@ -854,13 +869,20 @@ def complement(self): -1[ ]-1 0[ ][ ]0 0[ ]0 0[ ]0 -1[ ]-1 0[ ]0 0[ ]0 - sage: ascii_art(lw.complement()) + sage: ascii_art(lw.complement_rigging()) -1[ ][ ][ ]-1 0[ ][ ][ ]0 0[ ][ ][ ]0 0[ ][ ][ ]0 -1[ ]-1 0[ ][ ][ ]0 - sage: lw.complement() == mg.complement().to_lowest_weight([1,2,3,4])[0] + sage: lw.complement_rigging() == mg.complement_rigging().to_lowest_weight([1,2,3,4])[0] True + + sage: mg.complement_rigging(True).parent() + Rigged configurations of type ['D', 4, 1] and factor(s) ((2, 2), (1, 1)) """ P = self.parent() + if reverse_factors: + from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations + P = RiggedConfigurations(P._cartan_type, reversed(P.dims)) + mg, e_str = self.to_highest_weight(P._cartan_type.classical().index_set()) nu = [] rig = [] From 013737b07b3e0cb0edfc970bc9734035a7b7df08 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 22 Jul 2014 19:55:07 -0700 Subject: [PATCH 15/16] Added right_box method for symmetry. --- .../rigged_configuration_element.py | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index b7664dc7c2a..72a70c1d44e 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -773,7 +773,7 @@ def left_box(self, return_b=False): tensor products of Kirillov-Reshetikhin tableaux. For more information, see :meth:`to_tensor_product_of_kirillov_reshetikhin_tableaux()`. - We can extend `\delta` when tthe left-most factor is not a single + We can extend `\delta` when the left-most factor is not a single column by precomposing with a :meth:`left_split()`. .. NOTE:: @@ -806,6 +806,8 @@ def left_box(self, return_b=False): sage: x,b = mg.left_box(True) sage: b -1 + sage: b.parent() + The crystal of letters for type ['C', 4] """ # Don't do spinor cases P = self.parent() @@ -830,11 +832,62 @@ def left_box(self, return_b=False): RC = RiggedConfigurations(ct, bij.cur_dims) rc = RC(*bij.cur_partitions) if return_b: - return (rc, b) + from sage.combinat.crystals.letters import CrystalOfLetters + L = CrystalOfLetters(self.parent()._cartan_type.classical()) + return (rc, L(b)) return rc delta = left_box + def right_box(self, return_b=False): + r""" + Return the image of ``self`` under the right box removal map + `\delta^*`. + + Let `\theta` denote the + :meth:`complement rigging map` + and `\delta` denote the :meth:`left box removal map`, we + define the right box removal map by + `\delta^* := \theta \circ \delta \circ \theta`. + + .. NOTE:: + + Due to the special nature of the bijection for the spinor cases in + types `D_n^{(1)}`, `B_n^{(1)}`, and `A_{2n-1}^{(2)}`, this map is + not defined in these cases. + + INPUT: + + - ``return_b`` -- (default: ``False``) whether to return the + resulting letter from `\delta^*` + + OUTPUT: + + The resulting rigged configuration or if ``return_b`` is ``True``, + then a tuple of the resulting rigged configuration and the letter. + + EXAMPLES:: + + sage: RC = RiggedConfigurations(['C',4,1], [[3,2]]) + sage: mg = RC.module_generators[-1] + sage: ascii_art(mg) + 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ][ ]0 0[ ]0 + sage: ascii_art(mg.right_box()) + 0[ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 + 0[ ]0 0[ ][ ]0 0[ ]0 + sage: x,b = mg.right_box(True) + sage: b + -1 + sage: b.parent() + The crystal of letters for type ['C', 4] + """ + y = self.complement_rigging(True).left_box(return_b) + if return_b: + return (y[0].complement_rigging(True), y[1]) + return y.complement_rigging(True) + def complement_rigging(self, reverse_factors=False): r""" Apply the complement rigging morphism `\theta` to ``self``. From 1e15993eed4b02fed79649aca88f6a6a6d7d843b Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 25 Jul 2014 11:01:11 -0700 Subject: [PATCH 16/16] Removed lusztig_involution and right_box. --- .../rigged_configuration_element.py | 109 +++--------------- 1 file changed, 13 insertions(+), 96 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 72a70c1d44e..974e699aba1 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -637,53 +637,6 @@ def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False kr_tab = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps) return kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals() - def lusztig_involution(self): - r""" - Return the result of the classical Lusztig involution on ``self``. - - EXAMPLES:: - - sage: RC = RiggedConfigurations(['D',4,1], [[2,2]]) - sage: mg = RC.module_generators[1] - sage: ascii_art(mg.lusztig_involution()) - 0[ ][ ][ ]0 -1[ ][ ][ ]-1 0[ ][ ][ ]0 0[ ][ ][ ]0 - -1[ ][ ][ ]-1 - sage: elt = mg.f_string([2,1,3,2]) - sage: ascii_art(elt.lusztig_involution()) - 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 -2[ ][ ][ ]-2 - 0[ ][ ]0 - - We check that the Lusztig involution commutes with the bijection:: - - sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2], [1,2]]) - sage: all(b.to_rigged_configuration().lusztig_involution() # long time - ....: == b.lusztig_involution().to_rigged_configuration() for b in KRT) - True - - We check that the Lusztig involution (under the modification of also - mapping to the highest weight element) intertwines with the - complement map `\theta` (also modified to reverse the tensor factors) - under the bijection `\Phi`:: - - sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2], [2, 1], [1, 2]]) - sage: RCp = RiggedConfigurations(['D', 4, 1], [[1, 2], [2, 1], [2, 2]]) - sage: for mg in RC.module_generators: # long time - ....: y = mg.to_tensor_product_of_kirillov_reshetikhin_tableaux() - ....: hw = y.lusztig_involution().to_highest_weight([1,2,3,4])[0] - ....: c = RCp(*mg.complement_rigging()) - ....: hwc = c.to_tensor_product_of_kirillov_reshetikhin_tableaux() - ....: assert hw == hwc - """ - P = self.parent() - Cl = P.cartan_type().classical() - I = Cl.index_set() - aut = Cl.opposition_automorphism() - hw = self.to_highest_weight(I)[1] - hw.reverse() - from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations - RC = RiggedConfigurations(P._cartan_type, reversed(P.dims)) - return RC(*self, use_vacancy_numbers=True).to_lowest_weight(I)[0].e_string(aut[i] for i in hw) - # TODO: Move the morphisms to a lazy attribute of RiggedConfigurations # once #15463 is done def left_split(self): @@ -839,55 +792,6 @@ def left_box(self, return_b=False): delta = left_box - def right_box(self, return_b=False): - r""" - Return the image of ``self`` under the right box removal map - `\delta^*`. - - Let `\theta` denote the - :meth:`complement rigging map` - and `\delta` denote the :meth:`left box removal map`, we - define the right box removal map by - `\delta^* := \theta \circ \delta \circ \theta`. - - .. NOTE:: - - Due to the special nature of the bijection for the spinor cases in - types `D_n^{(1)}`, `B_n^{(1)}`, and `A_{2n-1}^{(2)}`, this map is - not defined in these cases. - - INPUT: - - - ``return_b`` -- (default: ``False``) whether to return the - resulting letter from `\delta^*` - - OUTPUT: - - The resulting rigged configuration or if ``return_b`` is ``True``, - then a tuple of the resulting rigged configuration and the letter. - - EXAMPLES:: - - sage: RC = RiggedConfigurations(['C',4,1], [[3,2]]) - sage: mg = RC.module_generators[-1] - sage: ascii_art(mg) - 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 - 0[ ][ ]0 0[ ][ ]0 0[ ]0 - 0[ ][ ]0 0[ ]0 - sage: ascii_art(mg.right_box()) - 0[ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0 - 0[ ]0 0[ ][ ]0 0[ ]0 - sage: x,b = mg.right_box(True) - sage: b - -1 - sage: b.parent() - The crystal of letters for type ['C', 4] - """ - y = self.complement_rigging(True).left_box(return_b) - if return_b: - return (y[0].complement_rigging(True), y[1]) - return y.complement_rigging(True) - def complement_rigging(self, reverse_factors=False): r""" Apply the complement rigging morphism `\theta` to ``self``. @@ -930,6 +834,19 @@ def complement_rigging(self, reverse_factors=False): sage: mg.complement_rigging(True).parent() Rigged configurations of type ['D', 4, 1] and factor(s) ((2, 2), (1, 1)) + + We check that the Lusztig involution (under the modification of also + mapping to the highest weight element) intertwines with the + complement map `\theta` (that reverses the tensor factors) + under the bijection `\Phi`:: + + sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2], [2, 1], [1, 2]]) + sage: for mg in RC.module_generators: # long time + ....: y = mg.to_tensor_product_of_kirillov_reshetikhin_tableaux() + ....: hw = y.lusztig_involution().to_highest_weight([1,2,3,4])[0] + ....: c = mg.complement_rigging(True) + ....: hwc = c.to_tensor_product_of_kirillov_reshetikhin_tableaux() + ....: assert hw == hwc """ P = self.parent() if reverse_factors: