Пример #1
0
    def _make_random_change(self, compiled_sequence: UnitarySequence) -> None:
        '''
        Chooses and implements a random change to the specified
        unitary sequence.
        '''
        count_append = np.count_nonzero([
            CompilerAction.is_append(action) for action in list(CompilerAction)
        ])
        count_non_append = len(CompilerAction) - count_append
        p_append = self.append_probability / count_append
        p_non_append = (1 - self.append_probability) / count_non_append
        action = np.random.choice(
            list(CompilerAction),
            1,
            p=[
                p_append if CompilerAction.is_append(action) else p_non_append
                for action in list(CompilerAction)
            ])

        new_sequence_entry = None
        if CompilerAction.is_append(action):
            new_sequence_entry = Compiler.create_random_sequence_entry(
                self.dimension, self.unitary_primitives,
                self.unitary_primitive_probabilities)

        if action == CompilerAction.AppendFirst:
            compiled_sequence.append_first(new_sequence_entry)
        elif action == CompilerAction.AppendLast:
            compiled_sequence.append_last(new_sequence_entry)
        elif action == CompilerAction.RemoveFirst:
            compiled_sequence.remove_first()
        elif action == CompilerAction.RemoveLast:
            compiled_sequence.remove_last()
Пример #2
0
    def test_append_and_remove(self) -> None:
        dimension = 2
        identity = Unitary.identity(dimension)

        sequence = UnitarySequence(dimension)
        assert sequence.get_length() == 0
        assert sequence.product().close_to(identity)

        sequence.append_first(
            UnitarySequenceEntry(UnitaryDefinitions.sigmax(), [0]))
        assert sequence.get_length() == 1
        assert sequence.product().close_to(UnitaryDefinitions.sigmax())

        sequence.append_last(
            UnitarySequenceEntry(UnitaryDefinitions.sigmay(), [0]))
        assert sequence.get_length() == 2
        assert sequence.product().close_to(UnitaryDefinitions.sigmaz())

        sequence.append_first(
            UnitarySequenceEntry(UnitaryDefinitions.sigmaz(), [0]))
        assert sequence.get_length() == 3
        assert sequence.product().close_to(identity)

        sequence.remove_last()
        assert sequence.get_length() == 2
        assert sequence.product().close_to(UnitaryDefinitions.sigmay())

        sequence.remove_first()
        assert sequence.get_length() == 1
        assert sequence.product().close_to(UnitaryDefinitions.sigmax())

        sequence.remove_first()
        assert sequence.get_length() == 0
        assert sequence.product().close_to(identity)
Пример #3
0
    def _make_random_change_layered(
            self, compiled_sequence: UnitarySequence,
            unitary_primitive_counts: Dict[UnitaryPrimitive, int]) -> None:
        '''
        Chooses and implements a random change to the specified
        layered unitary sequence.
        '''
        count_append = np.count_nonzero([
            CompilerAction.is_append(action) for action in list(CompilerAction)
        ])
        count_non_append = len(CompilerAction) - count_append
        p_append = self.append_probability / count_append
        p_non_append = (1 - self.append_probability) / count_non_append
        action = np.random.choice(
            list(CompilerAction),
            1,
            p=[
                p_append if CompilerAction.is_append(action) else p_non_append
                for action in list(CompilerAction)
            ])

        layer_length = sum(unitary_primitive_counts.values())
        new_layer = None
        if CompilerAction.is_append(action):
            new_layer = Compiler.create_random_layer(self.dimension,
                                                     unitary_primitive_counts)

        # only save the undo state for the first modification to the sequence
        # this is so that a future undo() call will reverse the entire action
        if action == CompilerAction.AppendFirst:
            for i, sequence_entry in enumerate(new_layer):
                compiled_sequence.append_first(sequence_entry,
                                               save_undo=(i == 0))
        elif action == CompilerAction.AppendLast:
            for i, sequence_entry in enumerate(new_layer):
                compiled_sequence.append_last(sequence_entry,
                                              save_undo=(i == 0))
        elif action == CompilerAction.RemoveFirst:
            for i in range(layer_length):
                compiled_sequence.remove_first(save_undo=(i == 0))
        elif action == CompilerAction.RemoveLast:
            for i in range(layer_length):
                compiled_sequence.remove_last(save_undo=(i == 0))
Пример #4
0
    def test_undo(self) -> None:
        dimension = 2

        identity = Unitary.identity(dimension)

        sequence = UnitarySequence(dimension)
        assert sequence.get_length() == 0

        with pytest.raises(Exception):
            sequence.undo()

        sequence.append_first(
            UnitarySequenceEntry(UnitaryDefinitions.sigmax(), [0]))
        assert sequence.get_length() == 1
        assert sequence.product().close_to(UnitaryDefinitions.sigmax())

        sequence.undo()
        assert sequence.get_length() == 0
        assert sequence.product().close_to(identity)

        with pytest.raises(Exception):
            sequence.undo()

        sequence.append_first(
            UnitarySequenceEntry(UnitaryDefinitions.sigmay(), [0]))
        sequence.append_first(
            UnitarySequenceEntry(UnitaryDefinitions.sigmay(), [0]))
        assert sequence.get_length() == 2
        assert sequence.product().close_to(identity)

        sequence.remove_last()
        assert sequence.get_length() == 1
        assert sequence.product().close_to(UnitaryDefinitions.sigmay())

        sequence.undo()
        assert sequence.get_length() == 2
        assert sequence.product().close_to(identity)

        with pytest.raises(Exception):
            sequence.undo()