From fedb665ce4d1f87a2046cdf93421b4b041c69b7b Mon Sep 17 00:00:00 2001 From: Erick Winston Date: Sat, 16 Sep 2023 02:51:53 -0400 Subject: [PATCH 1/2] fix bug in qs_decomposition --- qiskit/quantum_info/synthesis/qsd.py | 6 +- test/python/quantum_info/test_synthesis.py | 99 ++++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/qiskit/quantum_info/synthesis/qsd.py b/qiskit/quantum_info/synthesis/qsd.py index b2f00a56045d..80892a606d7e 100644 --- a/qiskit/quantum_info/synthesis/qsd.py +++ b/qiskit/quantum_info/synthesis/qsd.py @@ -243,7 +243,11 @@ def _apply_a2(circ): for i, instruction in enumerate(ccirc.data): if instruction.operation.name == "qsd2q": ind2q.append(i) - if not ind2q: + if len(ind2q) == 0: + return ccirc + elif len(ind2q) == 1: + # No neighbors to merge diagonal into; revert name + ccirc.data[ind2q[0]].operation.name = "Unitary" return ccirc # rolling over diagonals ind2 = None # lint diff --git a/test/python/quantum_info/test_synthesis.py b/test/python/quantum_info/test_synthesis.py index 19ec8b8139e9..043abf8c87f8 100644 --- a/test/python/quantum_info/test_synthesis.py +++ b/test/python/quantum_info/test_synthesis.py @@ -1548,6 +1548,105 @@ def test_opt_a1a2(self, nqubits): elif nqubits == 2: self.assertLessEqual(ccirc.count_ops().get("cx", 0), 3) + def test_a2_opt_single_2q(self): + """ + Test a2_opt when a unitary causes a single final 2-qubit unitary for which this optimization + won't help. This came up in issue 10787. + """ + # this somewhat unique signed permutation matrix seems to cause the issue + mat = np.array( + [ + [ + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 1.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + ], + [ + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 1.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + ], + [ + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + -1.0 + 0.0j, + 0.0 + 0.0j, + ], + [ + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + -1.0 + 0.0j, + ], + [ + 1.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + ], + [ + 0.0 + 0.0j, + 1.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + ], + [ + 0.0 + 0.0j, + 0.0 + 0.0j, + -1.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + ], + [ + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + -1.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + 0.0 + 0.0j, + ], + ] + ) + + gate = UnitaryGate(mat) + qc = QuantumCircuit(3) + qc.append(gate, range(3)) + try: + qc.to_gate().control(1) + except UnboundLocalError as uerr: + self.fail(str(uerr)) + class TestTwoQubitDecomposeUpToDiagonal(QiskitTestCase): """test TwoQubitDecomposeUpToDiagonal class""" From 3e02f81f87f29e09a2a15257f07ad5b5a2620d54 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Tue, 3 Oct 2023 14:05:44 +0200 Subject: [PATCH 2/2] reno --- releasenotes/notes/10787-078d7caa70fc7de8.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 releasenotes/notes/10787-078d7caa70fc7de8.yaml diff --git a/releasenotes/notes/10787-078d7caa70fc7de8.yaml b/releasenotes/notes/10787-078d7caa70fc7de8.yaml new file mode 100644 index 000000000000..ae22987bb75f --- /dev/null +++ b/releasenotes/notes/10787-078d7caa70fc7de8.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fix the Quantum Shannon Decomposition implemented in :func:`.qs_decomposition`. When a unitary + could not take advantage of the diagonal commutation optimization, it used to error. + Now, it leaves it as undecomposed 2-qubit unitary gate. + Fixes `#10787 `__