Esempio n. 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())
    def left_split(self):
        r"""
        Return the image of ``self`` under the left column splitting map.

        EXAMPLES::

            sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]])
            sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]]); elt.pp()
              1  2 (X)   1  4  4
              2  3
            sage: elt.left_split().pp()
              1 (X)   2 (X)   1  4  4
              2       3
        """
        P = self.parent()
        if P.dims[0][1] == 1:
            raise ValueError("cannot split a single column")
        r, s = P.dims[0]
        B = [[r, 1], [r, s - 1]]
        B.extend(P.dims[1:])
        from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \
                import TensorProductOfKirillovReshetikhinTableaux
        TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, B)
        x = self[0].left_split()
        return TP(*(list(x) + self[1:]))
    def right_split(self):
        r"""
        Return the image of ``self`` under the right column splitting map.

        EXAMPLES::

            sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]])
            sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]]); elt.pp()
              1  2 (X)   1  4  4
              2  3
            sage: elt.right_split().pp()
              1  2 (X)   1  4 (X)   4
              2  3

        Let `\ast` denote the :meth:`Lusztig involution<lusztig_involution>`,
        we check that `\ast \circ \mathrm{ls} \circ \ast = \mathrm{rs}`::

            sage: all(x.lusztig_involution().left_split().lusztig_involution() == x.right_split() for x in KRT)
            True
        """
        P = self.parent()
        if P.dims[-1][1] == 1:
            raise ValueError("cannot split a single column")
        r, s = P.dims[-1]
        B = list(P.dims[:-1])
        B.append([r, s - 1])
        B.append([r, 1])
        from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \
                import TensorProductOfKirillovReshetikhinTableaux
        TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, B)
        x = self[-1].right_split()
        return TP(*(self[:-1] + list(x)))
