diff --git a/unitary/alpha/__init__.py b/unitary/alpha/__init__.py index d69ed72e..472a0c71 100644 --- a/unitary/alpha/__init__.py +++ b/unitary/alpha/__init__.py @@ -43,10 +43,8 @@ from unitary.alpha.qudit_effects import ( Cycle, Flip, - Superpose, QuditCycle, QuditFlip, - QuditSuperpose, ) from unitary.alpha.quantum_object import ( diff --git a/unitary/alpha/quantum_effect_test.py b/unitary/alpha/quantum_effect_test.py index 2b2623ca..04044e57 100644 --- a/unitary/alpha/quantum_effect_test.py +++ b/unitary/alpha/quantum_effect_test.py @@ -91,4 +91,4 @@ def test_no_qutrits(compile_to_qubits): piece = alpha.QuantumObject("q0", 2) board.add_object(piece) with pytest.raises(ValueError, match="Cannot apply effect to qids"): - alpha.Superposition()(piece) + alpha.Phase()(piece) diff --git a/unitary/alpha/quantum_world.py b/unitary/alpha/quantum_world.py index 416ac0a7..1f272785 100644 --- a/unitary/alpha/quantum_world.py +++ b/unitary/alpha/quantum_world.py @@ -116,9 +116,9 @@ def copy(self) -> "QuantumWorld": for remap in self.qubit_remapping_dict: new_dict = {} for key_obj, value_obj in remap.items(): - new_dict[new_world.get_object_by_name(key_obj.name)] = ( - new_world.get_object_by_name(value_obj.name) - ) + new_dict[ + new_world.get_object_by_name(key_obj.name) + ] = new_world.get_object_by_name(value_obj.name) new_world.qubit_remapping_dict.append(new_dict) new_world.qubit_remapping_dict_length = self.qubit_remapping_dict_length.copy() return new_world diff --git a/unitary/alpha/qubit_effects.py b/unitary/alpha/qubit_effects.py index 4776e42b..f786046b 100644 --- a/unitary/alpha/qubit_effects.py +++ b/unitary/alpha/qubit_effects.py @@ -19,6 +19,7 @@ import cirq from unitary.alpha.quantum_effect import QuantumEffect +from unitary.alpha.qudit_gates import QuditHadamardGate class Phase(QuantumEffect): @@ -67,14 +68,16 @@ def __eq__(self, other): class Superposition(QuantumEffect): - """Takes a qubit in a basis state into a superposition.""" - - def num_dimension(self) -> Optional[int]: - return 2 + """Transforms a qubit (or qudit) in a basis state into a (equal, in terms of + absolute magnitude) superposition of all basis states. + """ def effect(self, *objects): for q in objects: - yield cirq.H(q.qubit) + if q.qubit.dimension == 2: + yield cirq.H(q.qubit) + else: + yield QuditHadamardGate(dimension=q.qubit.dimension)(q.qubit) def __eq__(self, other): return isinstance(other, Superposition) or NotImplemented diff --git a/unitary/alpha/qubit_effects_test.py b/unitary/alpha/qubit_effects_test.py index 4d35e6ca..e97ea3b4 100644 --- a/unitary/alpha/qubit_effects_test.py +++ b/unitary/alpha/qubit_effects_test.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # - +import enum import pytest import cirq @@ -20,6 +20,12 @@ import unitary.alpha as alpha +class StopLight(enum.Enum): + RED = 0 + YELLOW = 1 + GREEN = 2 + + @pytest.mark.parametrize("compile_to_qubits", [False, True]) @pytest.mark.parametrize("simulator", [cirq.Simulator, alpha.SparseSimulator]) def test_flip(simulator, compile_to_qubits): @@ -78,7 +84,7 @@ def test_partial_phase(simulator, compile_to_qubits): @pytest.mark.parametrize("compile_to_qubits", [False, True]) @pytest.mark.parametrize("simulator", [cirq.Simulator, alpha.SparseSimulator]) -def test_superposition(simulator, compile_to_qubits): +def test_qubit_superposition(simulator, compile_to_qubits): board = alpha.QuantumWorld(sampler=simulator(), compile_to_qubits=compile_to_qubits) piece = alpha.QuantumObject("t", 0) board.add_object(piece) @@ -87,6 +93,17 @@ def test_superposition(simulator, compile_to_qubits): assert str(alpha.Superposition()) == "Superposition" +def test_qudit_superposition(): + board = alpha.QuantumWorld(sampler=cirq.Simulator(), compile_to_qubits=False) + piece = alpha.QuantumObject("t", StopLight.GREEN) + board.add_object(piece) + alpha.Superposition()(piece) + results = board.peek([piece], count=100) + assert any(result == [StopLight.RED] for result in results) + assert any(result == [StopLight.YELLOW] for result in results) + assert any(result == [StopLight.GREEN] for result in results) + + @pytest.mark.parametrize("compile_to_qubits", [False, True]) @pytest.mark.parametrize("simulator", [cirq.Simulator, alpha.SparseSimulator]) def test_move(simulator, compile_to_qubits): diff --git a/unitary/alpha/qudit_effects.py b/unitary/alpha/qudit_effects.py index 9ff71bbb..96753ea6 100644 --- a/unitary/alpha/qudit_effects.py +++ b/unitary/alpha/qudit_effects.py @@ -125,27 +125,3 @@ class QuditFlip(Flip): def __init__(self, dimension: int, state0: int, state1: int): super().__init__(state0=state0, state1=state1) - - -class Superpose(QuantumEffect): - """Transforms each pure state to a (equal, in terms of absolute magnitude) superposition of - all pure states. - """ - - def effect(self, *objects): - for q in objects: - if q.qubit.dimension == 2: - yield cirq.H(q.qubit) - else: - yield QuditHadamardGate(dimension=q.qubit.dimension)(q.qubit) - - -class QuditSuperpose(Superpose): - """Equivalent to Superpose. - - Exists only for backwards compatibiltity. - Will be removed in 2024. - """ - - def __init__(self): - super().__init__() diff --git a/unitary/alpha/qudit_effects_test.py b/unitary/alpha/qudit_effects_test.py index 432f54f6..c2c3d8a2 100644 --- a/unitary/alpha/qudit_effects_test.py +++ b/unitary/alpha/qudit_effects_test.py @@ -75,14 +75,3 @@ def test_qudit_flip(simulator, compile_to_qubits): alpha.QuditFlip(3, 0, 1)(piece) results = board.peek([piece], count=100) assert all(result == [StopLight.GREEN] for result in results) - - -def test_qudit_superpose(): - board = alpha.QuantumWorld(sampler=cirq.Simulator(), compile_to_qubits=False) - piece = alpha.QuantumObject("t", StopLight.GREEN) - board.add_object(piece) - alpha.QuditSuperpose()(piece) - results = board.peek([piece], count=100) - assert any(result == [StopLight.RED] for result in results) - assert any(result == [StopLight.YELLOW] for result in results) - assert any(result == [StopLight.GREEN] for result in results)