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?

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_lightcone ang 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_lightcone ang 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
)

Output of the previous code cell

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 XX 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,
)

Output of the previous code cell

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)

Output of the previous code cell

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 XX, YY at ZZ, 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_lightconeanimate_shaded_lightcone
geometryang circuit diagramang coupling map ng QPU
pinakamainam para samga 1D chainanumang connectivity
Mga uri ng Paulipinagsama, maliban kung na-filterlaging hiwalay, bilang mga pie slice
oraslahat ng layer nang sabayisang layer kada frame
outputisang matplotlib figureisang 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.