def _call_(self, x): r""" Return the image of ``x`` in the rigged configuration model of `B(\infty)`. EXAMPLES:: sage: RC = crystals.infinity.RiggedConfigurations(['A',3]) sage: T = crystals.infinity.Tableaux(['A',3]) sage: phi = RC.coerce_map_from(T) sage: x = T.an_element().f_string([2,2,1,1,3,2,1,2,1,3]) sage: y = phi(x); ascii_art(y) -4[ ][ ][ ][ ]-2 -3[ ][ ][ ]-1 -1[ ][ ]-1 -2[ ]-1 sage: (~phi)(y) == x True """ conj = x.to_tableau().conjugate() ct = self.domain().cartan_type() act = ct.affine() TP = TensorProductOfKirillovReshetikhinTableaux(act, [[r,1] for r in conj.shape()]) elt = TP(pathlist=[reversed(row) for row in conj]) if ct.type() == 'A': bij = KRTToRCBijectionTypeA(elt) elif ct.type() == 'B': bij = MLTToRCBijectionTypeB(elt) elif ct.type() == 'C': bij = KRTToRCBijectionTypeC(elt) elif ct.type() == 'D': bij = MLTToRCBijectionTypeD(elt) else: raise NotImplementedError("bijection of type {} not yet implemented".format(ct)) return self.codomain()(bij.run())
def next_state(self, val): r""" Build the next state for type `A_{2n-1}^{(2)}`. TESTS:: sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A', 5, 2], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_A2_odd import KRTToRCBijectionTypeA2Odd sage: bijection = KRTToRCBijectionTypeA2Odd(KRT(pathlist=[[-2,3]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [3]) sage: bijection.next_state(3) """ # Note that we must subtract 1 from n to match the indices. n = self.n tableau_height = len(self.cur_path[0]) - 1 # If it is a regular value, we follow the A_n rules if val > 0: KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] else: max_width = 1 # Add cells similar to type A_n but we move to the right until we # reach the value of n for a in range(pos_val - 1, n): max_width = self.ret_rig_con[a].insert_cell(max_width) # Now go back following the regular A_n rules for a in reversed(range(tableau_height, n - 1)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if pos_val <= tableau_height: for a in range(pos_val-1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1)
def next_state(self, val): r""" Build the next state for type `A_{2n-1}^{(2)}`. TESTS:: sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['A', 5, 2], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_A2_odd import KRTToRCBijectionTypeA2Odd sage: bijection = KRTToRCBijectionTypeA2Odd(KRT(pathlist=[[-2,3]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [3]) sage: bijection.next_state(3) """ # Note that we must subtract 1 from n to match the indices. n = self.n tableau_height = len(self.cur_path[0]) - 1 # If it is a regular value, we follow the A_n rules if val > 0: KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] else: max_width = 1 # Add cells similar to type A_n but we move to the right until we # reach the value of n for a in range(pos_val - 1, n): max_width = self.ret_rig_con[a].insert_cell(max_width) # Now go back following the regular A_n rules for a in reversed(range(tableau_height, n - 1)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if pos_val <= tableau_height: for a in range(pos_val - 1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1)
def KRTToRCBijection(tp_krt): r""" Return the correct KR tableaux to rigged configuration bijection helper class. TESTS:: sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A', 4, 1], [[2,1]]) sage: from sage.combinat.rigged_configurations.bijection import KRTToRCBijection sage: bijection = KRTToRCBijection(KRT(pathlist=[[5,2]])) """ ct = tp_krt.cartan_type() typ = ct.type() if ct.is_untwisted_affine(): if typ == 'A': return KRTToRCBijectionTypeA(tp_krt) if typ == 'B': return KRTToRCBijectionTypeB(tp_krt) if typ == 'C': return KRTToRCBijectionTypeC(tp_krt) if typ == 'D': return KRTToRCBijectionTypeD(tp_krt) if typ == 'E': if ct.classical().rank() < 8: return KRTToRCBijectionTypeE67(tp_krt) #if typ == 'F': #if typ == 'G': else: if typ == 'BC': # A_{2n}^{(2)} return KRTToRCBijectionTypeA2Even(tp_krt) typ = ct.dual().type() if typ == 'BC': # A_{2n}^{(2)\dagger} return KRTToRCBijectionTypeA2Dual(tp_krt) if typ == 'B': # A_{2n-1}^{(2)} return KRTToRCBijectionTypeA2Odd(tp_krt) if typ == 'C': # D_{n+1}^{(2)} return KRTToRCBijectionTypeDTwisted(tp_krt) #if typ == 'F': # E_6^{(2)} if typ == 'G': # D_4^{(3)} return KRTToRCBijectionTypeDTri(tp_krt) raise NotImplementedError
def next_state(self, val): r""" Build the next state for type `D_4^{(3)}`. TESTS:: sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['D', 4, 3], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_D_tri import KRTToRCBijectionTypeDTri sage: bijection = KRTToRCBijectionTypeDTri(KRT(pathlist=[[-1,2]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [2]) sage: bijection.next_state(2) """ tableau_height = len(self.cur_path[0]) - 1 if val == 'E': self.ret_rig_con[0].insert_cell(0) self.ret_rig_con[1].insert_cell(0) if tableau_height == 0: self.ret_rig_con[0].insert_cell(0) self._update_vacancy_nums(0) self._update_vacancy_nums(1) self._update_partition_values(0) self._update_partition_values(1) return if val > 0: # If it is a regular value, we follow the A_n rules KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val if pos_val == 0: if len(self.ret_rig_con[0]) > 0: max_width = self.ret_rig_con[0][0] else: max_width = 1 max_width = self.ret_rig_con[0].insert_cell(max_width) width_n = max_width + 1 # Follow regular A_n rules for a in reversed(range(tableau_height, 2)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(0) self._update_partition_values(0) self._update_vacancy_nums(1) self._update_partition_values(1) # Make the largest string at \nu^{(1)} quasi-singular p = self.ret_rig_con[0] num_rows = len(p) for i in range(num_rows): if p._list[i] == width_n: j = i+1 while j < num_rows and p._list[j] == width_n \ and p.vacancy_numbers[j] == p.rigging[j]: j += 1 p.rigging[j-1] -= 1 break return case_S = [None] * 2 pos_val = -val if pos_val < 3: # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] else: max_width = 1 # Add cells similar to type A_n but we move to the right for a in range(pos_val - 1, 2): max_width = self.ret_rig_con[a].insert_cell(max_width) case_S[a] = max_width else: if len(self.ret_rig_con[0]) > 0: max_width = self.ret_rig_con[0][0] else: max_width = 1 # Special case for going through 0 # If we find a quasi-singular string first, then we are in case (Q, S) # otherwise we will find a singular string and insert 2 cells P = self.ret_rig_con[0] num_rows = len(P) case_QS = False for i in range(num_rows + 1): if i == num_rows: max_width = 0 if case_QS: P._list.append(1) P.vacancy_numbers.append(None) # Go through our partition until we find a length of greater than 1 j = len(P._list) - 1 while j >= 0 and P._list[j] == 1: j -= 1 P.rigging.insert(j + 1, None) width_n = 1 else: # Go through our partition until we find a length of greater than 2 j = len(P._list) - 1 while j >= 0 and P._list[j] <= 2: j -= 1 P._list.insert(j+1, 2) P.vacancy_numbers.insert(j+1, None) P.rigging.insert(j+1, None) break elif P._list[i] <= max_width: if P.vacancy_numbers[i] == P.rigging[i]: max_width = P._list[i] if case_QS: P._list[i] += 1 width_n = P._list[i] P.rigging[i] = None else: j = i - 1 while j >= 0 and P._list[j] <= max_width + 2: P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list.pop(i) P._list.insert(j+1, max_width + 2) P.rigging[j+1] = None break elif P.vacancy_numbers[i] - 1 == P.rigging[i] and not case_QS: case_QS = True P._list[i] += 1 P.rigging[i] = None # No need to set max_width here since we will find a singular string # Now go back following the regular C_n (ish) rules if case_S[1] == max_width: P = self.ret_rig_con[1] # Special case when adding twice to the first row if P.rigging[0] is None: P._list[0] += 1 else: for i in reversed(range(1, len(P))): if P.rigging[i] is None: j = i - 1 while j >= 0 and P._list[j] == P._list[i]: P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list[j+1] += 1 P.rigging[j+1] = None break else: max_width = self.ret_rig_con[1].insert_cell(max_width) if tableau_height == 0: if case_S[0] == max_width: P = self.ret_rig_con[0] # Since this is on the way back, the added string we want # to bump will never be the first (largest) string for i in reversed(range(1, len(P))): if P.rigging[i] is None: j = i - 1 while j >= 0 and P._list[j] == P._list[i]: P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list[j+1] += 1 P.rigging[j+1] = None break else: max_width = self.ret_rig_con[0].insert_cell(max_width) self._update_vacancy_nums(0) self._update_partition_values(0) self._update_vacancy_nums(1) self._update_partition_values(1) if case_QS: # Make the new string quasi-singular num_rows = len(P) for i in range(num_rows): if P._list[i] == width_n: j = i+1 while j < num_rows and P._list[j] == width_n \ and P.vacancy_numbers[j] == P.rigging[j]: j += 1 P.rigging[j-1] -= 1 break
def next_state(self, val): r""" Build the next state for type `D_{n+1}^{(2)}`. TESTS:: sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['D', 4, 2], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_D_twisted import KRTToRCBijectionTypeDTwisted sage: bijection = KRTToRCBijectionTypeDTwisted(KRT(pathlist=[[-1,2]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [2]) sage: bijection.next_state(2) """ n = self.n tableau_height = len(self.cur_path[0]) - 1 if val == 'E': KRTToRCBijectionTypeA2Even.next_state(self, val) return elif val > 0: # If it is a regular value, we follow the A_n rules KRTToRCBijectionTypeA.next_state(self, val) if tableau_height >= n - 1: self._correct_vacancy_nums() return pos_val = -val if pos_val == 0: if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[n-1][0] else: max_width = 1 max_width = self.ret_rig_con[n-1].insert_cell(max_width) width_n = max_width + 1 # Follow regular A_n rules for a in reversed(range(tableau_height, n-1)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) self._update_vacancy_nums(tableau_height) if tableau_height >= n - 1: self._correct_vacancy_nums() self._update_partition_values(tableau_height) if tableau_height > 0: self._update_vacancy_nums(tableau_height-1) self._update_partition_values(tableau_height-1) # Make the new string at n quasi-singular p = self.ret_rig_con[n-1] num_rows = len(p) for i in range(num_rows): if p._list[i] == width_n: j = i+1 while j < num_rows and p._list[j] == width_n \ and p.vacancy_numbers[j] == p.rigging[j]: j += 1 p.rigging[j-1] -= 1 break return case_S = [None] * n pos_val = -val # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] else: max_width = 1 # Add cells similar to type A_n but we move to the right until we # reach the value of n-1 for a in range(pos_val - 1, n-1): max_width = self.ret_rig_con[a].insert_cell(max_width) case_S[a] = max_width # Special case for n # If we find a quasi-singular string first, then we are in case (Q, S) # otherwise we will find a singular string and insert 2 cells partition = self.ret_rig_con[n-1] num_rows = len(partition) case_QS = False for i in range(num_rows + 1): if i == num_rows: max_width = 0 if case_QS: partition._list.append(1) partition.vacancy_numbers.append(None) # Go through our partition until we find a length of greater than 1 j = len(partition._list) - 1 while j >= 0 and partition._list[j] == 1: j -= 1 partition.rigging.insert(j + 1, None) width_n = 1 else: # Go through our partition until we find a length of greater than 2 j = len(partition._list) - 1 while j >= 0 and partition._list[j] <= 2: j -= 1 partition._list.insert(j+1, 2) partition.vacancy_numbers.insert(j+1, None) partition.rigging.insert(j+1, None) break elif partition._list[i] <= max_width: if partition.vacancy_numbers[i] == partition.rigging[i]: max_width = partition._list[i] if case_QS: partition._list[i] += 1 width_n = partition._list[i] partition.rigging[i] = None else: j = i - 1 while j >= 0 and partition._list[j] <= max_width + 2: partition.rigging[j+1] = partition.rigging[j] # Shuffle it along j -= 1 partition._list.pop(i) partition._list.insert(j+1, max_width + 2) partition.rigging[j+1] = None break elif partition.vacancy_numbers[i] - 1 == partition.rigging[i] and not case_QS: case_QS = True partition._list[i] += 1 partition.rigging[i] = None # No need to set max_width here since we will find a singular string # Now go back following the regular C_n (ish) rules for a in reversed(range(tableau_height, n-1)): if case_S[a] == max_width: self._insert_cell_case_S(self.ret_rig_con[a]) else: max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions self._update_vacancy_nums(tableau_height) if tableau_height >= n - 1: self._correct_vacancy_nums() self._update_partition_values(tableau_height) if pos_val <= tableau_height: for a in range(pos_val-1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) if case_QS: # Make the new string quasi-singular num_rows = len(partition) for i in range(num_rows): if partition._list[i] == width_n: j = i+1 while j < num_rows and partition._list[j] == width_n \ and partition.vacancy_numbers[j] == partition.rigging[j]: j += 1 partition.rigging[j-1] -= 1 break
def next_state(self, val): r""" Build the next state for type `C_n^{(1)}`. TESTS:: sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['C', 3, 1], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC sage: bijection = KRTToRCBijectionTypeC(KRT(pathlist=[[-1,2]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [2]) sage: bijection.next_state(2) """ # Note that we must subtract 1 from n to match the indices. n = self.n tableau_height = len(self.cur_path[0]) - 1 # If it is a regular value, we follow the A_n rules if val > 0: KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val case_S = [None] * n # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] else: max_width = 1 # Special case for inserting -n if pos_val == n: max_width *= 2 # Add cells similar to type A_n but we move to the right until we # reach the value of n for a in range(pos_val - 1, n - 1): max_width = self.ret_rig_con[a].insert_cell(max_width) case_S[a] = max_width # Special case for n max_width = self.ret_rig_con[n-1].insert_cell(max_width // 2) * 2 # Now go back following the special C_n rules for a in reversed(range(tableau_height, n - 1)): if case_S[a] == max_width: self._insert_cell_case_S(self.ret_rig_con[a]) else: max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if pos_val <= tableau_height: for a in range(pos_val-1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1)
def next_state(self, val): r""" Build the next state for type `D_4^{(3)}`. TESTS:: sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['D', 4, 3], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_D_tri import KRTToRCBijectionTypeDTri sage: bijection = KRTToRCBijectionTypeDTri(KRT(pathlist=[[-1,2]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [2]) sage: bijection.next_state(2) """ tableau_height = len(self.cur_path[0]) - 1 if val == 'E': self.ret_rig_con[0].insert_cell(0) self.ret_rig_con[1].insert_cell(0) if tableau_height == 0: self.ret_rig_con[0].insert_cell(0) self._update_vacancy_nums(0) self._update_vacancy_nums(1) self._update_partition_values(0) self._update_partition_values(1) return if val > 0: # If it is a regular value, we follow the A_n rules KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val if pos_val == 0: if len(self.ret_rig_con[0]) > 0: max_width = self.ret_rig_con[0][0] else: max_width = 1 max_width = self.ret_rig_con[0].insert_cell(max_width) width_n = max_width + 1 # Follow regular A_n rules for a in reversed(range(tableau_height, 2)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(0) self._update_partition_values(0) self._update_vacancy_nums(1) self._update_partition_values(1) # Make the largest string at \nu^{(1)} quasi-singular p = self.ret_rig_con[0] num_rows = len(p) for i in range(num_rows): if p._list[i] == width_n: j = i + 1 while j < num_rows and p._list[j] == width_n \ and p.vacancy_numbers[j] == p.rigging[j]: j += 1 p.rigging[j - 1] -= 1 break return case_S = [None] * 2 pos_val = -val if pos_val < 3: # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] else: max_width = 1 # Add cells similar to type A_n but we move to the right for a in range(pos_val - 1, 2): max_width = self.ret_rig_con[a].insert_cell(max_width) case_S[a] = max_width else: if len(self.ret_rig_con[0]) > 0: max_width = self.ret_rig_con[0][0] else: max_width = 1 # Special case for going through 0 # If we find a quasi-singular string first, then we are in case (Q, S) # otherwise we will find a singular string and insert 2 cells P = self.ret_rig_con[0] num_rows = len(P) case_QS = False for i in range(num_rows + 1): if i == num_rows: max_width = 0 if case_QS: P._list.append(1) P.vacancy_numbers.append(None) # Go through our partition until we find a length of greater than 1 j = len(P._list) - 1 while j >= 0 and P._list[j] == 1: j -= 1 P.rigging.insert(j + 1, None) width_n = 1 else: # Go through our partition until we find a length of greater than 2 j = len(P._list) - 1 while j >= 0 and P._list[j] <= 2: j -= 1 P._list.insert(j + 1, 2) P.vacancy_numbers.insert(j + 1, None) P.rigging.insert(j + 1, None) break elif P._list[i] <= max_width: if P.vacancy_numbers[i] == P.rigging[i]: max_width = P._list[i] if case_QS: P._list[i] += 1 width_n = P._list[i] P.rigging[i] = None else: j = i - 1 while j >= 0 and P._list[j] <= max_width + 2: P.rigging[j + 1] = P.rigging[j] # Shuffle it along j -= 1 P._list.pop(i) P._list.insert(j + 1, max_width + 2) P.rigging[j + 1] = None break elif P.vacancy_numbers[i] - 1 == P.rigging[i] and not case_QS: case_QS = True P._list[i] += 1 P.rigging[i] = None # No need to set max_width here since we will find a singular string # Now go back following the regular C_n (ish) rules if case_S[1] == max_width: P = self.ret_rig_con[1] # Special case when adding twice to the first row if P.rigging[0] is None: P._list[0] += 1 else: for i in reversed(range(1, len(P))): if P.rigging[i] is None: j = i - 1 while j >= 0 and P._list[j] == P._list[i]: P.rigging[j + 1] = P.rigging[j] # Shuffle it along j -= 1 P._list[j + 1] += 1 P.rigging[j + 1] = None break else: max_width = self.ret_rig_con[1].insert_cell(max_width) if tableau_height == 0: if case_S[0] == max_width: P = self.ret_rig_con[0] # Since this is on the way back, the added string we want # to bump will never be the first (largest) string for i in reversed(range(1, len(P))): if P.rigging[i] is None: j = i - 1 while j >= 0 and P._list[j] == P._list[i]: P.rigging[j + 1] = P.rigging[j] # Shuffle it along j -= 1 P._list[j + 1] += 1 P.rigging[j + 1] = None break else: max_width = self.ret_rig_con[0].insert_cell(max_width) self._update_vacancy_nums(0) self._update_partition_values(0) self._update_vacancy_nums(1) self._update_partition_values(1) if case_QS: # Make the new string quasi-singular num_rows = len(P) for i in range(num_rows): if P._list[i] == width_n: j = i + 1 while j < num_rows and P._list[j] == width_n \ and P.vacancy_numbers[j] == P.rigging[j]: j += 1 P.rigging[j - 1] -= 1 break
def next_state(self, val): r""" Build the next state for type `A_{2n}^{(2)\dagger}`. TESTS:: sage: KRT = TensorProductOfKirillovReshetikhinTableaux(CartanType(['A', 4, 2]).dual(), [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_A2_dual import KRTToRCBijectionTypeA2Dual sage: bijection = KRTToRCBijectionTypeA2Dual(KRT(pathlist=[[-1,2]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [2]) sage: bijection.next_state(2) """ n = self.n tableau_height = len(self.cur_path[0]) - 1 if val > 0: # If it is a regular value, we follow the A_n rules KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val if pos_val == 0: if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[n - 1][0] else: max_width = 1 max_width = self.ret_rig_con[n - 1].insert_cell(max_width) width_n = max_width + 1 # Follow regular A_n rules for a in reversed(range(tableau_height, n - 1)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) # Make the new string at n quasi-singular p = self.ret_rig_con[n - 1] for i in range(len(p)): if p._list[i] == width_n: p.rigging[i] = p.rigging[i] - QQ(1) / QQ(2) break return case_S = [None] * n pos_val = -val # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] else: max_width = 1 # Add cells similar to type A_n but we move to the right until we # reach the value of n-1 for a in range(pos_val - 1, n - 1): max_width = self.ret_rig_con[a].insert_cell(max_width) case_S[a] = max_width # Special case for n # If we find a quasi-singular string first, then we are in case (Q, S) # otherwise we will find a singular string and insert 2 cells partition = self.ret_rig_con[n - 1] num_rows = len(partition) case_QS = False for i in range(num_rows + 1): if i == num_rows: max_width = 0 if case_QS: partition._list.append(1) partition.vacancy_numbers.append(None) # Go through our partition until we find a length of greater than 1 j = len(partition._list) - 1 while j >= 0 and partition._list[j] == 1: j -= 1 partition.rigging.insert(j + 1, None) width_n = 1 else: # Go through our partition until we find a length of greater than 2 j = len(partition._list) - 1 while j >= 0 and partition._list[j] <= 2: j -= 1 partition._list.insert(j + 1, 2) partition.vacancy_numbers.insert(j + 1, None) partition.rigging.insert(j + 1, None) break elif partition._list[i] <= max_width: if partition.vacancy_numbers[i] == partition.rigging[i]: max_width = partition._list[i] if case_QS: partition._list[i] += 1 width_n = partition._list[i] partition.rigging[i] = None else: j = i - 1 while j >= 0 and partition._list[j] <= max_width + 2: partition.rigging[j + 1] = partition.rigging[ j] # Shuffle it along j -= 1 partition._list.pop(i) partition._list.insert(j + 1, max_width + 2) partition.rigging[j + 1] = None break elif partition.vacancy_numbers[i] - QQ(1) / QQ( 2) == partition.rigging[i] and not case_QS: case_QS = True partition._list[i] += 1 partition.rigging[i] = None # No need to set max_width here since we will find a singular string # Now go back following the regular C_n (ish) rules for a in reversed(range(tableau_height, n - 1)): if case_S[a] == max_width: self._insert_cell_case_S(self.ret_rig_con[a]) else: max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if pos_val <= tableau_height: for a in range(pos_val - 1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) if case_QS: # Make the new string quasi-singular num_rows = len(partition) for i in range(num_rows): if partition._list[i] == width_n: partition.rigging[i] = partition.rigging[i] - QQ(1) / QQ(2) break
def next_state(self, val): r""" Build the next state for type `D_n^{(1)}`. TESTS:: sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['D', 4, 1], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_D import KRTToRCBijectionTypeD sage: bijection = KRTToRCBijectionTypeD(KRT(pathlist=[[5,3]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [3]) sage: bijection.next_state(3) """ # Note that type D_n only contains the (absolute) values between 1 and n # (unlike type A_n which is 1 to n+1). Thus we only need to subtract 1 # to match the indices. # Also note that we must subtract 1 from n to match the indices as well. n = self.n tableau_height = len(self.cur_path[0]) - 1 # If it is a regular value, we follow the A_n rules if val > 0: KRTToRCBijectionTypeA.next_state(self, val) # If we are inserting n-1 (which will only update nu[a] for a <= # n-1), we need to update the vacancy number of nu[n] as well if val == n - 1: self._update_vacancy_nums(val) if tableau_height >= n - 2: self._correct_vacancy_nums() return pos_val = -val if pos_val == n: # Special case for `\overline{n}` and adding to make height `n` # where we only update the vacancy numbers # This only occurs with `r = n - 1` if self.cur_dims[0][0] == n - 1 and tableau_height == n - 1: self._update_vacancy_nums(n - 2) self._update_vacancy_nums(n - 1) self._correct_vacancy_nums() return if len(self.ret_rig_con[n - 1]) > 0: max_width = self.ret_rig_con[n - 1][0] + 1 else: max_width = 1 # Update the last one and skip a rigged partition max_width = self.ret_rig_con[n - 1].insert_cell(max_width) for a in reversed(range(tableau_height, n - 2)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update all other effected remaining values self._update_vacancy_nums(n - 1) if tableau_height >= n - 2: self._correct_vacancy_nums() self._update_partition_values(n - 1) self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) self._update_vacancy_nums(n - 2) return # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] + 1 else: max_width = 1 # Special case for `\overline{n-1}` to take the larger of the last two if pos_val == n - 1 and len(self.ret_rig_con[n - 1]) > 0 and \ self.ret_rig_con[n - 1][0] + 1 > max_width: max_width = self.ret_rig_con[n - 1][0] + 1 # Add cells similar to type A_n but we move to the right until we reach # the value of n-2 for a in range(pos_val - 1, n - 2): max_width = self.ret_rig_con[a].insert_cell(max_width) # Handle the special behavior near values of n if tableau_height <= n - 2: max_width2 = self.ret_rig_con[n - 2].insert_cell(max_width) max_width = self.ret_rig_con[n - 1].insert_cell(max_width) if max_width2 < max_width: max_width = max_width2 elif pos_val <= self.cur_dims[0][0]: # Special case when the height will become n max_width = self.ret_rig_con[self.cur_dims[0][0] - 1].insert_cell(max_width) # Go back following the regular A_n rules if tableau_height <= n - 3: max_width = self.ret_rig_con[n - 3].insert_cell(max_width) self._update_vacancy_nums(n - 2) self._update_vacancy_nums(n - 1) if tableau_height >= n - 2: self._correct_vacancy_nums() self._update_partition_values(n - 2) self._update_partition_values(n - 1) for a in reversed(range(tableau_height, n - 3)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n - 2: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if pos_val <= tableau_height: for a in range(pos_val - 1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif 0 < tableau_height: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) elif pos_val <= n - 1: for a in range(pos_val - 1, n - 2): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2)
def next_state(self, val): r""" Build the next state for type `B_n^{(1)}`. TESTS:: sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_B import KRTToRCBijectionTypeB sage: bijection = KRTToRCBijectionTypeB(KRT(pathlist=[[-1,2]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [3]) sage: bijection.next_state(3) """ n = self.n tableau_height = len(self.cur_path[0]) - 1 # If it is a regular value, we follow the A_n rules if val > 0: KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val # Special case for 0 if pos_val == 0: if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[n-1][0] else: max_width = 1 max_width = self.ret_rig_con[n-1].insert_cell(max_width) width_n = max_width + 1 max_width = max_width // 2 # Check to see if we need to make the new string quasi-singular max_width = self.ret_rig_con[n-2].insert_cell(max_width) self._update_vacancy_nums(n - 1) self._update_partition_values(n - 1) # Check if we need to make the new string at n quasi-singular p = self.ret_rig_con[n-1] num_rows = len(p) # Note that max width is 1 less than the corresponding string length if max_width*2 + 1 != width_n: for i in range(num_rows): if p._list[i] == width_n: j = i+1 while j < num_rows and p._list[j] == width_n \ and p.vacancy_numbers[j] == p.rigging[j]: j += 1 p.rigging[j-1] -= 1 break # Follow regular A_n rules for a in reversed(range(tableau_height, n-2)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if tableau_height > 0: self._update_vacancy_nums(tableau_height-1) self._update_partition_values(tableau_height-1) return # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] + 1 else: max_width = 0 # Add cells similar to type A_n but we move to the right until n for a in range(pos_val - 1, n - 1): max_width = self.ret_rig_con[a].insert_cell(max_width) # Handle the special behavior at n if pos_val != n: max_width = max_width * 2 # Find either the quasi-singular string and the next largest singular, # the largest singular string if smaller than the max width # or the two largest singular strings singular_max_width = False case_QS = False # Note, case_QS and singular_max_width will never both be True p = self.ret_rig_con[n-1] num_rows = len(p) width_n = 0 for i in range(num_rows + 1): if i == num_rows: if case_QS: # If we are in case (QS), we will be adding a box p._list.append(1) p.vacancy_numbers.append(None) p.rigging.append(None) width_n = 1 max_width = 0 elif not singular_max_width: # If we have not found a (quasi)singular string, we must add 2 boxes # Go through our partition until we find a length of greater than 2 j = len(p._list) - 1 while j >= 0 and p._list[j] <= 2: j -= 1 p._list.insert(j+1, 2) p.vacancy_numbers.insert(j+1, None) p.rigging.insert(j+1, None) max_width = 0 break elif p.vacancy_numbers[i] == p.rigging[i]: if p._list[i] < max_width: if singular_max_width: width_n = p._list[i] break max_width = p._list[i] if case_QS: p._list[i] += 1 p.rigging[i] = None width_n = max_width + 1 else: # Add 2 boxes j = i - 1 while j >= 0 and p._list[j] <= max_width + 2: p.rigging[j+1] = p.rigging[j] # Shuffle it along j -= 1 p._list.pop(i) p._list.insert(j+1, max_width + 2) p.rigging[j+1] = None break if p._list[i] == max_width and not singular_max_width: p._list[i] += 1 # We always at least add a box to the first singular value p.rigging[i] = None if case_QS: width_n = p._list[i] break singular_max_width = True elif p._list[i] == max_width + 1 and not case_QS: # If we can't add 2 boxes, we must be in case (QS) p._list[i] += 1 p.rigging[i] = None width_n = max_width case_QS = True elif p.vacancy_numbers[i] - 1 == p.rigging[i] and not case_QS and not singular_max_width and p._list[i] <= max_width: case_QS = True max_width = p._list[i] p._list[i] += 1 p.rigging[i] = None if singular_max_width: # There are 2 possibilities, case (S) and case (QS), we might need # to attempt both # Make a *deep* copy of the element cp = self.ret_rig_con.__copy__() for i,rp in enumerate(cp): cp[i] = rp._clone() # We attempt case (S) first self._insert_cell_case_S(p) max_width = max_width // 2 # We need to do the next partition in order to determine the step at n max_width = self.ret_rig_con[n-2].insert_cell(max_width) self._update_vacancy_nums(n - 1) self._update_partition_values(n - 1) # If we need to make the smaller added string quasisingular # Note that max width is 1 less than the corresponding string length if case_QS and max_width*2 + 1 != width_n: for i in range(num_rows): if p._list[i] == width_n: j = i+1 while j < num_rows and p._list[j] == width_n \ and p.vacancy_numbers[j] == p.rigging[j]: j += 1 p.rigging[j-1] -= 1 break # Continue back following the regular A_n rules for a in reversed(range(tableau_height, n - 2)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) assert pos_val > 0 if pos_val <= tableau_height: for a in range(pos_val-1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) if singular_max_width: try: self.ret_rig_con.check() except StandardError: self.other_outcome(cp, pos_val, width_n)
def next_state(self, val): r""" Build the next state for type `D_n^{(1)}`. TESTS:: sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['D', 4, 1], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_D import KRTToRCBijectionTypeD sage: bijection = KRTToRCBijectionTypeD(KRT(pathlist=[[5,3]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [3]) sage: bijection.next_state(3) """ # Note that type D_n only contains the (absolute) values between 1 and n # (unlike type A_n which is 1 to n+1). Thus we only need to subtract 1 # to match the indices. # Also note that we must subtract 1 from n to match the indices as well. n = self.n tableau_height = len(self.cur_path[0]) - 1 # If it is a regular value, we follow the A_n rules if val > 0: KRTToRCBijectionTypeA.next_state(self, val) # If we are inserting n-1 (which will only update nu[a] for a <= # n-1), we need to update the vacancy number of nu[n] as well if val == n - 1: self._update_vacancy_nums(val) if tableau_height >= n - 2: self._correct_vacancy_nums() return pos_val = -val if pos_val == n: # Special case for `\overline{n}` and adding to make height `n` # where we only update the vacancy numbers # This only occurs with `r = n - 1` if self.cur_dims[0][0] == n - 1 and tableau_height == n - 1: self._update_vacancy_nums(n-2) self._update_vacancy_nums(n-1) self._correct_vacancy_nums() return if len(self.ret_rig_con[n - 1]) > 0: max_width = self.ret_rig_con[n - 1][0] + 1 else: max_width = 1 # Update the last one and skip a rigged partition max_width = self.ret_rig_con[n - 1].insert_cell(max_width) for a in reversed(range(tableau_height, n - 2)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update all other effected remaining values self._update_vacancy_nums(n - 1) if tableau_height >= n - 2: self._correct_vacancy_nums() self._update_partition_values(n - 1) self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) self._update_vacancy_nums(n - 2) return # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] + 1 else: max_width = 1 # Special case for `\overline{n-1}` to take the larger of the last two if pos_val == n - 1 and len(self.ret_rig_con[n - 1]) > 0 and \ self.ret_rig_con[n - 1][0] + 1 > max_width: max_width = self.ret_rig_con[n - 1][0] + 1 # Add cells similar to type A_n but we move to the right until we reach # the value of n-2 for a in range(pos_val - 1, n - 2): max_width = self.ret_rig_con[a].insert_cell(max_width) # Handle the special behavior near values of n if tableau_height <= n - 2: max_width2 = self.ret_rig_con[n - 2].insert_cell(max_width) max_width = self.ret_rig_con[n - 1].insert_cell(max_width) if max_width2 < max_width: max_width = max_width2 elif pos_val <= self.cur_dims[0][0]: # Special case when the height will become n max_width = self.ret_rig_con[self.cur_dims[0][0] - 1].insert_cell(max_width) # Go back following the regular A_n rules if tableau_height <= n - 3: max_width = self.ret_rig_con[n - 3].insert_cell(max_width) self._update_vacancy_nums(n - 2) self._update_vacancy_nums(n - 1) if tableau_height >= n - 2: self._correct_vacancy_nums() self._update_partition_values(n - 2) self._update_partition_values(n - 1) for a in reversed(range(tableau_height, n - 3)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n - 2: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if pos_val <= tableau_height: for a in range(pos_val - 1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val-2) self._update_partition_values(pos_val-2) elif 0 < tableau_height: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) elif pos_val <= n - 1: for a in range(pos_val - 1, n - 2): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val-2) self._update_partition_values(pos_val-2)
def next_state(self, val): r""" Build the next state for type `B_n^{(1)}`. TESTS:: sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_B import KRTToRCBijectionTypeB sage: bijection = KRTToRCBijectionTypeB(KRT(pathlist=[[-1,2]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [3]) sage: bijection.next_state(3) """ n = self.n tableau_height = len(self.cur_path[0]) - 1 # If it is a regular value, we follow the A_n rules if val > 0: KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val # Special case for 0 if pos_val == 0: if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[n - 1][0] else: max_width = 1 max_width = self.ret_rig_con[n - 1].insert_cell(max_width) width_n = max_width + 1 max_width = max_width // 2 # Check to see if we need to make the new string quasi-singular max_width = self.ret_rig_con[n - 2].insert_cell(max_width) self._update_vacancy_nums(n - 1) self._update_partition_values(n - 1) # Check if we need to make the new string at n quasi-singular p = self.ret_rig_con[n - 1] num_rows = len(p) # Note that max width is 1 less than the corresponding string length if max_width * 2 + 1 != width_n: for i in range(num_rows): if p._list[i] == width_n: j = i + 1 while j < num_rows and p._list[j] == width_n \ and p.vacancy_numbers[j] == p.rigging[j]: j += 1 p.rigging[j - 1] -= 1 break # Follow regular A_n rules for a in reversed(range(tableau_height, n - 2)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) return # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] + 1 else: max_width = 0 # Add cells similar to type A_n but we move to the right until n for a in range(pos_val - 1, n - 1): max_width = self.ret_rig_con[a].insert_cell(max_width) # Handle the special behavior at n if pos_val != n: max_width = max_width * 2 # Find either the quasi-singular string and the next largest singular, # the largest singular string if smaller than the max width # or the two largest singular strings singular_max_width = False case_QS = False # Note, case_QS and singular_max_width will never both be True p = self.ret_rig_con[n - 1] num_rows = len(p) width_n = 0 for i in range(num_rows + 1): if i == num_rows: if case_QS: # If we are in case (QS), we will be adding a box p._list.append(1) p.vacancy_numbers.append(None) p.rigging.append(None) width_n = 1 max_width = 0 elif not singular_max_width: # If we have not found a (quasi)singular string, we must add 2 boxes # Go through our partition until we find a length of greater than 2 j = len(p._list) - 1 while j >= 0 and p._list[j] <= 2: j -= 1 p._list.insert(j + 1, 2) p.vacancy_numbers.insert(j + 1, None) p.rigging.insert(j + 1, None) max_width = 0 break elif p.vacancy_numbers[i] == p.rigging[i]: if p._list[i] < max_width: if singular_max_width: width_n = p._list[i] break max_width = p._list[i] if case_QS: p._list[i] += 1 p.rigging[i] = None width_n = max_width + 1 else: # Add 2 boxes j = i - 1 while j >= 0 and p._list[j] <= max_width + 2: p.rigging[j + 1] = p.rigging[j] # Shuffle it along j -= 1 p._list.pop(i) p._list.insert(j + 1, max_width + 2) p.rigging[j + 1] = None break if p._list[i] == max_width and not singular_max_width: p._list[ i] += 1 # We always at least add a box to the first singular value p.rigging[i] = None if case_QS: width_n = p._list[i] break singular_max_width = True elif p._list[i] == max_width + 1 and not case_QS: # If we can't add 2 boxes, we must be in case (QS) p._list[i] += 1 p.rigging[i] = None width_n = max_width case_QS = True elif p.vacancy_numbers[i] - 1 == p.rigging[ i] and not case_QS and not singular_max_width and p._list[ i] <= max_width: case_QS = True max_width = p._list[i] p._list[i] += 1 p.rigging[i] = None if singular_max_width: # There are 2 possibilities, case (S) and case (QS), we might need # to attempt both # Make a *deep* copy of the element cp = self.ret_rig_con.__copy__() for i, rp in enumerate(cp): cp[i] = rp._clone() # We attempt case (S) first self._insert_cell_case_S(p) max_width = max_width // 2 # We need to do the next partition in order to determine the step at n max_width = self.ret_rig_con[n - 2].insert_cell(max_width) self._update_vacancy_nums(n - 1) self._update_partition_values(n - 1) # If we need to make the smaller added string quasisingular # Note that max width is 1 less than the corresponding string length if case_QS and max_width * 2 + 1 != width_n: for i in range(num_rows): if p._list[i] == width_n: j = i + 1 while j < num_rows and p._list[j] == width_n \ and p.vacancy_numbers[j] == p.rigging[j]: j += 1 p.rigging[j - 1] -= 1 break # Continue back following the regular A_n rules for a in reversed(range(tableau_height, n - 2)): max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) assert pos_val > 0 if pos_val <= tableau_height: for a in range(pos_val - 1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1) if singular_max_width: try: self.ret_rig_con.check() except Exception: self.other_outcome(cp, pos_val, width_n)
def next_state(self, val): r""" Build the next state for type `C_n^{(1)}`. TESTS:: sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['C', 3, 1], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC sage: bijection = KRTToRCBijectionTypeC(KRT(pathlist=[[-1,2]])) sage: bijection.cur_path.insert(0, []) sage: bijection.cur_dims.insert(0, [0, 1]) sage: bijection.cur_path[0].insert(0, [2]) sage: bijection.next_state(2) """ # Note that we must subtract 1 from n to match the indices. n = self.n tableau_height = len(self.cur_path[0]) - 1 # If it is a regular value, we follow the A_n rules if val > 0: KRTToRCBijectionTypeA.next_state(self, val) return pos_val = -val case_S = [None] * n # Always add a cell to the first singular value in the first # tableau we are updating. if len(self.ret_rig_con[pos_val - 1]) > 0: max_width = self.ret_rig_con[pos_val - 1][0] else: max_width = 1 # Special case for inserting -n if pos_val == n: max_width *= 2 # Add cells similar to type A_n but we move to the right until we # reach the value of n for a in range(pos_val - 1, n - 1): max_width = self.ret_rig_con[a].insert_cell(max_width) case_S[a] = max_width # Special case for n max_width = self.ret_rig_con[n - 1].insert_cell(max_width // 2) * 2 # Now go back following the special C_n rules for a in reversed(range(tableau_height, n - 1)): if case_S[a] == max_width: self._insert_cell_case_S(self.ret_rig_con[a]) else: max_width = self.ret_rig_con[a].insert_cell(max_width) self._update_vacancy_nums(a + 1) self._update_partition_values(a + 1) # Update the final rigged partitions if tableau_height < n: self._update_vacancy_nums(tableau_height) self._update_partition_values(tableau_height) if pos_val <= tableau_height: for a in range(pos_val - 1, tableau_height): self._update_vacancy_nums(a) self._update_partition_values(a) if pos_val > 1: self._update_vacancy_nums(pos_val - 2) self._update_partition_values(pos_val - 2) elif tableau_height > 0: self._update_vacancy_nums(tableau_height - 1) self._update_partition_values(tableau_height - 1)