Paano bigyang-kahulugan ang mga visualization ng shaded lightcone
Nagbibigay ang package ng dalawang paraan para tingnan ang isang shaded lightcone:
-
Ino-overlay ng
draw_shaded_lightconeang mga bound sa circuit diagram. Pinakamainam ito para sa mga circuit sa 1D chain ng mga qubit, kung saan magkatugma ang circuit diagram at ang pisikal na layout. -
Piniprojek ng
animate_shaded_lightconeang mga bound sa coupling map ng QPU at hinahakbang ang circuit layer por layer. Pinakamainam ito kapag ang qubit connectivity ay higit sa isang 1D na linya, kung saan ang circuit diagram ay hindi na naghahatid kung aling mga qubit ang magkapitbahay.
Ipinapakita ng parehong visualization ang parehong pinagbabatayang mga numero. Tinatalakay ng gabay na ito kung ano ang ibig sabihin ng mga numerong iyon, at ipinapaliwanag ang mga detalyeng madaling mabasa nang mali.
Pag-setup
Gamitin ang parehong Trotterized Ising circuit at observable gaya ng quickstart guide.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_addon_slc": "qiskit-addon-slc", "samplomatic": "samplomatic"}
_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 Pauli, PauliLindbladMap, QubitSparsePauliList
from qiskit_addon_slc.bounds import (
compute_backward_bounds,
compute_forward_bounds,
merge_bounds,
)
from qiskit_addon_slc.utils import generate_noise_model_paulis
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions
def trotter_ising_circuit(num_qubits, num_steps, rx_angle, rzz_angle):
"""Trotterized transverse-field Ising evolution on a 1D chain."""
circuit = QuantumCircuit(num_qubits)
for _ in range(num_steps):
circuit.rx(rx_angle, range(num_qubits))
circuit.barrier()
for start in (0, 1): # even then odd bonds
for i in range(start, num_qubits - 1, 2):
circuit.rzz(rzz_angle, i, i + 1)
circuit.barrier()
return circuit
num_qubits = 10
circuit = trotter_ising_circuit(
num_qubits, num_steps=4, rx_angle=np.pi / 16, rzz_angle=-np.pi / 3
)
observable = Pauli("I" * num_qubits).compose("Z", [num_qubits // 2])
boxing_pass = generate_boxing_pass_manager(
inject_noise_targets="all",
inject_noise_strategy="individual_modification",
inject_noise_site="after",
twirling_strategy="active",
remove_barriers="never",
)
boxed_circuit = boxing_pass.run(circuit)
noise_model_paulis = generate_noise_model_paulis(
find_unique_box_instructions(boxed_circuit)
)
forward_bounds = compute_forward_bounds(
boxed_circuit, noise_model_paulis, observable
)
backward_bounds = compute_backward_bounds(boxed_circuit, noise_model_paulis)
rng = np.random.default_rng(42)
noise_rates = {
layer: PauliLindbladMap.from_components(
rng.random(len(terms)) * 5e-3,
QubitSparsePauliList.from_sparse_list(
terms.to_sparse_list(), terms.num_qubits
),
)
for layer, terms in noise_model_paulis.items()
}
merged_bounds = merge_bounds(
boxed_circuit, forward_bounds, backward_bounds, noise_rates
)
print(f"observable: Z on qubit {num_qubits // 2}")
Optimal spacetime partitioning not implemented! Just partitioning list of noisy boxes.
observable: Z on qubit 5
draw_shaded_lightcone
Bawat maingay na box ay may shade ayon sa bound sa mga error na nangyayari roon: ang maliwanag ay nangangahulugang malaking bound, at ang box na naglalaho sa background ay nangangahulugang kaunti ang epekto ng mga error nito sa observable. Ang mga naglahong box na iyon ang mga kandidato para alisin sa mitigated na noise model.
from qiskit_addon_slc.visualization import draw_shaded_lightcone
draw_shaded_lightcone(
boxed_circuit, merged_bounds, noise_model_paulis, fold=-1, scale=0.5
)

Mahahalagang tala
1. Ang bawat numero ay kabuuan ng mga error term na may iisang support. Kapag walang filter, ang mga bound ng
bawat error term na kumikilos sa iisang qubit, o sa iisang pares ng mga qubit, ay idinaragdag sa isang halaga:
lahat ng tatlong uri ng Pauli sa isang qubit, at lahat ng siyam sa isang pares. May dalawang kahihinatnan ito. Ang isang halaga ay maaaring
lumampas sa 2.0, kahit walang bound ng iisang term na makakagawa nito (ang box na may label na 4.5 ay ilang term na nagsasama,
hindi nilabag na bound). Hindi masasabi ng figure kung ang malaking halaga ay mula sa isang uri
ng Pauli o mula sa ilang magkakatulad; ipinapakita ng susunod na seksyon kung paano paghiwalayin ang mga ito.
2. Nagsisimula ang color scale sa 2.0 at lumalaki ayon sa data. Tumatakbo ang scale mula 0 hanggang sa
entry na "max_bound" ng metadata ng na-overlay na circuit, na siyang mas malaki sa 2.0 at sa pinakamalaking
halagang ipinapakita. Ang mga unfiltered na kabuuan ay madalas lumampas sa 2.0, kaya ini-stretch ang scale para magkasya ang mga ito, at ang parehong
kulay ay maaaring kumatawan sa magkakaibang halaga sa magkakaibang figure. Kapag maliit ang bawat halaga, nananatili ang
scale sa 2.0 at lahat ay mukhang pare-parehong madilim (iyon ay ang scale na sumasalamin sa absolute na
laki, hindi pagkakamali sa rendering).
Paghihiwalay ng mga uri ng Pauli
Gamitin ang pauli_filter para makita ang isang uri sa bawat pagkakataon. Ang integer ay pumipili ng Pauli weight; ang string ay pumipili ng
isang tiyak na Pauli, na itinutugma sa bawat noise term na binawasan sa sarili nitong non-identity support. Kaya
ang "X" ay pumipili ng bawat single-qubit na error, kahit aling qubit ang kinikilusan nito, at ang "XX" ay pumipili sa
mga weight-2 (ang full-width na label gaya ng "XII" ay walang tinutugma).
from qiskit_addon_slc.visualization import accumulate_filtered_bounds
box_id = next(iter(merged_bounds))
print(f"single-qubit supports of box {box_id!r}:\n")
print(f"{'filter':>8} bounds per qubit")
for pauli_filter in (None, 1, "X", "Y", "Z"):
filtered = accumulate_filtered_bounds(
boxed_circuit, merged_bounds, noise_model_paulis, pauli_filter
)
per_qubit = {
support[0]: round(float(bound), 3)
for support, bound in sorted(filtered[box_id].items())
if len(support) == 1
}
print(f"{pauli_filter!s:>8} {per_qubit}")
single-qubit supports of box 'm0':
filter bounds per qubit
None {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.312, 4: 1.355, 5: 5.111, 6: 1.506, 7: 0.124, 8: 0.019, 9: 0.0}
1 {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.312, 4: 1.355, 5: 5.111, 6: 1.506, 7: 0.124, 8: 0.019, 9: 0.0}
X {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.153, 4: 0.577, 5: 2.0, 6: 0.702, 7: 0.056, 8: 0.01, 9: 0.0}
Y {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.148, 4: 0.607, 5: 2.0, 6: 0.631, 7: 0.057, 8: 0.01, 9: 0.0}
Z {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.011, 4: 0.172, 5: 1.111, 6: 0.172, 7: 0.011, 8: 0.0, 9: 0.0}
Ang unfiltered na hilera ay kabuuan ng tatlong uri ng Pauli sa ilalim nito. Ang pag-filter ang tanging paraan para malaman kung ang malaking unfiltered na halaga ay mula sa isang nangingibabaw na uri ng error o mula sa ilang magkakatulad. Mahalaga iyon, dahil ang mitigation ay kumikilos kada term, hindi kada site.
Ang pagpasa ng parehong filter sa draw_shaded_lightcone ay nagtatala nito sa pamagat ng figure, kaya ang naka-filter
na figure ay hindi mapagkakamalang unfiltered:
draw_shaded_lightcone(
boxed_circuit,
merged_bounds,
noise_model_paulis,
pauli_filter="X",
fold=-1,
scale=0.5,
)

Ibang-iba ang hitsura ng figure na ito sa unfiltered sa itaas, at hindi lang dahil mas kaunti ang ipinapakita nitong
halaga. Bawat placeholder sa mga figure na ito ay kumakatawan sa isang support: isang qubit, o isang pares ng
mga qubit. Kapag walang filter, ang isang box ay nagpapakita ng placeholder sa bawat qubit at sa bawat pares ng magkatabing
mga qubit, kaya kumakalat ito sa ilang column. Sa "X", ang mga single-qubit na support na lang ang natitira, at
ang bawat box ay lumiliit sa isang column.
Pero wala sa alinmang larawan ang aktwal na inilalapat ng PEC. Ang mga placeholder ay paraan lang para ipakita ang mga bound, hindi mga anti-noise gate. Sa panahon ng eksperimento, ang bawat box na may mga error term na minimitigate ay tinatrato bilang isang layer ng two-qubit gate, at ang mga anti-noise Pauli na na-sample para sa mga error term nito ay pinagsasama-sama sa isang Pauli na inilalapat sa buong layer na iyon.
animate_shaded_lightcone
Sa isang device na ang connectivity ay hindi 1D na linya, hindi na ipinapakita ng circuit diagram kung aling mga qubit ang
magkatabi, kaya imposibleng mabasa ang spatial na pagkalat ng lightcone.
Ang animate_shaded_lightcone ay iginuguhit na lang ang coupling map ng QPU at ina-animate ang mga bound dito,
isang noisy box kada frame.
Kailangan nito ng CouplingMap, na inilalatag nito sa isang grid sa pamamagitan ng pag-embed ng graph ng device, kaya kaya nitong hawakan ang parehong
heavy-hex at square na connectivity.
Tandaan: Sa na-render na dokumentasyong ito, static ang animation. Gumagana lang ang slider at play button kapag interactive na tumatakbo ang notebook, halimbawa sa Jupyter.
from qiskit import transpile
from qiskit.transpiler import CouplingMap
from qiskit_addon_slc.visualization import animate_shaded_lightcone
# A small square-lattice device stands in for a real backend here.
coupling_map = CouplingMap.from_grid(3, 4)
# Lay the chain onto a connected path of physical qubits, snaking through the grid, so the
# transpiler inserts no SWAPs: a SWAP-laden circuit is far more expensive to bound and harder to
# read.
initial_layout = [0, 1, 2, 3, 7, 6, 5, 4, 8, 9]
device_circuit = transpile(
circuit,
coupling_map=coupling_map,
initial_layout=initial_layout,
optimization_level=0,
)
boxed_device_circuit = boxing_pass.run(device_circuit)
device_noise_paulis = generate_noise_model_paulis(
find_unique_box_instructions(boxed_device_circuit),
coupling_map=coupling_map,
circuit=boxed_device_circuit,
)
# The same observable, on the physical qubit the middle of the chain was laid onto.
device_observable = Pauli("I" * device_circuit.num_qubits).compose(
"Z", [initial_layout[num_qubits // 2]]
)
device_bounds = compute_forward_bounds(
boxed_device_circuit, device_noise_paulis, device_observable
)
animate_shaded_lightcone(boxed_device_circuit, device_bounds, coupling_map)

Pagbasa sa animation
Ang bawat qubit ay isang pie chart, isang slice para sa bawat uri ng Pauli. Ang marker ng isang qubit ay hinahati sa tatlong
slice para sa mga error nitong , at , na bawat isa ay may sariling shade ayon sa bound nito. Ito ang pag-filter mula sa
nakaraang seksyon na nakapaloob na sa figure (hindi na kailangan ng pauli_filter para paghiwalayin ang mga uri).
Dala ng mga edge ang mga two-qubit error bound. Ang linya sa pagitan ng dalawang magkakabit na qubit ay may shade ayon sa bound sa mga weight-2 error na tumatama sa pares na iyon.
Ang light gray ay nangangahulugang walang data, hindi maliit na bound. Ang isang slice o edge ay iginuguhit na light gray kapag
walang error term para dito ang noise model ng box, halimbawa sa mga qubit na hindi ginagalaw ng box. Iginuguhit itong
gray sa halip na madilim para hindi ito mapagkamalang bound na zero. Iba ang mga box na lampas sa limitasyong
max_num_boxes: dala nila ang trivial na bound na 2.0, kaya iginuguhit sila sa
maliwanag na dulo ng scale.
Hakbang-hakbang ang slider sa mga box, hindi pantay na sa oras. May isang frame kada noisy box, ayon sa
ayos ng circuit (o pabaliktad gamit ang reverse=True, na sinusundan ang lightcone pabalik mula sa
observable). Kadalasang mas madaling maunawaan ang panonood nito nang pabaliktad: lumalaki ang cone
paitaas mula sa mga qubit na sinukat. Ang bawat frame ay may label na identifier ng box nito, ang parehong key
kung saan itinatago ng bounds dictionary ang box na iyon, kaya magagamit din ang slider para tumalon sa
isang partikular na box at hanapin ang mga numero nito.
Tandaan: Ang layout ng mga qubit ay nakukuha mula sa graph ng coupling map sa pamamagitan ng pag-embed nito sa isang square
lattice. Ang coupling map na hindi ma-embed (dahil disconnected ito, o masyadong siksik ang koneksyon
para sa isang grid) ay magtataas ng ValueError sa halip na gumuhit ng nakaliligaw na larawan.
Alin ang gagamitin
draw_shaded_lightcone | animate_shaded_lightcone | |
|---|---|---|
| geometry | ang circuit diagram | ang coupling map ng QPU |
| pinakamainam para sa | mga 1D chain | anumang connectivity |
| Mga uri ng Pauli | pinagsama, maliban kung na-filter | laging hiwalay, bilang mga pie slice |
| oras | lahat ng layer nang sabay | isang layer kada frame |
| output | isang matplotlib figure | isang plotly figure |
Para sa 1D chain, mas madaling makuha sa isang sulyap ang static na figure at maaaring i-reproduce sa isang paper. Lampas sa 1D, ang animation lang sa dalawa ang nagpapakita nang tapat ng spatial na istruktura.