Lumaktaw sa pangunahing nilalaman

Bumuo ng mga noise model

Package versions

Ang code sa pahinang ito ay ginawa gamit ang mga sumusunod na kinakailangan. Inirerekomenda naming gamitin ang mga bersyong ito o mas bago.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
qiskit-aer~=0.17

Ipinapakita ng pahinang ito kung paano gamitin ang Qiskit Aer noise module para bumuo ng mga noise model para sa pag-simulate ng mga quantum circuit sa harap ng mga error. Ito ay kapaki-pakinabang para sa pag-emulate ng maingay na mga quantum processor at para sa pag-aaral ng epekto ng ingay sa pagpapatupad ng mga quantum algorithm.

# Added by doQumentation β€” required packages for this notebook
!pip install -q numpy qiskit qiskit-aer qiskit-ibm-runtime
import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import Kraus, SuperOp
from qiskit.visualization import plot_histogram
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator

# Import from Qiskit Aer noise module
from qiskit_aer.noise import (
NoiseModel,
QuantumError,
ReadoutError,
depolarizing_error,
pauli_error,
thermal_relaxation_error,
)

Qiskit Aer noise module​

Ang Qiskit Aer noise module ay naglalaman ng mga Python class para bumuo ng mga customized na noise model para sa simulation. May tatlong pangunahing klase:

  1. Ang NoiseModel class na nag-iimbak ng noise model na ginagamit para sa maingay na simulation.

  2. Ang QuantumError class na naglalarawan ng mga CPTP gate error. Maaari itong ilapat:

    • Pagkatapos ng mga gate o reset na instruksyon
    • Bago ang mga measure na instruksyon.
  3. Ang ReadoutError class na naglalarawan ng mga classical readout error.

Pag-initialize ng noise model mula sa isang backend​

Maaari kang mag-initialize ng noise model na may mga parameter na nakuha mula sa pinakabagong calibration data ng isang pisikal na backend:

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.backend("ibm_fez")
noise_model = NoiseModel.from_backend(backend)

Magbubunga ito ng noise model na halos inaproksima ang mga error na mararanasan kapag ginamit ang backend na iyon. Kung gusto mong mas detalyadong kontrol sa mga parameter ng noise model, kailangan mong gumawa ng sariling noise model, tulad ng inilarawan sa natitirang bahagi ng pahinang ito.

Mga quantum error​

Sa halip na direktang harapin ang QuantumError na object, maraming helper function ang umiiral para awtomatikong makabuo ng isang tiyak na uri ng parameterized na quantum error. Ang mga ito ay nasa loob ng noise module at kinabibilangan ng mga function para sa maraming karaniwang uri ng error na ginagamit sa quantum computing research. Ang mga pangalan ng function at ang uri ng error na ibinabalik ng bawat isa ay:

Standard na error functionMga detalye
kraus_errorisang pangkalahatang n-qubit CPTP error channel na ibinibigay bilang listahan ng mga Kraus matrix [K0,...][K_0, ...].
mixed_unitary_errorisang n-qubit mixed unitary error na ibinibigay bilang listahan ng mga unitary matrix at probabilidad [(U0,p0),...][(U_0, p_0),...].
coherent_unitary_errorisang n-qubit coherent unitary error na ibinibigay bilang isang unitary matrix UU.
pauli_errorisang n-qubit Pauli error channel (mixed unitary) na ibinibigay bilang listahan ng mga Pauli at probabilidad [(P0,p0),...][(P_0, p_0),...]
depolarizing_errorisang n-qubit depolarizing error channel na parameterized ng isang depolarization probability pp.
reset_errorisang single-qubit reset error na parameterized ng mga probabilidad p0,p1p_0, p_1 ng pag-reset sa estado na ∣0⟩\vert0\rangle, ∣1⟩\vert1\rangle.
thermal_relaxation_errorisang single-qubit thermal relaxation channel na parameterized ng mga relaxation time constant T1T_1, T2T_2, gate time tt, at excited state thermal population p1p_1.
phase_amplitude_damping_errorIsang single-qubit generalized combined phase at amplitude damping error channel na ibinibigay ng isang amplitude damping parameter Ξ»\lambda, isang phase damping parameter Ξ³\gamma, at isang excited state thermal population p1p_1.
amplitude_damping_errorIsang single-qubit generalized amplitude damping error channel na ibinibigay ng isang amplitude damping parameter Ξ»\lambda, at isang excited state thermal population p1p_1.
phase_damping_errorIsang single-qubit phase damping error channel na ibinibigay ng isang phase damping parameter Ξ³\gamma.

