Permulaan Pantas
Panduan ini menunjukkan contoh kerja minimum bagi pakej qiskit-paulice. Kami menggunakan semakan Pauli ruang-masa untuk mengesan ralat semasa pelaksanaan litar Clifford, kemudian memilih lepas (postselect) hanya sampel yang tiada ralat dikesan. Untuk aliran kerja hujung-ke-hujung yang lebih terperinci yang mengukur peningkatan fidelity, lihat tutorial mendalam.
Langkah aliran kerja
- Sediakan input: litar muatan Clifford, qubit sasaran/ancilla untuk menempatkan semakan, dan model hingar.
- Cari semakan Pauli ruang-masa yang baik dan tambahkannya ke litar.
- Sampel litar yang telah disemak.
- Pilih lepas hanya sampel yang tiada ralat dikesan.
1. Sediakan input
add_pauli_checks menerima litar Clifford yang berakhir dengan pengukuran (atau, dengan kwarg stabilizers, litar tanpa pengukuran, seperti dalam panduan kod ruang-masa), qubit sasaran yang akan digunakan untuk melaksanakan semakan, dan model hingar yang digunakan untuk menilai calon semakan. Di sini kami membina litar Clifford rawak yang cetek, menempatkannya pada rantaian 1D qubit fizikal pada ibm_boston, memasangkan setiap qubit muatan dengan ancilla jiran (supaya semakan tidak memerlukan gate SWAP), dan menyimpulkan model hingar depolarizing kasar daripada data penanda aras backend.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_aer": "qiskit-aer", "qiskit_ibm_runtime": "qiskit-ibm-runtime", "qiskit_paulice": "qiskit-paulice"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_paulice.layout import get_check_qubits
from qiskit_paulice.noise_models import NoiseModel
# Backend and a 1D chain of physical qubits to run on
backend = QiskitRuntimeService().backend("ibm_boston")
layout = [68, 69, 78, 89, 90, 91, 98, 111, 112, 113, 119, 133]
# A shallow brickwork random Clifford payload circuit
rng = np.random.default_rng(1764)
circuit = QuantumCircuit(len(layout))
circuit.h(range(circuit.num_qubits))
for d in range(4):
for i in range(d % 2, circuit.num_qubits - 1, 2):
circuit.cz(i, i + 1)
for q in range(circuit.num_qubits):
if rng.integers(0, 2):
circuit.sx(q)
if rng.integers(0, 2):
circuit.s(q)
circuit.measure_all()
# Pair each payload qubit with a neighboring ancilla to host a check (no SWAPs needed)
target_qubits, ancilla_qubits = get_check_qubits(backend.coupling_map, layout)
# A rough depolarizing noise model from backend benchmark data, used to score checks
noise_model = NoiseModel.from_backend(
backend, layout, uniform_gate_noise=True
)
circuit.draw("mpl", fold=-1)

2. Cari dan tambah semakan Pauli ruang-masa
add_pauli_checks mencari semakan berwajaran rendah yang berkesan pada setiap qubit sasaran dan menambahkannya ke litar, lalu memulangkan jujukan contoh CheckedCircuit. Contoh CheckedCircuit mengandungi bilangan semakan yang meningkat, daripada 0 semakan hingga satu semakan bagi setiap qubit sasaran. Setiap semakan meningkatkan keupayaan pengesanan ralat dengan kos kedalaman litar yang sedikit meningkat. Untuk contoh ini kami akan menggunakan litar dengan semakan pada setiap qubit sasaran.
from qiskit_paulice import add_pauli_checks
# The circuit has virtual qubits, so we specify our target qubits with virtual indices
target_qubits_v = [layout.index(q) for q in target_qubits]
# Add spacetime Pauli checks
checked_circuit = add_pauli_checks(circuit, target_qubits_v, noise_model)[-1]
checked_circuit.circuit.draw("mpl", fold=-1, scale=0.4, idle_wires=False)

3. Sampel litar yang telah disemak
Sebelum membuat pensampelan, kami mentranspil litar yang telah disemak ke atas qubit fizikal (initial_layout = layout + ancilla_qubits) dan ke dalam set gate asas natif ibm_boston. Untuk meniru QPU yang bising, kami membuat pensampelan dengan backend penstabil Aer yang bising yang kadar ralatnya sepadan dengan noise_model yang digunakan untuk memilih semakan.
from qiskit import transpile
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel as AerNoiseModel
from qiskit_aer.noise import ReadoutError, depolarizing_error
# Transpile once: lay the checked circuit out on our qubits and into the native basis
isa_circuit = transpile(
checked_circuit.circuit,
backend,
initial_layout=layout + ancilla_qubits,
optimization_level=0,
)
# Build an Aer noise model matching the depolarizing model used to pick checks
aer_noise = AerNoiseModel()
aer_noise.add_all_qubit_quantum_error(
depolarizing_error(noise_model.gate_noise, 2), ["cz"]
)
p = noise_model.readout_noise
aer_noise.add_all_qubit_readout_error(ReadoutError([[1 - p, p], [p, 1 - p]]))
simulator = AerSimulator(method="stabilizer", noise_model=aer_noise)
counts = (
simulator.run(isa_circuit, shots=1000, seed_simulator=1764)
.result()
.get_counts()
)
print(f"sampled {sum(counts.values())} shots")
sampled 1000 shots
4. Pilih lepas sampel tanpa ralat dikesan
get_postselection_method memetakan setiap tembakan kepada vektor sindrom; kami hanya mengekalkan tembakan dengan sindrom sifar sepenuhnya — iaitu tembakan yang tiada semakan mengesan ralat. Membuang tembakan yang ditandakan menyingkirkan ralat yang dikesan daripada taburan yang tinggal, sekali gus meningkatkan fidelity-nya dengan kos kadar pensampelan yang lebih rendah. Lihat tutorial untuk perbandingan fidelity secara kuantitatif.
# Keep only the shots in which no check reported an error
ps_fn = checked_circuit.get_postselection_method()
counts_postselected = {
bs: n for bs, n in counts.items() if not ps_fn(bs).any()
}
kept, total = sum(counts_postselected.values()), sum(counts.values())
print(f"kept {kept} of {total} shots ({kept / total:.0%})")
kept 927 of 1000 shots (93%)