Wire Cutting Phrased as a Two-Qubit `Move` Instruction
หน้านี้ยังไม่ได้รับการแปล คุณกำลังดูเวอร์ชันต้นฉบับภาษาอังกฤษ
In this tutorial, we will reconstruct expectation values of a seven-qubit circuit by splitting it into two four-qubit circuits using wire cutting.
These are the steps that we will take in this Qiskit pattern:
- Step 1: Map problem to quantum circuits and operators:
- Map the hamiltonian onto a quantum circuit.
- Step 2: Optimize for target hardware [Uses the cutting addon]:
- Cut the circuit and observable.
- Transpile the subexperiments for hardware.
- Step 3: Execute on target hardware:
- Run the subexperiments obtained in Step 2 using a
Samplerprimitive.
- Run the subexperiments obtained in Step 2 using a
- Step 4: Post-process results [Uses the cutting addon]:
- Combine the results of Step 3 to reconstruct the expectation value of the observable in question.
Step 1: Map
Create a circuit to cut
First, we begin with a circuit inspired by Fig. 1(a) of arXiv:2302.03366v1.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-addon-cutting qiskit-aer qiskit-ibm-runtime
import numpy as np
from qiskit import QuantumCircuit
qc_0 = QuantumCircuit(7)
for i in range(7):
qc_0.rx(np.pi / 4, i)
qc_0.cx(0, 3)
qc_0.cx(1, 3)
qc_0.cx(2, 3)
qc_0.cx(3, 4)
qc_0.cx(3, 5)
qc_0.cx(3, 6)
qc_0.cx(0, 3)
qc_0.cx(1, 3)
qc_0.cx(2, 3)
<qiskit.circuit.instructionset.InstructionSet at 0x7f16ab191a80>
qc_0.draw("mpl")

Specify an observable
from qiskit.quantum_info import SparsePauliOp
observable = SparsePauliOp(["ZIIIIII", "IIIZIII", "IIIIIIZ"])
Step 2: Optimize
Create a new circuit where Move instructions have been placed at the desired cut locations
Given the above circuit, we would like to place two wire cuts on the middle qubit line, so that the circuit can separate into two circuits of four qubits each. One way to do this is to manually place two-qubit Move instructions that move the state from one qubit wire to another. A Move instruction is conceptually equivalent to a reset operation on the second qubit, followed by a SWAP gate. The effect of this instruction is to transfer the state of the first (source) qubit to the second (detination) qubit, while discarding the incoming state of the second qubit. For this to work as intended, it is important that the second (destination) qubit share no entanglement with the remainder of the system; otherwise, the reset operation will cause the state of the remainder of the system to be partially collapsed.
Here, we build a new circuit with one additional qubit and the Move operations in place. In this example, we are able to reuse a qubit: the source qubit of the first Move becomes the destination qubit of the second Move operation.
Note: As an alternative to working directly with Move instructions, one may choose to mark wire cuts using a single-qubit CutWire instruction. The cut_wires function exists to transform CutWires to Move instructions on newly allocated qubits. However, in contrast to the manual method, this automatic method does not allow for the re-use of qubit wires. See the CutWire how-to guide for details.
from qiskit_addon_cutting.instructions import Move
qc_1 = QuantumCircuit(8)
for i in [*range(4), *range(5, 8)]:
qc_1.rx(np.pi / 4, i)
qc_1.cx(0, 3)
qc_1.cx(1, 3)
qc_1.cx(2, 3)
qc_1.append(Move(), [3, 4])
qc_1.cx(4, 5)
qc_1.cx(4, 6)
qc_1.cx(4, 7)
qc_1.append(Move(), [4, 3])
qc_1.cx(0, 3)
qc_1.cx(1, 3)
qc_1.cx(2, 3)
qc_1.draw("mpl")

Create observable to go with the new circuit
This observable corresponds with observable, but we must account correctly for the extra qubit wire that has been added (i.e., we insert an "I" at index 4). Note that in Qiskit, the string representation qubit-0 corresponds to the right-most Pauli character.
observable_expanded = SparsePauliOp(["ZIIIIIII", "IIIIZIII", "IIIIIIIZ"])