Pagsasama ng mga quantum error​

Ang mga instance ng QuantumError ay maaaring pagsamahin sa pamamagitan ng composition, tensor product, at tensor expansion (reversed order tensor product) para makagawa ng mga bagong QuantumError tulad ng:

  • Composition: E(ρ)=E2(E1(ρ))\cal{E}(\rho)=\cal{E_2}(\cal{E_1}(\rho)) bilang error = error1.compose(error2)
  • Tensor product: E(ρ)=(E1βŠ—E2)(ρ)\cal{E}(\rho) =(\cal{E_1}\otimes\cal{E_2})(\rho) bilang error = error1.tensor(error2)
  • Expand product: E(ρ)=(E2βŠ—E1)(ρ)\cal{E}(\rho) =(\cal{E_2}\otimes\cal{E_1})(\rho) bilang error = error1.expand(error2)

Halimbawa​

Para bumuo ng 5% single-qubit bit-flip error:

# Construct a 1-qubit bit-flip and phase-flip errors
p_error = 0.05
bit_flip = pauli_error([("X", p_error), ("I", 1 - p_error)])
phase_flip = pauli_error([("Z", p_error), ("I", 1 - p_error)])
print(bit_flip)
print(phase_flip)
QuantumError on 1 qubits. Noise circuits:
P(0) = 0.05, Circuit =
β”Œβ”€β”€β”€β”
q: ─ X β”œ
β””β”€β”€β”€β”˜
P(1) = 0.95, Circuit =
β”Œβ”€β”€β”€β”
q: ─ I β”œ
β””β”€β”€β”€β”˜
QuantumError on 1 qubits. Noise circuits:
P(0) = 0.05, Circuit =
β”Œβ”€β”€β”€β”
q: ─ Z β”œ
β””β”€β”€β”€β”˜
P(1) = 0.95, Circuit =
β”Œβ”€β”€β”€β”
q: ─ I β”œ
β””β”€β”€β”€β”˜
# Compose two bit-flip and phase-flip errors
bitphase_flip = bit_flip.compose(phase_flip)
print(bitphase_flip)
QuantumError on 1 qubits. Noise circuits:
P(0) = 0.0025000000000000005, Circuit =
β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”
q: ─ X β”œβ”€ Z β”œ
β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜
P(1) = 0.0475, Circuit =
β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”
q: ─ X β”œβ”€ I β”œ
β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜
P(2) = 0.0475, Circuit =
β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”
q: ─ I β”œβ”€ Z β”œ
β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜
P(3) = 0.9025, Circuit =
β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”
q: ─ I β”œβ”€ I β”œ
β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜
# Tensor product two bit-flip and phase-flip errors with
# bit-flip on qubit-0, phase-flip on qubit-1
error2 = phase_flip.tensor(bit_flip)
print(error2)
QuantumError on 2 qubits. Noise circuits:
P(0) = 0.0025000000000000005, Circuit =
β”Œβ”€β”€β”€β”
q_0: ─ X β”œ
β”œβ”€β”€β”€β”€
q_1: ─ Z β”œ
β””β”€β”€β”€β”˜
P(1) = 0.0475, Circuit =
β”Œβ”€β”€β”€β”
q_0: ─ I β”œ
β”œβ”€β”€β”€β”€
q_1: ─ Z β”œ
β””β”€β”€β”€β”˜
P(2) = 0.0475, Circuit =
β”Œβ”€β”€β”€β”
q_0: ─ X β”œ
β”œβ”€β”€β”€β”€
q_1: ─ I β”œ
β””β”€β”€β”€β”˜
P(3) = 0.9025, Circuit =
β”Œβ”€β”€β”€β”
q_0: ─ I β”œ
β”œβ”€β”€β”€β”€
q_1: ─ I β”œ
β””β”€β”€β”€β”˜

Pag-convert sa at mula sa mga QuantumChannel operator​

Maaari rin tayong mag-convert pabalik-balik sa pagitan ng mga QuantumError object sa Qiskit Aer at mga QuantumChannel object sa Qiskit.

