示例#1
0
    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())
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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())
示例#5
0
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
示例#6
0
    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
示例#7
0
    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
示例#8
0
    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)
示例#9
0
    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
示例#10
0
    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)
示例#12
0
    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)
示例#13
0
    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)
示例#14
0
    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)
示例#15
0
    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)