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()
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)
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))
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()