# Convert to Kraus operator
bit_flip_kraus = Kraus(bit_flip)
print(bit_flip_kraus)
Kraus([[[-9.74679434e-01+0.j,  0.00000000e+00+0.j],
[ 0.00000000e+00+0.j, -9.74679434e-01+0.j]],

[[ 0.00000000e+00+0.j, 2.23606798e-01+0.j],
[ 2.23606798e-01+0.j, -4.96506831e-17+0.j]]],
input_dims=(2,), output_dims=(2,))
# Convert to Superoperator
phase_flip_sop = SuperOp(phase_flip)
print(phase_flip_sop)
SuperOp([[1. +0.j, 0. +0.j, 0. +0.j, 0. +0.j],
[0. +0.j, 0.9+0.j, 0. +0.j, 0. +0.j],
[0. +0.j, 0. +0.j, 0.9+0.j, 0. +0.j],
[0. +0.j, 0. +0.j, 0. +0.j, 1. +0.j]],
input_dims=(2,), output_dims=(2,))
# Convert back to a quantum error
print(QuantumError(bit_flip_kraus))

# Check conversion is equivalent to original error
QuantumError(bit_flip_kraus) == bit_flip
QuantumError on 1 qubits. Noise circuits:
P(0) = 1.0, Circuit =
β”Œβ”€β”€β”€β”€β”€β”€β”€β”
q: ─ kraus β”œ
β””β”€β”€β”€β”€β”€β”€β”€β”˜
True

Readout error​

Ang mga classical readout error ay tinukoy ng isang listahan ng mga assignment probability vector P(A∣B)P(A|B):

  • Ang AA ay ang naitala na classical bit value
  • Ang BB ay ang tunay na bit value na ibinalik mula sa pagsukat

Halimbawa, para sa isang qubit: P(A∣B)=[P(A∣0),P(A∣1)] P(A|B) = [P(A|0), P(A|1)].

# Measurement misassignment probabilities
p0given1 = 0.1
p1given0 = 0.05

ReadoutError([[1 - p1given0, p1given0], [p0given1, 1 - p0given1]])
ReadoutError([[0.95 0.05]
[0.1 0.9 ]])

Ang mga readout error ay maaari ring pagsamahin gamit ang compose, tensor, at expand, tulad ng sa mga quantum error.

Magdagdag ng mga error sa isang noise model​

Kapag nagdadagdag ng quantum error sa isang noise model, kailangan nating tukuyin ang uri ng instruction na kinakatawan nito at kung aling mga Qubit ang apektado. May dalawang uri ng quantum error:

  1. All-qubit quantum error
  2. Specific qubit quantum error

1. All-qubit quantum error​

Inilalapat nito ang parehong error sa bawat pagkakataon ng isang instruction, anuman ang mga Qubit na kinakatawan nito.

Idinaragdag ito bilang noise_model.add_all_qubit_quantum_error(error, instructions):

# Create an empty noise model
noise_model = NoiseModel()

# Add depolarizing error to all single qubit u1, u2, u3 gates
error = depolarizing_error(0.05, 1)
noise_model.add_all_qubit_quantum_error(error, ["u1", "u2", "u3"])

# Print noise model info
print(noise_model)
NoiseModel:
Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']
Instructions with noise: ['u3', 'u2', 'u1']
All-qubits errors: ['u1', 'u2', 'u3']

2. Specific qubit quantum error​

Inilalapat nito ang error sa bawat pagkakataon ng isang instruction na kumikilos sa isang tinukoy na listahan ng mga Qubit. Pansinin na mahalaga ang pagkakasunod ng mga Qubit: halimbawa, ang isang error na inilapat sa mga Qubit [0, 1] para sa isang two-qubit gate ay iba sa isang inilapat sa mga Qubit [1, 0].

Idinaragdag ito bilang noise_model.add_quantum_error(error, instructions, qubits):

# Create an empty noise model
noise_model = NoiseModel()

# Add depolarizing error to all single qubit u1, u2, u3 gates on qubit 0 only
error = depolarizing_error(0.05, 1)
noise_model.add_quantum_error(error, ["u1", "u2", "u3"], [0])

# Print noise model info
print(noise_model)
NoiseModel:
Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']
Instructions with noise: ['u3', 'u2', 'u1']
Qubits with noise: [0]
Specific qubit errors: [('u1', (0,)), ('u2', (0,)), ('u3', (0,))]

Tala tungkol sa non-local qubit quantum error​

Hindi sinusuportahan ng NoiseModel ang pagdaragdag ng non-local qubit quantum errors. Dapat itong pangasiwaan sa labas ng NoiseModel. Ibig sabihin nito, kung kailangan mong ipasok ang iyong mga quantum error sa iyong Circuit sa ilalim ng iyong sariling mga kundisyon, dapat kang sumulat ng sariling transpiler pass (TransformationPass) at patakbuhin ang pass bago patakbuhin ang simulator.

Magpatakbo ng noisy simulation gamit ang isang noise model​

