From a8b834d4875fcd0b294ddee101d4336ee131f9df Mon Sep 17 00:00:00 2001 From: lillian542 Date: Mon, 17 Jun 2024 16:12:05 -0400 Subject: [PATCH 1/3] add handling for measurements=[] --- pennylane/transforms/split_non_commuting.py | 2 ++ tests/transforms/test_split_non_commuting.py | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/pennylane/transforms/split_non_commuting.py b/pennylane/transforms/split_non_commuting.py index 8c23061e852..c15c30b995b 100644 --- a/pennylane/transforms/split_non_commuting.py +++ b/pennylane/transforms/split_non_commuting.py @@ -243,6 +243,8 @@ def circuit(x): [[expval(X(0)), probs(wires=[1])], [probs(wires=[0, 1])]] """ + if len(tape.measurements) == 0: + return [tape], lambda x: x[0] # Special case for a single measurement of a Sum or Hamiltonian, in which case # the grouping information can be computed and cached in the observable. diff --git a/tests/transforms/test_split_non_commuting.py b/tests/transforms/test_split_non_commuting.py index 709a0ed8e2a..5af275bc17a 100644 --- a/tests/transforms/test_split_non_commuting.py +++ b/tests/transforms/test_split_non_commuting.py @@ -568,6 +568,17 @@ def test_tape_with_non_pauli_obs(self, non_pauli_obs): fn([[0.1, 0.2], [0.3, 0.6], 0.4, 0.5, 0.7]), [0.01, 0.06, 0.06, 0.16, 0.25, 0.36, 0.49] ) + @pytest.mark.parametrize("grouping_strategy", [None, "default", "qwc", "wires"]) + def test_no_measurements(self, grouping_strategy): + """Test that if the tape contains no measurements, the transform doesn't + modify it""" + + tape = qml.tape.QuantumScript([qml.X(0)]) + tapes, post_processing_fn = split_non_commuting(tape, grouping_strategy=grouping_strategy) + assert len(tapes) == 1 + assert tapes[0] == tape + assert post_processing_fn(tapes) == tape + class TestIntegration: """Tests the ``split_non_commuting`` transform performed on a QNode""" From 0da7371c594a6bc7f5a015e5a28937ffd071f07f Mon Sep 17 00:00:00 2001 From: lillian542 Date: Mon, 17 Jun 2024 16:19:05 -0400 Subject: [PATCH 2/3] update changelog --- doc/releases/changelog-dev.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index f76d6850bf0..d5a9ea69edf 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -343,6 +343,9 @@ * `qml.transforms.map_batch_transform` is deprecated, since a transform can be applied directly to a batch of tapes. [(#5676)](https://github.com/PennyLaneAI/pennylane/pull/5676) +* `split_non_commuting` returns the unmodified tape if there are no measurements, instead of an empty list. + [(#5869)](https://github.com/PennyLaneAI/pennylane/pull/5869) +

Documentation 📝

* The documentation for the `default.tensor` device has been added. From 3bf99b7c0bf403d674e508c506005ab82cd1ee63 Mon Sep 17 00:00:00 2001 From: lillian542 Date: Mon, 17 Jun 2024 17:15:37 -0400 Subject: [PATCH 3/3] apply suggestions from code review --- doc/releases/changelog-dev.md | 4 +--- pennylane/transforms/split_non_commuting.py | 9 ++++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index d5a9ea69edf..a796df460d8 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -105,6 +105,7 @@ * `qml.transforms.split_non_commuting` can now handle circuits containing measurements of multi-term observables. [(#5729)](https://github.com/PennyLaneAI/pennylane/pull/5729) [(#5853)](https://github.com/PennyLaneAI/pennylane/pull/5838) + [(#5869)](https://github.com/PennyLaneAI/pennylane/pull/5869) * The qchem module has dedicated functions for calling `pyscf` and `openfermion` backends. [(#5553)](https://github.com/PennyLaneAI/pennylane/pull/5553) @@ -343,9 +344,6 @@ * `qml.transforms.map_batch_transform` is deprecated, since a transform can be applied directly to a batch of tapes. [(#5676)](https://github.com/PennyLaneAI/pennylane/pull/5676) -* `split_non_commuting` returns the unmodified tape if there are no measurements, instead of an empty list. - [(#5869)](https://github.com/PennyLaneAI/pennylane/pull/5869) -

Documentation 📝

* The documentation for the `default.tensor` device has been added. diff --git a/pennylane/transforms/split_non_commuting.py b/pennylane/transforms/split_non_commuting.py index c15c30b995b..71d7798f309 100644 --- a/pennylane/transforms/split_non_commuting.py +++ b/pennylane/transforms/split_non_commuting.py @@ -28,6 +28,13 @@ from pennylane.typing import Result, ResultBatch +def null_postprocessing(results): + """A postprocessing function returned by a transform that only converts the batch of results + into a result for a single ``QuantumTape``. + """ + return results[0] + + @transform def split_non_commuting( tape: qml.tape.QuantumScript, @@ -244,7 +251,7 @@ def circuit(x): """ if len(tape.measurements) == 0: - return [tape], lambda x: x[0] + return [tape], null_postprocessing # Special case for a single measurement of a Sum or Hamiltonian, in which case # the grouping information can be computed and cached in the observable.