Esempio n. 4
0
    def __init__(self, initial_state, cartan_type=2, vacuum=1):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: B = SolitonCellularAutomata('3411111122411112223', 4)
            sage: TestSuite(B).run()
        """
        if cartan_type in ZZ:
            cartan_type = CartanType(['A', cartan_type - 1, 1])
        else:
            cartan_type = CartanType(cartan_type)
        self._cartan_type = cartan_type
        self._vacuum = vacuum
        K = KirillovReshetikhinTableaux(self._cartan_type, self._vacuum, 1)
        try:
            # FIXME: the maximal_vector() does not work in type E and F
            self._vacuum_elt = K.maximal_vector()
        except (ValueError, TypeError, AttributeError):
            self._vacuum_elt = K.module_generators[0]

        if isinstance(initial_state, str):
            # We consider things 1-9
            initial_state = [[ZZ(x) if x != '.' else ZZ.one()]
                             for x in initial_state]
        try:
            KRT = TensorProductOfKirillovReshetikhinTableaux(
                self._cartan_type,
                [[vacuum, len(st) // vacuum] for st in initial_state])
            self._states = [KRT(pathlist=initial_state)]
        except TypeError:
            KRT = TensorProductOfKirillovReshetikhinTableaux(
                self._cartan_type, [[vacuum, 1] for st in initial_state])
            self._states = [KRT(*initial_state)]

        self._evolutions = []
        self._nballs = len(self._states[0])
    def lusztig_involution(self):
        r"""
        Return the result of the classical Lusztig involution on ``self``.

        EXAMPLES::

            sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A',3,1], [[2,2],[1,3]])
            sage: elt = KRT(pathlist=[[2,1,3,2],[1,4,4]])
            sage: li = elt.lusztig_involution(); li
            [[1, 1, 4]] (X) [[2, 3], [3, 4]]
            sage: li.parent()
            Tensor product of Kirillov-Reshetikhin tableaux of type ['A', 3, 1] and factor(s) ((1, 3), (2, 2))
        """
        from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \
                import TensorProductOfKirillovReshetikhinTableaux
        P = self.parent()
        P = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, reversed(P.dims))
        return P(*[x.lusztig_involution() for x in reversed(self)])
Esempio n. 6
0
    def run(self, verbose=False):
        """
        Run the bijection from a tensor product of KR tableaux to a rigged
        configuration.

        INPUT:

        - ``tp_krt`` -- A tensor product of KR tableaux

        - ``verbose`` -- (Default: ``False``) Display each step in the
          bijection

        EXAMPLES::

            sage: from sage.combinat.rigged_configurations.bij_type_B import KRTToRCBijectionTypeB
            sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[2, 1]])
            sage: KRTToRCBijectionTypeB(KRT(pathlist=[[0,3]])).run()
            <BLANKLINE>
            0[ ]0
            <BLANKLINE>
            -1[ ]-1
            -1[ ]-1
            <BLANKLINE>
            0[]0
            <BLANKLINE>
            sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[3, 1]])
            sage: KRTToRCBijectionTypeB(KRT(pathlist=[[-2,3,1]])).run()
            <BLANKLINE>
            (/)
            <BLANKLINE>
            -1[ ]-1
            <BLANKLINE>
            0[]0
            <BLANKLINE>
        """
        if verbose:
            from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \
              import TensorProductOfKirillovReshetikhinTableauxElement

        for cur_crystal in reversed(self.tp_krt):
            r = cur_crystal.parent().r()

            # Check if it is a spinor
            if r == self.n:
                # Perform the spinor bijection by converting to type A_{2n-1}^{(2)}
                #   doing the bijection there and pulling back
                from sage.combinat.rigged_configurations.bij_type_A2_odd import KRTToRCBijectionTypeA2Odd
                from sage.combinat.rigged_configurations.tensor_product_kr_tableaux import TensorProductOfKirillovReshetikhinTableaux
                from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition

                if verbose:
                    print "===================="
                    if len(self.cur_path) == 0:
                        print(repr([])) # Special case for displaying when the rightmost factor is a spinor
                    else:
                        print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), self.cur_path)))
                    print("--------------------")
                    print(repr(self.ret_rig_con))
                    print("--------------------\n")
                    print("Applying doubling map")

                # Convert to a type A_{2n-1}^{(2)} RC
                dims = self.cur_dims[:]
                dims.insert(0, [r, cur_crystal.parent().s()])
                KRT = TensorProductOfKirillovReshetikhinTableaux(['A', 2*self.n-1, 2], dims)
                # Convert the n-th partition into a regular rigged partition
                self.ret_rig_con[-1] = RiggedPartition(self.ret_rig_con[-1]._list,
                                                       self.ret_rig_con[-1].rigging,
                                                       self.ret_rig_con[-1].vacancy_numbers)
                bij = KRTToRCBijectionTypeA2Odd(KRT.module_generators[0]) # Placeholder element
                bij.ret_rig_con = KRT.rigged_configurations()(*self.ret_rig_con)
                bij.cur_path = self.cur_path
                bij.cur_dims = self.cur_dims
                for i in range(len(self.cur_dims)):
                    if bij.cur_dims[i][0] != self.n:
                        bij.cur_dims[i][1] *= 2
                for i in range(self.n-1):
                    for j in range(len(bij.ret_rig_con[i])):
                        bij.ret_rig_con[i]._list[j] *= 2
                        bij.ret_rig_con[i].rigging[j] *= 2
                        bij.ret_rig_con[i].vacancy_numbers[j] *= 2

                # Perform the type A_{2n-1}^{(2)} bijection
                r = cur_crystal.parent().r()
                # Iterate through the columns
                for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))):
                    bij.cur_path.insert(0, []) # Prepend an empty list
                    bij.cur_dims.insert(0, [0, 1])

                    # Note that we do not need to worry about iterating over columns
                    #   (see previous note about the data structure).
                    for letter in reversed(cur_column):
                        bij.cur_dims[0][0] += 1
                        val = letter.value # Convert from a CrystalOfLetter to an Integer

                        if verbose:
                            print("====================")
                            print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), bij.cur_path)))
                            print("--------------------")
                            print(repr(bij.ret_rig_con))
                            print("--------------------\n")

                        # Build the next state
                        bij.cur_path[0].insert(0, [letter]) # Prepend the value
                        bij.next_state(val)

                    # If we've split off a column, we need to merge the current column
                    #   to the current crystal tableau
                    if col_number > 0:
                        for i, letter_singleton in enumerate(self.cur_path[0]):
                            bij.cur_path[1][i].insert(0, letter_singleton[0])
                        bij.cur_dims[1][1] += 1
                        bij.cur_path.pop(0)
                        bij.cur_dims.pop(0)

                        # And perform the inverse column splitting map on the RC
                        for a in range(self.n):
                            bij._update_vacancy_nums(a)

                if verbose:
                    print("====================")
                    print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), bij.cur_path)))
                    print("--------------------")
                    print(repr(bij.ret_rig_con))
                    print("--------------------\n")
                    print("Applying halving map")

                # Convert back to a type B_n^{(1)}
                for i in range(len(self.cur_dims)):
                    if bij.cur_dims[i][0] != self.n:
                        bij.cur_dims[i][1] //= 2
                for i in range(self.n-1):
                    for j in range(len(bij.ret_rig_con[i])):
                        bij.ret_rig_con[i]._list[j] //= 2
                        bij.ret_rig_con[i].rigging[j] //= 2
                        bij.ret_rig_con[i].vacancy_numbers[j] //= 2
                self.ret_rig_con = self.tp_krt.parent().rigged_configurations()(*bij.ret_rig_con)
                # Make it mutable so we don't have to keep making copies, at the
                #   end of the bijection, we will make it immutable again
                self.ret_rig_con._set_mutable()
            else:
                # Perform the regular type B_n^{(1)} bijection
                # Iterate through the columns
                for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))):
                    self.cur_path.insert(0, []) # Prepend an empty list
                    self.cur_dims.insert(0, [0, 1])

                    # Note that we do not need to worry about iterating over columns
                    #   (see previous note about the data structure).
                    for letter in reversed(cur_column):
                        self.cur_dims[0][0] += 1
                        val = letter.value # Convert from a CrystalOfLetter to an Integer

                        if verbose:
                            print("====================")
                            print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), self.cur_path)))
                            print("--------------------")
                            print(repr(self.ret_rig_con))
                            print("--------------------\n")

                        # Build the next state
                        self.cur_path[0].insert(0, [letter]) # Prepend the value
                        self.next_state(val)

                    # If we've split off a column, we need to merge the current column
                    #   to the current crystal tableau
                    if col_number > 0:
                        if verbose:
                            print("====================")
                            print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), self.cur_path)))
                            print("--------------------")
                            print(repr(self.ret_rig_con))
                            print("--------------------\n")
                            print("Applying column merge")

                        for i, letter_singleton in enumerate(self.cur_path[0]):
                            self.cur_path[1][i].insert(0, letter_singleton[0])
                        self.cur_dims[1][1] += 1
                        self.cur_path.pop(0)
                        self.cur_dims.pop(0)

                        # And perform the inverse column splitting map on the RC
                        for a in range(self.n):
                            self._update_vacancy_nums(a)
        self.ret_rig_con.set_immutable() # Return it to immutable
        return self.ret_rig_con
Esempio n. 7
0
    def run(self, verbose=False):
        """
        Run the bijection from a tensor product of KR tableaux to a rigged
        configuration.

        INPUT:

        - ``tp_krt`` -- A tensor product of KR tableaux

        - ``verbose`` -- (Default: ``False``) Display each step in the
          bijection

        EXAMPLES::

            sage: from sage.combinat.rigged_configurations.bij_type_B import KRTToRCBijectionTypeB
            sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[2, 1]])
            sage: KRTToRCBijectionTypeB(KRT(pathlist=[[0,3]])).run()
            <BLANKLINE>
            0[ ]0
            <BLANKLINE>
            -1[ ]-1
            -1[ ]-1
            <BLANKLINE>
            0[]0
            <BLANKLINE>
            sage: KRT = TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[3, 1]])
            sage: KRTToRCBijectionTypeB(KRT(pathlist=[[-2,3,1]])).run()
            <BLANKLINE>
            (/)
            <BLANKLINE>
            -1[ ]-1
            <BLANKLINE>
            0[]0
            <BLANKLINE>
        """
        if verbose:
            from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \
              import TensorProductOfKirillovReshetikhinTableauxElement

        for cur_crystal in reversed(self.tp_krt):
            r = cur_crystal.parent().r()

            # Check if it is a spinor
            if r == self.n:
                # Perform the spinor bijection by converting to type A_{2n-1}^{(2)}
                #   doing the bijection there and pulling back
                from sage.combinat.rigged_configurations.bij_type_A2_odd import KRTToRCBijectionTypeA2Odd
                from sage.combinat.rigged_configurations.tensor_product_kr_tableaux import TensorProductOfKirillovReshetikhinTableaux
                from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition

                if verbose:
                    print "===================="
                    if len(self.cur_path) == 0:
                        print(
                            repr([])
                        )  # Special case for displaying when the rightmost factor is a spinor
                    else:
                        print(
                            repr(
                                TensorProductOfKirillovReshetikhinTableauxElement(
                                    self.tp_krt.parent(), self.cur_path)))
                    print("--------------------")
                    print(repr(self.ret_rig_con))
                    print("--------------------\n")
                    print("Applying doubling map")

                # Convert to a type A_{2n-1}^{(2)} RC
                dims = self.cur_dims[:]
                dims.insert(0, [r, cur_crystal.parent().s()])
                KRT = TensorProductOfKirillovReshetikhinTableaux(
                    ['A', 2 * self.n - 1, 2], dims)
                # Convert the n-th partition into a regular rigged partition
                self.ret_rig_con[-1] = RiggedPartition(
                    self.ret_rig_con[-1]._list, self.ret_rig_con[-1].rigging,
                    self.ret_rig_con[-1].vacancy_numbers)
                bij = KRTToRCBijectionTypeA2Odd(
                    KRT.module_generators[0])  # Placeholder element
                bij.ret_rig_con = KRT.rigged_configurations()(
                    *self.ret_rig_con)
                bij.cur_path = self.cur_path
                bij.cur_dims = self.cur_dims
                for i in range(len(self.cur_dims)):
                    if bij.cur_dims[i][0] != self.n:
                        bij.cur_dims[i][1] *= 2
                for i in range(self.n - 1):
                    for j in range(len(bij.ret_rig_con[i])):
                        bij.ret_rig_con[i]._list[j] *= 2
                        bij.ret_rig_con[i].rigging[j] *= 2
                        bij.ret_rig_con[i].vacancy_numbers[j] *= 2

                # Perform the type A_{2n-1}^{(2)} bijection
                r = cur_crystal.parent().r()
                # Iterate through the columns
                for col_number, cur_column in enumerate(
                        reversed(cur_crystal.to_array(False))):
                    bij.cur_path.insert(0, [])  # Prepend an empty list
                    bij.cur_dims.insert(0, [0, 1])

                    # Note that we do not need to worry about iterating over columns
                    #   (see previous note about the data structure).
                    for letter in reversed(cur_column):
                        bij.cur_dims[0][0] += 1
                        val = letter.value  # Convert from a CrystalOfLetter to an Integer

                        if verbose:
                            print("====================")
                            print(
                                repr(
                                    TensorProductOfKirillovReshetikhinTableauxElement(
                                        self.tp_krt.parent(), bij.cur_path)))
                            print("--------------------")
                            print(repr(bij.ret_rig_con))
                            print("--------------------\n")

                        # Build the next state
                        bij.cur_path[0].insert(0,
                                               [letter])  # Prepend the value
                        bij.next_state(val)

                    # If we've split off a column, we need to merge the current column
                    #   to the current crystal tableau
                    if col_number > 0:
                        for i, letter_singleton in enumerate(self.cur_path[0]):
                            bij.cur_path[1][i].insert(0, letter_singleton[0])
                        bij.cur_dims[1][1] += 1
                        bij.cur_path.pop(0)
                        bij.cur_dims.pop(0)

                        # And perform the inverse column splitting map on the RC
                        for a in range(self.n):
                            bij._update_vacancy_nums(a)

                if verbose:
                    print("====================")
                    print(
                        repr(
                            TensorProductOfKirillovReshetikhinTableauxElement(
                                self.tp_krt.parent(), bij.cur_path)))
                    print("--------------------")
                    print(repr(bij.ret_rig_con))
                    print("--------------------\n")
                    print("Applying halving map")

                # Convert back to a type B_n^{(1)}
                for i in range(len(self.cur_dims)):
                    if bij.cur_dims[i][0] != self.n:
                        bij.cur_dims[i][1] //= 2
                for i in range(self.n - 1):
                    for j in range(len(bij.ret_rig_con[i])):
                        bij.ret_rig_con[i]._list[j] //= 2
                        bij.ret_rig_con[i].rigging[j] //= 2
                        bij.ret_rig_con[i].vacancy_numbers[j] //= 2
                self.ret_rig_con = self.tp_krt.parent().rigged_configurations(
                )(*bij.ret_rig_con)
                # Make it mutable so we don't have to keep making copies, at the
                #   end of the bijection, we will make it immutable again
                self.ret_rig_con._set_mutable()
            else:
                # Perform the regular type B_n^{(1)} bijection
                # Iterate through the columns
                for col_number, cur_column in enumerate(
                        reversed(cur_crystal.to_array(False))):
                    self.cur_path.insert(0, [])  # Prepend an empty list
                    self.cur_dims.insert(0, [0, 1])

                    # Note that we do not need to worry about iterating over columns
                    #   (see previous note about the data structure).
                    for letter in reversed(cur_column):
                        self.cur_dims[0][0] += 1
                        val = letter.value  # Convert from a CrystalOfLetter to an Integer

                        if verbose:
                            print("====================")
                            print(
                                repr(
                                    TensorProductOfKirillovReshetikhinTableauxElement(
                                        self.tp_krt.parent(), self.cur_path)))
                            print("--------------------")
                            print(repr(self.ret_rig_con))
                            print("--------------------\n")

                        # Build the next state
                        self.cur_path[0].insert(0,
                                                [letter])  # Prepend the value
                        self.next_state(val)

                    # If we've split off a column, we need to merge the current column
                    #   to the current crystal tableau
                    if col_number > 0:
                        if verbose:
                            print("====================")
                            print(
                                repr(
                                    TensorProductOfKirillovReshetikhinTableauxElement(
                                        self.tp_krt.parent(), self.cur_path)))
                            print("--------------------")
                            print(repr(self.ret_rig_con))
                            print("--------------------\n")
                            print("Applying column merge")

                        for i, letter_singleton in enumerate(self.cur_path[0]):
                            self.cur_path[1][i].insert(0, letter_singleton[0])
                        self.cur_dims[1][1] += 1
                        self.cur_path.pop(0)
                        self.cur_dims.pop(0)

                        # And perform the inverse column splitting map on the RC
                        for a in range(self.n):
                            self._update_vacancy_nums(a)
        self.ret_rig_con.set_immutable()  # Return it to immutable
        return self.ret_rig_con
Esempio n. 8
0
    def evolve(self, carrier_capacity=None, carrier_index=None, number=None):
        """
        Evolve ``self``.

        Time evolution `T_s` of a SCA state `p` is determined by

        .. MATH::

            u_{r,s} \otimes T_s(p) = R(p \otimes u_{r,s}),

        where `u_{r,s}` is the maximal element of `B^{r,s}`.

        INPUT:

        - ``carrier_capacity`` -- (default: the number of balls in
          the system) the size `s` of carrier

        - ``carrier_index`` -- (default: the vacuum index) the index `r`
          of the carrier

        - ``number`` -- (optional) the number of times to perform
          the evolutions

        To perform multiple evolutions of the SCA, ``carrier_capacity``
        and ``carrier_index`` may be lists of the same length.

        EXAMPLES::

            sage: B = SolitonCellularAutomata('3411111122411112223', 4)
            sage: for k in range(10):
            ....:     B.evolve()
            sage: B
            Soliton cellular automata of type ['A', 3, 1] and vacuum = 1
              initial state:
              34......224....2223
              evoltuions: [(1, 19), (1, 19), (1, 19), (1, 19), (1, 19),
                           (1, 19), (1, 19), (1, 19), (1, 19), (1, 19)]
              current state:
              ......2344.......222....23...............................

            sage: B.reset()
            sage: B.evolve(number=10); B
            Soliton cellular automata of type ['A', 3, 1] and vacuum = 1
              initial state:
              34......224....2223
              evoltuions: [(1, 19), (1, 19), (1, 19), (1, 19), (1, 19),
                           (1, 19), (1, 19), (1, 19), (1, 19), (1, 19)]
              current state:
              ......2344.......222....23...............................

            sage: B.reset()
            sage: B.evolve(carrier_capacity=[1,2,3,4,5,6,7,8,9,10]); B
            Soliton cellular automata of type ['A', 3, 1] and vacuum = 1
              initial state:
              34......224....2223
              evoltuions: [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
                           (1, 6), (1, 7), (1, 8), (1, 9), (1, 10)]
              current state:
              ........2344....222..23..............................

            sage: B.reset()
            sage: B.evolve(carrier_index=[1,2,3])
            Last carrier:
              1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
              2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  3  4  4
            sage: B
            Soliton cellular automata of type ['A', 3, 1] and vacuum = 1
              initial state:
              34......224....2223
              evoltuions: [(1, 19), (2, 19), (3, 19)]
              current state:
              ..................................22......223...2222.....

            sage: B.reset()
            sage: B.evolve(carrier_capacity=[1,2,3], carrier_index=[1,2,3])
            Last carrier:
              1  1
              3  4
            Last carrier:
              1  1  1
              2  2  3
              3  3  4
            sage: B
            Soliton cellular automata of type ['A', 3, 1] and vacuum = 1
              initial state:
              34......224....2223
              evoltuions: [(1, 1), (2, 2), (3, 3)]
              current state:
              .....22.......223....2222..

            sage: B.reset()
            sage: B.evolve(1, 2, number=3)
            Last carrier:
              1
              3
            Last carrier:
              1
              4
            Last carrier:
              1
              3
            sage: B
            Soliton cellular automata of type ['A', 3, 1] and vacuum = 1
              initial state:
              34......224....2223
              evoltuions: [(2, 1), (2, 1), (2, 1)]
              current state:
              .24......222.....2222.
        """
        if isinstance(carrier_capacity, (list, tuple)):
            if not isinstance(carrier_index, (list, tuple)):
                carrier_index = [carrier_index] * len(carrier_capacity)
            if len(carrier_index) != len(carrier_capacity):
                raise ValueError("carrier_index and carrier_capacity"
                                 " must have the same length")
            for i, r in zip(carrier_capacity, carrier_index):
                self.evolve(i, r)
            return
        if isinstance(carrier_index, (list, tuple)):
            # carrier_capacity must be not be a list/tuple if given
            for r in carrier_index:
                self.evolve(carrier_capacity, r)
            return

        if carrier_capacity is None:
            carrier_capacity = self._nballs
        if carrier_index is None:
            carrier_index = self._vacuum

        if number is not None:
            for k in range(number):
                self.evolve(carrier_capacity, carrier_index)
            return

        passed = False
        K = KirillovReshetikhinTableaux(self._cartan_type, carrier_index,
                                        carrier_capacity)
        try:
            # FIXME: the maximal_vector() does not work in type E and F
            empty_carrier = K.maximal_vector()
        except (ValueError, TypeError, AttributeError):
            empty_carrier = K.module_generators[0]
        carrier_factor = (carrier_index, carrier_capacity)
        last_final_carrier = empty_carrier
        state = self._states[-1]
        dims = state.parent().dims
        while not passed:
            KRT = TensorProductOfKirillovReshetikhinTableaux(
                self._cartan_type, dims + (carrier_factor, ))
            elt = KRT(*(list(state) + [empty_carrier]))
            RC = RiggedConfigurations(self._cartan_type,
                                      (carrier_factor, ) + dims)
            elt2 = RC(*elt.to_rigged_configuration()
                      ).to_tensor_product_of_kirillov_reshetikhin_tableaux()
            # Back to an empty carrier or we are not getting any better
            if elt2[0] == empty_carrier or elt2[0] == last_final_carrier:
                passed = True
                KRT = TensorProductOfKirillovReshetikhinTableaux(
                    self._cartan_type, dims)
                self._states.append(KRT(*elt2[1:]))
                self._evolutions.append(carrier_factor)
                if elt2[0] != empty_carrier:
                    print("Last carrier:")
                    print(ascii_art(last_final_carrier))
            else:
                # We need to add more vacuum states
                last_final_carrier = elt2[0]
                dims = tuple([(self._vacuum, 1)] * carrier_capacity) + dims