Ang command na AerSimulator(noise_model=noise_model) ay nagbabalik ng simulator na naka-configure sa ibinigay na noise model. Bukod sa pag-set ng noise model ng simulator, ino-override din nito ang mga basis gate ng simulator, ayon sa mga gate ng noise model.

Mga halimbawa ng noise model​

Magbibigay tayo ngayon ng ilang halimbawa ng mga noise model. Para sa aming mga demonstrasyon, gumagamit tayo ng simpleng test Circuit na gumagawa ng n-Qubit GHZ state:

# System Specification
n_qubits = 4
circ = QuantumCircuit(n_qubits)

# Test Circuit
circ.h(0)
for qubit in range(n_qubits - 1):
circ.cx(qubit, qubit + 1)
circ.measure_all()
print(circ)
β”Œβ”€β”€β”€β”                β–‘ β”Œβ”€β”
q_0: ─ H β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–‘β”€β”€Mβ”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β” β–‘ β””β•₯β”˜β”Œβ”€β”
q_1: ────── X β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β–‘β”€β”€β•«β”€β”€Mβ”œβ”€β”€β”€β”€β”€β”€
β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β” β–‘ β•‘ β””β•₯β”˜β”Œβ”€β”
q_2: ─────────── X β”œβ”€β”€β– β”€β”€β”€β–‘β”€β”€β•«β”€β”€β•«β”€β”€Mβ”œβ”€β”€β”€
β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β” β–‘ β•‘ β•‘ β””β•₯β”˜β”Œβ”€β”
q_3: ──────────────── X β”œβ”€β–‘β”€β”€β•«β”€β”€β•«β”€β”€β•«β”€β”€Mβ”œ
β””β”€β”€β”€β”˜ β–‘ β•‘ β•‘ β•‘ β””β•₯β”˜
meas: 4/════════════════════════╩══╩══╩══╩═
0 1 2 3

Ideal na simulation​

# Ideal simulator and execution
sim_ideal = AerSimulator()
result_ideal = sim_ideal.run(circ).result()
plot_histogram(result_ideal.get_counts(0))

Output of the previous code cell

Halimbawa ng noise 1: Basic bit-flip error noise model​

Isaalang-alang natin ang isang simpleng halimbawa ng toy noise model na karaniwan sa pananaliksik sa quantum information theory:

  • Kapag nag-apply ng single-qubit gate, i-flip ang estado ng Qubit na may probabilidad na p_gate1.
  • Kapag nag-apply ng two-qubit gate, mag-apply ng single-qubit errors sa bawat Qubit.
  • Kapag nag-reset ng isang Qubit, mag-reset sa 1 sa halip na 0 na may probabilidad na p_reset.
  • Kapag sinusukat ang isang Qubit, i-flip ang estado ng Qubit na may probabilidad na p_meas.
# Example error probabilities
p_reset = 0.03
p_meas = 0.1
p_gate1 = 0.05

# QuantumError objects
error_reset = pauli_error([("X", p_reset), ("I", 1 - p_reset)])
error_meas = pauli_error([("X", p_meas), ("I", 1 - p_meas)])
error_gate1 = pauli_error([("X", p_gate1), ("I", 1 - p_gate1)])
error_gate2 = error_gate1.tensor(error_gate1)

# Add errors to noise model
noise_bit_flip = NoiseModel()
noise_bit_flip.add_all_qubit_quantum_error(error_reset, "reset")
noise_bit_flip.add_all_qubit_quantum_error(error_meas, "measure")
noise_bit_flip.add_all_qubit_quantum_error(error_gate1, ["u1", "u2", "u3"])
noise_bit_flip.add_all_qubit_quantum_error(error_gate2, ["cx"])

print(noise_bit_flip)
NoiseModel:
Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']
Instructions with noise: ['u3', 'u2', 'measure', 'cx', 'reset', 'u1']
All-qubits errors: ['reset', 'measure', 'u1', 'u2', 'u3', 'cx']

Patakbuhin ang noisy simulation​

# Create noisy simulator backend
sim_noise = AerSimulator(noise_model=noise_bit_flip)

# Transpile circuit for noisy basis gates
passmanager = generate_preset_pass_manager(
optimization_level=3, backend=sim_noise
)
circ_tnoise = passmanager.run(circ)

# Run and get counts
result_bit_flip = sim_noise.run(circ_tnoise).result()
counts_bit_flip = result_bit_flip.get_counts(0)

# Plot noisy output
plot_histogram(counts_bit_flip)

Output of the previous code cell

Halimbawa 2: T1/T2 thermal relaxation​

