Lewati ke konten utama
Proyek ini masih dalam tahap beta. Menemukan bug? Buat isu GitHub. Punya pertanyaan atau ide? Tanya di Discussions — kami sangat menghargai masukan kamu!
Bagaimana kualitas terjemahan di halaman ini?

Panduan Cepat

Panduan ini menunjukkan contoh kerja minimal dari paket qiskit-addon-pna. Kita pakai propagated noise absorption (PNA) untuk membangun observable yang meredam noise. Diberikan sebuah circuit dan noise model Pauli-Lindblad, PNA merambatkan observable secara klasik melalui noise channel invers. Mengukur observable hasilnya pada QPU yang noisy akan memitigasi noise gate yang telah dipelajari.

Untuk melihat cara membangun alur kerja yang realistis dan menjalankannya di hardware kuantum dengan directed execution model, termasuk mempelajari noise model dengan NoiseLearnerV3, lihat tutorial PNA di IBM Quantum Platform.

1. Siapkan input untuk PNA​

PNA menerima circuit, noise model, dan observable sebagai input. Di sini kita membangun model Ising medan transversal 10-qubit yang di-Trotterize pada rantai 1D. Kita membuat noise model Pauli-Lindblad 2-local acak untuk setiap gate entangling dan menanamkannya sebagai instruksi Qiskit Aer PauliLindbladError tepat sebelum gate tersebut. Kita memilih observable Pauli-Z berbobot 4 untuk diukur.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"matplotlib": "matplotlib", "numpy": "numpy", "qiskit": "qiskit", "qiskit_addon_pna": "qiskit-addon-pna", "qiskit_aer": "qiskit-aer"}
_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.quantum_info import SparsePauliOp, pauli_basis
from qiskit_aer.noise import PauliLindbladError

def random_pauli_lindblad_noise(generators, seed, noise_scale=2e-3):
rates = np.random.default_rng(seed).random(len(generators)) * noise_scale
return PauliLindbladError(generators, rates)

def ising_circuit(
num_qubits,
layers,
edge_noise=None,
*,
num_steps=3,
rx_angle=np.pi / 8,
rzz_angle=-np.pi / 2,
):
"""Trotterized transverse-field Ising model; edge_noise=None gives the noiseless circuit."""
qc = QuantumCircuit(num_qubits)
for _ in range(num_steps):
qc.rx(rx_angle, range(num_qubits))
for layer in layers:
for edge in layer:
if edge_noise is not None:
qc.append(
edge_noise[edge], edge
) # inject synthetic gate noise
qc.rzz(rzz_angle, *edge)
return qc

num_qubits = 10

# Two entangling layers per Trotter step: even and odd bonds of a 1D chain
layers = [
[(i, i + 1) for i in range(0, num_qubits - 1, 2)],
[(i, i + 1) for i in range(1, num_qubits - 1, 2)],
]
edges = [edge for layer in layers for edge in layer]

# Random 2-local Pauli-Lindblad noise, one instance per entangling gate
two_qubit_paulis = SparsePauliOp(
[p for p in pauli_basis(2) if np.sum(p.x + p.z)]
).paulis
edge_noise = {
edge: random_pauli_lindblad_noise(two_qubit_paulis, seed=1234 + j)
for j, edge in enumerate(edges)
}

noisy_circuit = ising_circuit(num_qubits, layers, edge_noise)

# A single weight-4 observable: <Z3 Z4 Z5 Z6>
observable = SparsePauliOp.from_sparse_list(
[("ZZZZ", [3, 4, 5, 6], 1.0)], num_qubits=num_qubits
)

noisy_circuit.draw("mpl", fold=-1, scale=0.6)

Output of the previous code cell

2. Hasilkan observable yang meredam noise​

generate_noise_mitigating_observable merambatkan setiap generator Pauli dari noise channel invers maju sampai akhir circuit. Observable kemudian dirambatkan mundur melalui noise channel invers, menghasilkan observable baru O~\tilde{O}. Tiga parameter kunci memengaruhi biaya komputasi:

  • max_err_terms: jumlah suku yang dipertahankan di setiap generator anti-noise saat dirambatkan maju.

  • max_obs_terms: jumlah suku yang dipertahankan di O~\tilde{O}.

  • atol: suku dengan magnitudo koefisien di bawah ambang ini dibuang.

Untuk circuit kecil yang hampir Clifford ini, kita set batas suku tinggi dan memakai atol yang sedang, sehingga O~\tilde{O} tetap kecil dan kita bisa mengukur semua sukunya.

Catatan: Fungsi ini memakai Python multiprocessing. Saat dijalankan sebagai script, panggil di dalam guard if __name__ == "__main__":.

from qiskit_addon_pna import generate_noise_mitigating_observable

mitigating_observable = generate_noise_mitigating_observable(
noisy_circuit,
observable,
max_err_terms=100_000,
max_obs_terms=100_000,
atol=1e-5,
num_processes=4,
)

print(f"Original observable: {len(observable)} term")
print(f"Noise-mitigating observable: {len(mitigating_observable)} terms")
Original observable: 1 term
Noise-mitigating observable: 207 terms

3. Mitigasi error gate dengan mengukur observable yang meredam noise​

Di sini kita lihat bahwa observable baru secara efektif memitigasi noise gate yang memengaruhi eksperimen.

import matplotlib.pyplot as plt
from qiskit_aer.primitives import EstimatorV2

noiseless_circuit = ising_circuit(num_qubits, layers)

# density_matrix method at zero precision -> exact expectation values (no shot noise)
estimator = EstimatorV2(
options={
"backend_options": {"method": "density_matrix"},
"default_precision": 0.0,
}
)

ideal, noisy, mitigated = (
result.data.evs
for result in estimator.run(
[
(noiseless_circuit, observable),
(noisy_circuit, observable),
(noisy_circuit, mitigating_observable),
]
).result()
)

print(f"Ideal (noiseless): {ideal:.4f}")
print(f"Noisy (unmitigated): {noisy:.4f}")
print(f"Mitigated (PNA): {mitigated:.4f}")

fig, ax = plt.subplots()
ax.bar(
["Noisy", "Mitigated"],
[noisy, mitigated],
width=0.6,
color=["#b0b0b0", "#4c4c4c"],
)
ax.axhline(ideal, color="green", linestyle="--", label="Ideal (noiseless)")
ax.set_ylabel(r"$\langle Z_3 Z_4 Z_5 Z_6 \rangle$")
ax.legend()
plt.show()
Ideal (noiseless): 0.8073
Noisy (unmitigated): 0.6431
Mitigated (PNA): 0.8071

Output of the previous code cell