From 6e9fa5e6097cd3788855108361d772d988b8370f Mon Sep 17 00:00:00 2001 From: Jay Soni Date: Wed, 16 Aug 2023 16:11:47 -0400 Subject: [PATCH 1/4] support --- pennylane_qulacs/qulacs_device.py | 7 ++++--- tests/test_apply.py | 26 ++++++++++++++------------ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/pennylane_qulacs/qulacs_device.py b/pennylane_qulacs/qulacs_device.py index 216310f..e8ab5f2 100644 --- a/pennylane_qulacs/qulacs_device.py +++ b/pennylane_qulacs/qulacs_device.py @@ -21,7 +21,7 @@ import numpy as np from pennylane import QubitDevice, DeviceError -from pennylane.ops import QubitStateVector, BasisState, QubitUnitary, CRZ, PhaseShift, Adjoint +from pennylane.ops import QubitStateVector, BasisState, QubitUnitary, CRZ, PhaseShift, Adjoint, StatePrep import qulacs.gate as gate from qulacs import QuantumCircuit, QuantumState, Observable @@ -85,6 +85,7 @@ class QulacsDevice(QubitDevice): } _operation_map = { + "StatePrep": None, "QubitStateVector": None, "BasisState": None, "QubitUnitary": None, @@ -159,7 +160,7 @@ def apply_operations(self, operations): """ for i, op in enumerate(operations): - if i > 0 and isinstance(op, (QubitStateVector, BasisState)): + if i > 0 and isinstance(op, (QubitStateVector, BasisState, StatePrep)): raise DeviceError( "Operation {} cannot be used after other Operations have already been applied " "on a {} device.".format(op.name, self.short_name) @@ -169,7 +170,7 @@ def apply_operations(self, operations): inverse = True op = op.base - if isinstance(op, QubitStateVector): + if isinstance(op, (QubitStateVector, StatePrep)): self._apply_qubit_state_vector(op) elif isinstance(op, BasisState): self._apply_basis_state(op) diff --git a/tests/test_apply.py b/tests/test_apply.py index a8991f0..3b24e3a 100755 --- a/tests/test_apply.py +++ b/tests/test_apply.py @@ -163,12 +163,13 @@ def test_basis_state_on_wires_subset(self, state, device_wires, op_wires, tol): expected = dev._expand_state(expected, op_wires) assert np.allclose(res, expected, tol) - def test_qubit_state_vector(self, init_state, tol): - """Test QubitStateVector application""" + @pytest.mark.parametrize("state_prep_op", (qml.QubitStateVector, qml.StatePrep)) + def test_qubit_state_vector(self, init_state, state_prep_op, tol): + """Test QubitStateVector and StatePrep application""" dev = QulacsDevice(1) state = init_state(1) - op = qml.QubitStateVector(state, wires=[0]) + op = state_prep_op(state, wires=[0]) dev.apply([op]) dev._obs_queue = [] @@ -176,14 +177,15 @@ def test_qubit_state_vector(self, init_state, tol): expected = state assert np.allclose(res, expected, tol) + @pytest.mark.parametrize("state_prep_op", (qml.QubitStateVector, qml.StatePrep)) @pytest.mark.parametrize("device_wires", [3, 4, 5]) @pytest.mark.parametrize("op_wires", [[0], [2], [0, 1], [1, 0], [2, 0]]) - def test_qubit_state_vector_on_wires_subset(self, init_state, device_wires, op_wires, tol): - """Test QubitStateVector application on a subset of device wires""" + def test_qubit_state_vector_on_wires_subset(self, init_state, device_wires, op_wires, state_prep_op, tol): + """Test QubitStateVector and StatePrep application on a subset of device wires""" dev = QulacsDevice(device_wires) state = init_state(len(op_wires)) - op = qml.QubitStateVector(state, wires=op_wires) + op = state_prep_op(state, wires=op_wires) dev.apply([op]) dev._obs_queue = [] @@ -198,7 +200,7 @@ def test_single_qubit_no_parameters(self, init_state, op, mat, tol): dev = QulacsDevice(1) state = init_state(1) - dev.apply([qml.QubitStateVector(state, wires=[0]), op]) + dev.apply([qml.StatePrep(state, wires=[0]), op]) dev._obs_queue = [] res = dev.state @@ -213,7 +215,7 @@ def test_single_qubit_parameters(self, init_state, op, func, theta, tol): state = init_state(1) op.data = [theta] - dev.apply([qml.QubitStateVector(state, wires=[0]), op]) + dev.apply([qml.StatePrep(state, wires=[0]), op]) dev._obs_queue = [] res = dev.state @@ -226,7 +228,7 @@ def test_two_qubit_no_parameters(self, init_state, op, mat, tol): dev = QulacsDevice(2) state = init_state(2) - dev.apply([qml.QubitStateVector(state, wires=[0, 1]), op]) + dev.apply([qml.StatePrep(state, wires=[0, 1]), op]) dev._obs_queue = [] res = dev.state @@ -242,7 +244,7 @@ def test_qubit_unitary(self, init_state, mat, tol): state = init_state(N) op = qml.QubitUnitary(mat, wires=list(range(N))) - dev.apply([qml.QubitStateVector(state, wires=list(range(N))), op]) + dev.apply([qml.StatePrep(state, wires=list(range(N))), op]) dev._obs_queue = [] res = dev.state @@ -262,7 +264,7 @@ def test_three_qubit_no_parameters(self, init_state, op, mat, tol): dev = QulacsDevice(3) state = init_state(3) - dev.apply([qml.QubitStateVector(state, wires=[0, 1, 2]), op]) + dev.apply([qml.StatePrep(state, wires=[0, 1, 2]), op]) dev._obs_queue = [] res = dev.state @@ -277,7 +279,7 @@ def test_two_qubit_parameters(self, init_state, op, func, theta, tol): state = init_state(2) op.data = [theta] - dev.apply([qml.QubitStateVector(state, wires=[0, 1]), op]) + dev.apply([qml.StatePrep(state, wires=[0, 1]), op]) dev._obs_queue = [] From 6198fcb7abbf129d2be039d387ccf1f467622f3d Mon Sep 17 00:00:00 2001 From: Jay Soni Date: Thu, 17 Aug 2023 16:13:47 -0400 Subject: [PATCH 2/4] add for ci --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0cab76b..1973f92 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -pennylane>=0.15 +git+https://github.com/PennyLaneAI/pennylane.git Qulacs>=0.1.10.1 numpy~=1.16 From f98ff636737d3fdc4f7295085791a422bc7284e9 Mon Sep 17 00:00:00 2001 From: Jay Soni Date: Tue, 22 Aug 2023 11:06:02 -0400 Subject: [PATCH 3/4] lint --- pennylane_qulacs/qulacs_device.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pennylane_qulacs/qulacs_device.py b/pennylane_qulacs/qulacs_device.py index e8ab5f2..88628ca 100644 --- a/pennylane_qulacs/qulacs_device.py +++ b/pennylane_qulacs/qulacs_device.py @@ -21,7 +21,15 @@ import numpy as np from pennylane import QubitDevice, DeviceError -from pennylane.ops import QubitStateVector, BasisState, QubitUnitary, CRZ, PhaseShift, Adjoint, StatePrep +from pennylane.ops import ( + QubitStateVector, + BasisState, + QubitUnitary, + CRZ, + PhaseShift, + Adjoint, + StatePrep, +) import qulacs.gate as gate from qulacs import QuantumCircuit, QuantumState, Observable From c07762a464d004f58dc896cef40399e5dc2055bd Mon Sep 17 00:00:00 2001 From: Jay Soni Date: Tue, 22 Aug 2023 16:16:01 -0400 Subject: [PATCH 4/4] changelog --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cd87f5..77ba2cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Release 0.30.0-dev +# Release 0.32.0-dev ### New features since last release @@ -6,6 +6,9 @@ ### Improvements +* Added support for `qml.StatePrep` as a state preparation operation. + [(#54)](https://github.com/PennyLaneAI/pennylane-qulacs/pull/54) + ### Documentation ### Bug fixes @@ -14,6 +17,8 @@ This release contains contributions from (in alphabetical order): +Jay Soni + --- # Release 0.29.0