Isaalang-alang naman natin ang isang mas makatotohanang error model batay sa thermal relaxation kasama ang kapaligiran ng Qubit:

  • Ang bawat Qubit ay may mga parameter na thermal relaxation time constant na T1T_1 at dephasing time constant na T2T_2.
  • Pansinin na kailangan nating magkaroon ng T2≀2T1T_2 \le 2 T_1.
  • Ang mga error rate sa mga instruction ay tinutukoy ng mga oras ng gate at mga halaga ng T1T_1, T2T_2 ng Qubit.
# T1 and T2 values for qubits 0-3
T1s = np.random.normal(
50e3, 10e3, 4
) # Sampled from normal distribution mean 50 microsec
T2s = np.random.normal(
70e3, 10e3, 4
) # Sampled from normal distribution mean 50 microsec

# Truncate random T2s <= T1s
T2s = np.array([min(T2s[j], 2 * T1s[j]) for j in range(4)])

# Instruction times (in nanoseconds)
time_u1 = 0 # virtual gate
time_u2 = 50 # (single X90 pulse)
time_u3 = 100 # (two X90 pulses)
time_cx = 300
time_reset = 1000 # 1 microsecond
time_measure = 1000 # 1 microsecond

# QuantumError objects
errors_reset = [
thermal_relaxation_error(t1, t2, time_reset) for t1, t2 in zip(T1s, T2s)
]
errors_measure = [
thermal_relaxation_error(t1, t2, time_measure) for t1, t2 in zip(T1s, T2s)
]
errors_u1 = [
thermal_relaxation_error(t1, t2, time_u1) for t1, t2 in zip(T1s, T2s)
]
errors_u2 = [
thermal_relaxation_error(t1, t2, time_u2) for t1, t2 in zip(T1s, T2s)
]
errors_u3 = [
thermal_relaxation_error(t1, t2, time_u3) for t1, t2 in zip(T1s, T2s)
]
errors_cx = [
[
thermal_relaxation_error(t1a, t2a, time_cx).expand(
thermal_relaxation_error(t1b, t2b, time_cx)
)
for t1a, t2a in zip(T1s, T2s)
]
for t1b, t2b in zip(T1s, T2s)
]

# Add errors to noise model
noise_thermal = NoiseModel()
for j in range(4):
noise_thermal.add_quantum_error(errors_reset[j], "reset", [j])
noise_thermal.add_quantum_error(errors_measure[j], "measure", [j])
noise_thermal.add_quantum_error(errors_u1[j], "u1", [j])
noise_thermal.add_quantum_error(errors_u2[j], "u2", [j])
noise_thermal.add_quantum_error(errors_u3[j], "u3", [j])
for k in range(4):
noise_thermal.add_quantum_error(errors_cx[j][k], "cx", [j, k])

print(noise_thermal)
NoiseModel:
Basis gates: ['cx', 'id', 'rz', 'sx', 'u2', 'u3']
Instructions with noise: ['u3', 'u2', 'measure', 'cx', 'reset']
Qubits with noise: [0, 1, 2, 3]
Specific qubit errors: [('reset', (0,)), ('reset', (1,)), ('reset', (2,)), ('reset', (3,)), ('measure', (0,)), ('measure', (1,)), ('measure', (2,)), ('measure', (3,)), ('u2', (0,)), ('u2', (1,)), ('u2', (2,)), ('u2', (3,)), ('u3', (0,)), ('u3', (1,)), ('u3', (2,)), ('u3', (3,)), ('cx', (0, 0)), ('cx', (0, 1)), ('cx', (0, 2)), ('cx', (0, 3)), ('cx', (1, 0)), ('cx', (1, 1)), ('cx', (1, 2)), ('cx', (1, 3)), ('cx', (2, 0)), ('cx', (2, 1)), ('cx', (2, 2)), ('cx', (2, 3)), ('cx', (3, 0)), ('cx', (3, 1)), ('cx', (3, 2)), ('cx', (3, 3))]

Patakbuhin ang noisy simulation​

# Run the noisy simulation
sim_thermal = AerSimulator(noise_model=noise_thermal)

# Transpile circuit for noisy basis gates
passmanager = generate_preset_pass_manager(
optimization_level=3, backend=sim_thermal
)
circ_tthermal = passmanager.run(circ)

# Run and get counts
result_thermal = sim_thermal.run(circ_tthermal).result()
counts_thermal = result_thermal.get_counts(0)

# Plot noisy output
plot_histogram(counts_thermal)

Output of the previous code cell

Mga susunod na hakbang​

Recommendations