mirror of https://github.com/Qiskit/qiskit.git
Improve reverse_bits to support registerless bits (#7423)
* Improve reverse_bits to support registerless bits * Change the algorithm of reverse_bits * Reimplement reverse_bits with reversed bits Also add more test cases. * Simplify bit lookups Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
This commit is contained in:
parent
0041b6ff26
commit
b898359192
|
@ -475,37 +475,51 @@ class QuantumCircuit:
|
|||
.. parsed-literal::
|
||||
|
||||
┌───┐
|
||||
q_0: ┤ H ├─────■──────
|
||||
└───┘┌────┴─────┐
|
||||
q_1: ─────┤ RX(1.57) ├
|
||||
└──────────┘
|
||||
a_0: ┤ H ├──■─────────────────
|
||||
└───┘┌─┴─┐
|
||||
a_1: ─────┤ X ├──■────────────
|
||||
└───┘┌─┴─┐
|
||||
a_2: ──────────┤ X ├──■───────
|
||||
└───┘┌─┴─┐
|
||||
b_0: ───────────────┤ X ├──■──
|
||||
└───┘┌─┴─┐
|
||||
b_1: ────────────────────┤ X ├
|
||||
└───┘
|
||||
|
||||
output:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
┌──────────┐
|
||||
q_0: ─────┤ RX(1.57) ├
|
||||
┌───┐└────┬─────┘
|
||||
q_1: ┤ H ├─────■──────
|
||||
┌───┐
|
||||
b_0: ────────────────────┤ X ├
|
||||
┌───┐└─┬─┘
|
||||
b_1: ───────────────┤ X ├──■──
|
||||
┌───┐└─┬─┘
|
||||
a_0: ──────────┤ X ├──■───────
|
||||
┌───┐└─┬─┘
|
||||
a_1: ─────┤ X ├──■────────────
|
||||
┌───┐└─┬─┘
|
||||
a_2: ┤ H ├──■─────────────────
|
||||
└───┘
|
||||
"""
|
||||
circ = QuantumCircuit(
|
||||
*reversed(self.qregs),
|
||||
*reversed(self.cregs),
|
||||
list(reversed(self.qubits)),
|
||||
list(reversed(self.clbits)),
|
||||
name=self.name,
|
||||
global_phase=self.global_phase,
|
||||
)
|
||||
num_qubits = self.num_qubits
|
||||
num_clbits = self.num_clbits
|
||||
old_qubits = self.qubits
|
||||
old_clbits = self.clbits
|
||||
new_qubits = circ.qubits
|
||||
new_clbits = circ.clbits
|
||||
new_qubit_map = circ.qubits[::-1]
|
||||
new_clbit_map = circ.clbits[::-1]
|
||||
for reg in reversed(self.qregs):
|
||||
bits = [new_qubit_map[self.find_bit(qubit).index] for qubit in reversed(reg)]
|
||||
circ.add_register(QuantumRegister(bits=bits, name=reg.name))
|
||||
for reg in reversed(self.cregs):
|
||||
bits = [new_clbit_map[self.find_bit(clbit).index] for clbit in reversed(reg)]
|
||||
circ.add_register(ClassicalRegister(bits=bits, name=reg.name))
|
||||
|
||||
for inst, qargs, cargs in self.data:
|
||||
new_qargs = [new_qubits[num_qubits - old_qubits.index(q) - 1] for q in qargs]
|
||||
new_cargs = [new_clbits[num_clbits - old_clbits.index(c) - 1] for c in cargs]
|
||||
new_qargs = [new_qubit_map[self.find_bit(qubit).index] for qubit in qargs]
|
||||
new_cargs = [new_clbit_map[self.find_bit(clbit).index] for clbit in cargs]
|
||||
circ._append(inst, new_qargs, new_cargs)
|
||||
return circ
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed :meth:`.QuantumCircuit.reverse_bits` with circuits containing registerless
|
||||
:class:`.Qubit` and :class:`.Clbit`. For example, the following will now work::
|
||||
|
||||
from qiskit.circuit import QuantumCircuit, Qubit, Clbit
|
||||
|
||||
qc = QuantumCircuit([Qubit(), Clbit()])
|
||||
qc.h(0).c_if(qc.clbits[0], 0)
|
||||
qc.reverse_bits()
|
|
@ -1008,6 +1008,80 @@ class TestCircuitOperations(QiskitTestCase):
|
|||
|
||||
self.assertEqual(qc.reverse_bits(), expected)
|
||||
|
||||
def test_reverse_bits_with_overlapped_registers(self):
|
||||
"""Test reversing order of bits when registers are overlapped."""
|
||||
qr1 = QuantumRegister(2, "a")
|
||||
qr2 = QuantumRegister(bits=[qr1[0], qr1[1], Qubit()], name="b")
|
||||
qc = QuantumCircuit(qr1, qr2)
|
||||
qc.h(qr1[0])
|
||||
qc.cx(qr1[0], qr1[1])
|
||||
qc.cx(qr1[1], qr2[2])
|
||||
|
||||
qr2 = QuantumRegister(bits=[Qubit(), qr1[0], qr1[1]], name="b")
|
||||
expected = QuantumCircuit(qr2, qr1)
|
||||
expected.h(qr1[1])
|
||||
expected.cx(qr1[1], qr1[0])
|
||||
expected.cx(qr1[0], qr2[0])
|
||||
|
||||
self.assertEqual(qc.reverse_bits(), expected)
|
||||
|
||||
def test_reverse_bits_with_registerless_bits(self):
|
||||
"""Test reversing order of registerless bits."""
|
||||
q0 = Qubit()
|
||||
q1 = Qubit()
|
||||
c0 = Clbit()
|
||||
c1 = Clbit()
|
||||
qc = QuantumCircuit([q0, q1], [c0, c1])
|
||||
qc.h(0)
|
||||
qc.cx(0, 1)
|
||||
qc.x(0).c_if(1, True)
|
||||
qc.measure(0, 0)
|
||||
|
||||
expected = QuantumCircuit([c1, c0], [q1, q0])
|
||||
expected.h(1)
|
||||
expected.cx(1, 0)
|
||||
expected.x(1).c_if(0, True)
|
||||
expected.measure(1, 1)
|
||||
|
||||
self.assertEqual(qc.reverse_bits(), expected)
|
||||
|
||||
def test_reverse_bits_with_registers_and_bits(self):
|
||||
"""Test reversing order of bits with registers and registerless bits."""
|
||||
qr = QuantumRegister(2, "a")
|
||||
q = Qubit()
|
||||
qc = QuantumCircuit(qr, [q])
|
||||
qc.h(qr[0])
|
||||
qc.cx(qr[0], qr[1])
|
||||
qc.cx(qr[1], q)
|
||||
|
||||
expected = QuantumCircuit([q], qr)
|
||||
expected.h(qr[1])
|
||||
expected.cx(qr[1], qr[0])
|
||||
expected.cx(qr[0], q)
|
||||
|
||||
self.assertEqual(qc.reverse_bits(), expected)
|
||||
|
||||
def test_reverse_bits_with_mixed_overlapped_registers(self):
|
||||
"""Test reversing order of bits with overlapped registers and registerless bits."""
|
||||
q = Qubit()
|
||||
qr1 = QuantumRegister(bits=[q, Qubit()], name="qr1")
|
||||
qr2 = QuantumRegister(bits=[qr1[1], Qubit()], name="qr2")
|
||||
qc = QuantumCircuit(qr1, qr2, [Qubit()])
|
||||
qc.h(q)
|
||||
qc.cx(qr1[0], qr1[1])
|
||||
qc.cx(qr1[1], qr2[1])
|
||||
qc.cx(2, 3)
|
||||
|
||||
qr2 = QuantumRegister(2, "qr2")
|
||||
qr1 = QuantumRegister(bits=[qr2[1], q], name="qr1")
|
||||
expected = QuantumCircuit([Qubit()], qr2, qr1)
|
||||
expected.h(qr1[1])
|
||||
expected.cx(qr1[1], qr1[0])
|
||||
expected.cx(qr1[0], qr2[0])
|
||||
expected.cx(1, 0)
|
||||
|
||||
self.assertEqual(qc.reverse_bits(), expected)
|
||||
|
||||
def test_cnot_alias(self):
|
||||
"""Test that the cnot method alias adds a cx gate."""
|
||||
qc = QuantumCircuit(2)
|
||||
|
|
Loading…
Reference in New Issue