Lumaktaw sa pangunahing nilalaman
Ang proyektong ito ay nasa beta. Nakakita ng bug? Mag-bukas ng GitHub issue. May tanong o ideya? Magtanong sa Discussions — gusto naming marinig ang iyong feedback!
Gaano kaganda ang kalidad ng pagsasalin sa pahinang ito?

Mabilisang simula

Ipinapakita ng gabay na ito ang isang minimal na gumaganang halimbawa ng package na qiskit-addon-pna. Gumagamit tayo ng propagated noise absorption (PNA) para bumuo ng noise-mitigating na observable. Kapag may circuit at Pauli-Lindblad noise model, klasikal na ipinapalaganap ng PNA ang observable sa inverse noise channel. Ang pagsukat sa nagresultang observable sa maingay na QPU ay nagmi-mitigate sa natutunang gate noise.

Para makita kung paano bumuo ng makatotohanang workflow at tumakbo sa quantum hardware gamit ang directed execution model, kasama ang pag-aaral ng noise model gamit ang NoiseLearnerV3, tingnan ang PNA tutorial sa IBM Quantum Platform.

1. Ihanda ang mga input para sa PNA​

Ang PNA ay kumukuha ng circuit, noise model, at observable bilang input. Dito, bumubuo tayo ng 10-qubit na Trotterized transverse-field Ising model sa 1D chain. Gumagawa tayo ng random na 2-local Pauli-Lindblad noise model para sa bawat entangling gate at ine-embed ito bilang Qiskit Aer PauliLindbladError instruction bago mismo ang gate na iyon. Pumipili tayo ng weight-4 na Pauli-Z observable na susukatin.

# 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. Buuin ang noise-mitigating na observable​

Ang generate_noise_mitigating_observable ay nagpapalaganap pasulong ng bawat Pauli generator ng inverse noise channel hanggang sa dulo ng circuit. Pagkatapos, ang observable ay ibinabalik pabalik sa inverse noise channel, na nagbabalik ng bagong observable na O~\tilde{O}. Tatlong pangunahing parameter ang nakaaapekto sa gastos ng kalkulasyon:

  • max_err_terms: ang bilang ng mga term na pinapanatili sa bawat anti-noise generator habang ipinapalaganap ito pasulong.

  • max_obs_terms: ang bilang ng mga term na pinapanatili sa O~\tilde{O}.

  • atol: ang mga term na may coefficient magnitude na mas mababa sa threshold na ito ay itinatapon.

Para sa maliit at near-Clifford na circuit na ito, itinatakda nating mataas ang mga limitasyon ng term at gumagamit ng katamtamang atol, kaya nananatiling maliit ang O~\tilde{O} at masusukat natin ang lahat ng term nito.

Tandaan: Gumagamit ang function na ito ng Python multiprocessing. Kapag tumatakbo bilang script, tawagin ito sa loob ng guard na 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. I-mitigate ang mga gate error sa pamamagitan ng pagsukat sa noise-mitigating na observable​

Dito makikita natin na epektibong nagmi-mitigate ang bagong observable sa gate noise na nakaaapekto sa eksperimento.

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