Mag-benchmark ng dynamic circuits gamit ang cut Bell pairs
Tantiya sa paggamit: 22 segundo sa isang Heron r2 processor (TANDAAN: Ito ay tantiya lamang. Maaaring mag-iba ang inyong runtime.)
Konteksto​
Ang quantum hardware ay karaniwang limitado sa lokal na mga interaksyon, ngunit maraming algorithm ang nangangailangan ng pag-entangle sa mga malayong qubit o maging mga qubit sa magkahiwalay na processors. Ang mga dynamic circuit - ibig sabihin, mga circuit na may mid-circuit measurement at feedforward - ay nagbibigay ng paraan upang malampasan ang mga limitasyong ito sa pamamagitan ng paggamit ng real-time classical communication upang epektibong ipatupad ang mga non-local quantum operations. Sa diskarteng ito, ang mga resulta ng measurement mula sa isang bahagi ng circuit (o isang QPU) ay maaaring kondisyonal na mag-trigger ng mga gate sa iba, na nagpapahintulot sa atin na i-teleport ang entanglement sa mahabang distansya. Ito ang nagbubuo ng batayan ng local operations and classical communication (LOCC) schemes, kung saan kumokonsumo tayo ng mga entangled resource states (Bell pairs) at nakikipag-communicate ng mga resulta ng measurement sa pamamagitan ng classical upang ikonekta ang mga malayong qubit.
Ang isang promising na gamit ng LOCC ay upang irealize ang mga virtual long-range CNOT gates sa pamamagitan ng teleportation, gaya ng ipinapakita sa long-range entanglement tutorial. Sa halip na direktang long-range CNOT (na maaaring hindi pahintulutan ng hardware connectivity), lumilikha tayo ng mga Bell pair at gumagawa ng teleportation-based gate implementation. Gayunpaman, ang fidelity ng mga ganitong operasyon ay nakadepende sa mga katangian ng hardware. Ang qubit decoherence sa panahon ng kinakailangang pagkaantala (habang naghihintay ng mga resulta ng measurement) at ang classical communication latency ay maaaring magpababa ng entangled state. Gayundin, ang mga error sa mid-circuit measurements ay mas mahirap itama kaysa sa mga error sa final measurements dahil kumakalat ang mga ito sa natitirang bahagi ng circuit sa pamamagitan ng mga conditional gates.
Sa reference experiment, ipinakilala ng mga may-akda ang isang Bell pair fidelity benchmark upang kilalanin kung aling mga bahagi ng device ang pinakaangkop para sa LOCC-based entanglement. Ang ideya ay magpatakbo ng isang maliit na dynamic circuit sa bawat grupo ng apat na konektadong qubit sa processor. Ang apat na qubit na circuit na ito ay unang lumilikha ng Bell pair sa dalawang gitnang qubit, pagkatapos ay ginagamit ang mga iyon bilang resource upang i-entangle ang dalawang edge qubit sa pamamagitan ng paggamit ng LOCC. Konkretong, ang mga qubit 1 at 2 ay inihahanda sa isang uncut Bell pair nang lokal (gamit ang Hadamard at CNOT), at pagkatapos ay ang isang teleportation routine ay kumokonsumo ng Bell pair na iyon upang i-entangle ang mga qubit 0 at 3. Ang mga qubit 1 at 2 ay sinusukat sa panahon ng pagpapatupad ng circuit, at batay sa mga resulta, ang mga Pauli corrections (isang X sa qubit 3 at Z sa qubit 0) ay inilalapat. Ang mga qubit 0 at 3 ay naiiwan sa isang Bell state sa katapusan ng circuit.
Upang sukatin ang kalidad ng panghuling entangled pair na ito, sinusukat natin ang mga stabilizers nito: partikular, ang parity sa basis () at sa basis (). Para sa perpektong Bell pair, ang parehong mga expectation na ito ay katumbas ng +1. Sa praktika, ang ingay ng hardware ay magpapababa ng mga halagang ito. Kaya inuulit natin ang circuit nang dalawang beses para sa bawat qubit-pair: isang circuit ay sumusukat sa mga qubit 0 at 3 sa basis, at ang isa ay sumusukat sa mga ito sa basis. Mula sa mga resulta, nakakakuha tayo ng tantiya ng at para sa pair ng qubit na iyon. Ginagamit natin ang mean squared error (MSE) ng mga stabilizers na ito na may kaugnayan sa ideal na halaga (1) bilang simpleng sukatan ng entanglement fidelity. Ang mas mababang MSE ay nangangahulugang ang dalawang qubit ay nakamit ang Bell state na mas malapit sa ideal (mas mataas na fidelity), samantalang ang mas mataas na MSE ay nagpapahiwatig ng mas maraming error. Sa pamamagitan ng pag-scan ng eksperimentong ito sa buong device, maaari nating i-benchmark ang measurement-and-feedforward capability ng iba't ibang grupo ng qubit at kilalanin ang pinakamahusay na mga pair ng qubit para sa mga operasyong LOCC.
Ipinakikita ng tutorial na ito ang eksperimento sa isang IBM Quantum® device upang ilarawan kung paano magagamit ang mga dynamic circuit upang makabuo at masuri ang entanglement sa pagitan ng mga malayong qubit. Magsasagawa tayo ng mapping ng lahat ng apat na qubit na linear chains sa device, magpapatakbo ng teleportation circuit sa bawat isa, at pagkatapos ay ipa-visualize ang distribusyon ng mga halaga ng MSE. Ang end-to-end na prosesong ito ay nagpapakita kung paano gamitin ang Qiskit Runtime at mga dynamic circuit features upang magbigay ng impormasyon sa mga pagpiling hardware-aware para sa pagputol ng mga circuit o pag-distribute ng mga quantum algorithm sa isang modular system.
Mga Kinakailangan​
Bago magsimula ng tutorial na ito, siguraduhin na mayroon kayong sumusunod na naka-install:
- Qiskit SDK v2.0 o mas bago, na may visualization support
- Qiskit Runtime v0.40 o mas bago (
pip install qiskit-ibm-runtime)
Pag-setup​
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-runtime
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler
from qiskit.transpiler import generate_preset_pass_manager
import numpy as np
import matplotlib.pyplot as plt
def create_bell_stab(initial_layouts):
"""
Create a circuit for a 1D chain of qubits (number of qubits must be a multiple of 4),
where a middle Bell pair is consumed to create a Bell at the edge.
Takes as input a list of lists, where each element of the list is a
1D chain of physical qubits that is used as the initial_layout for the transpiled circuit.
Returns a list of length-2 tuples, each tuple contains a circuit to measure the ZZ stabilizer and
a circuit to measure the XX stabilizer of the edge Bell state.
"""
bell_circuits = []
for (
initial_layout
) in initial_layouts: # Iterate over chains of physical qubits
assert (
len(initial_layout) % 4 == 0
), f"The length of the chain must be a multiple of 4, len(inital_layout)={len(initial_layout)}"
num_pairs = len(initial_layout) // 4
bell_parallel = QuantumCircuit(4 * num_pairs, 4 * num_pairs)
for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
(c0, c1) = pair_idx * 4, pair_idx * 4 + 3 # edge qubits
(ca0, ca1) = pair_idx * 4 + 1, pair_idx * 4 + 2 # middle qubits
bell_parallel.h(q0)
bell_parallel.h(q1)
bell_parallel.cx(q1, q2)
bell_parallel.cx(q0, q1)
bell_parallel.cx(q2, q3)
bell_parallel.h(q2)
# add barrier BEFORE measurements and add id in conditional
bell_parallel.barrier()
for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
(ca0, ca1) = pair_idx * 4 + 1, pair_idx * 4 + 2 # middle qubits
bell_parallel.measure(q1, ca0)
bell_parallel.measure(q2, ca1)
# bell_parallel.barrier() #remove barrier after measurement
for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
(ca0, ca1) = pair_idx * 4 + 1, pair_idx * 4 + 2 # middle qubits
with bell_parallel.if_test((ca0, 1)):
bell_parallel.x(q3)
with bell_parallel.if_test((ca1, 1)):
bell_parallel.z(q0)
bell_parallel.id(q0) # add id here for correct alignment
bell_zz = bell_parallel.copy()
bell_zz.barrier()
bell_xx = bell_parallel.copy()
bell_xx.barrier()
for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
bell_xx.h(q0)
bell_xx.h(q3)
bell_xx.barrier()
for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
(c0, c1) = pair_idx * 4, pair_idx * 4 + 3 # edge qubits
bell_zz.measure(q0, c0)
bell_zz.measure(q3, c1)
bell_xx.measure(q0, c0)
bell_xx.measure(q3, c1)
bell_circuits.append(bell_zz)
bell_circuits.append(bell_xx)
return bell_circuits
def get_mse(result, initial_layouts):
"""
given a result object and the initial layouts, returns a dict of layouts and their mse
"""
layout_mse = {}
for layout_idx, initial_layout in enumerate(initial_layouts):
layout_mse[tuple(initial_layout)] = {}
num_pairs = len(initial_layout) // 4
counts_zz = result[2 * layout_idx].data.c.get_counts()
total_shots = sum(counts_zz.values())
# Get ZZ expectation value
exp_zz_list = []
for pair_idx in range(num_pairs):
exp_zz = 0
for bitstr, shots in counts_zz.items():
bitstr = bitstr[::-1] # reverse order to big endian
b1, b0 = (
bitstr[pair_idx * 4],
bitstr[pair_idx * 4 + 3],
) # parse bitstring to get edge measurements for each 4-q chain
z_val0 = 1 if b0 == "0" else -1
z_val1 = 1 if b1 == "0" else -1
exp_zz += z_val0 * z_val1 * shots
exp_zz /= total_shots
exp_zz_list.append(exp_zz)
counts_xx = result[2 * layout_idx + 1].data.c.get_counts()
total_shots = sum(counts_xx.values())
# Get XX expectation value
exp_xx_list = []
for pair_idx in range(num_pairs):
exp_xx = 0
for bitstr, shots in counts_xx.items():
bitstr = bitstr[::-1] # reverse order to big endian
b1, b0 = (
bitstr[pair_idx * 4],
bitstr[pair_idx * 4 + 3],
) # parse bitstring to get edge measurements for each 4-q chain
x_val0 = 1 if b0 == "0" else -1
x_val1 = 1 if b1 == "0" else -1
exp_xx += x_val0 * x_val1 * shots
exp_xx /= total_shots
exp_xx_list.append(exp_xx)
mse_list = [
((exp_zz - 1) ** 2 + (exp_xx - 1) ** 2) / 2
for exp_zz, exp_xx in zip(exp_zz_list, exp_xx_list)
]
print(f"layout {initial_layout}")
for idx in range(num_pairs):
layout_mse[tuple(initial_layout)][
tuple(initial_layout[4 * idx : 4 * idx + 4])
] = mse_list[idx]
print(
f"qubits: {initial_layout[4*idx:4*idx+4]}, mse:, {round(mse_list[idx],4)}"
)
# print(f'exp_zz: {round(exp_zz_list[idx],4)}, exp_xx: {round(exp_xx_list[idx],4)}')
print(" ")
return layout_mse
def plot_mse_ecdfs(layouts_mse, combine_layouts=False):
"""
Plot CDF of MSE data for multiple layouts. Optionally combine all data in a single CDF
"""
if not combine_layouts:
for initial_layout, layouts in layouts_mse.items():
sorted_layouts = dict(
sorted(layouts.items(), key=lambda item: item[1])
) # sort layouts by mse
# get layouts and mses
layout_list = list(sorted_layouts.keys())
mse_list = np.asarray(list(sorted_layouts.values()))
# convert to numpy
x = np.array(mse_list)
y = np.arange(1, len(x) + 1) / len(x)
# Prepend (x[0], 0) to start CDF at zero
x = np.insert(x, 0, x[0])
y = np.insert(y, 0, 0)
# Create the plot
plt.plot(
x,
y,
marker="x",
linestyle="-",
label=f"qubits: {initial_layout}",
)
# add qubits labels for the edge pairs
for xi, yi, q in zip(x[1:], y[1:], layout_list):
plt.annotate(
[q[0], q[3]],
(xi, yi),
textcoords="offset points",
xytext=(5, -10),
ha="left",
fontsize=8,
)
elif combine_layouts:
all_layouts = {}
all_initial_layout = []
for (
initial_layout,
layouts,
) in layouts_mse.items(): # puts together all layout information
all_layouts.update(layouts)
all_initial_layout += initial_layout
sorted_layouts = dict(
sorted(all_layouts.items(), key=lambda item: item[1])
) # sort layouts by mse
# get layouts and mses
layout_list = list(sorted_layouts.keys())
mse_list = np.asarray(list(sorted_layouts.values()))
# convert to numpy
x = np.array(mse_list)
y = np.arange(1, len(x) + 1) / len(x)
# Prepend (x[0], 0) to start CDF at zero
x = np.insert(x, 0, x[0])
y = np.insert(y, 0, 0)
# Create the plot
plt.plot(
x,
y,
marker="x",
linestyle="-",
label=f"qubits: {sorted(list(set(all_initial_layout)))}",
)
# add qubit labels for the edge pairs
for xi, yi, q in zip(x[1:], y[1:], layout_list):
plt.annotate(
[q[0], q[3]],
(xi, yi),
textcoords="offset points",
xytext=(5, -10),
ha="left",
fontsize=8,
)
plt.xscale("log")
plt.xlabel("Mean squared error of ⟨ZZ⟩ and ⟨XX⟩")
plt.ylabel("Cumulative distribution function")
plt.title("CDF for different initial layouts")
plt.grid(alpha=0.3)
plt.show()
Hakbang 1: I-map ang classical inputs sa quantum problem​
Ang unang hakbang ay ang paglikha ng isang set ng mga quantum circuit upang i-benchmark ang lahat ng kandidatong Bell-pair links na inangkop sa topology ng device. Programmatically naming hinahanap ang device coupling map para sa lahat ng linearly-connected chains ng apat na qubit. Ang bawat ganitong chain (na naka-label ng mga qubit indices ) ay nagsisilbing test case para sa entanglement-swapping circuit. Sa pamamagitan ng pagtukoy ng lahat ng posibleng length-4 paths, sinisiguro natin ang maximum coverage para sa posibleng pagpangkat ng mga qubit na maaaring magrealize ng protocol.
service = QiskitRuntimeService()
backend = service.least_busy(operational=True)
Ginagawa natin ang mga chains na ito sa pamamagitan ng paggamit ng helper function na nagsasagawa ng greedy search sa device graph. Ito ay nagbabalik ng mga "stripes" ng apat na apat-na-qubit chains na nakabalot sa 16-qubit groups (ang mga dynamic circuit ay kasalukuyang naghihigpit sa laki ng measurement register sa 16 qubits). Ang pag-bundle ay nagbibigay-daan sa atin na magpatakbo ng maraming apat-na-qubit experiments nang sabay-sabay sa magkaibang mga bahagi ng chip, at gumawa ng epektibong paggamit ng buong device. Ang bawat 16-qubit stripe ay naglalaman ng apat na disjoint chains, na nangangahulugan na walang qubit na muling ginagamit sa loob ng grupong iyon. Halimbawa, ang isang stripe ay maaaring binubuo ng mga chains , , , at na magkasama. Ang anumang qubit na hindi kasama sa stripe ay ibinalik sa variable na leftover.
from itertools import chain
from collections import defaultdict
def stripes16_from_backend(backend):
"""
Creates stripes of 16 qubits, four non-overlapping four-qubit chains, that cover as much of
the coupling map as possible. Returns any unused qubits as leftovers.
"""
# get the undirected adjacency list
edges = backend.coupling_map.get_edges()
graph = defaultdict(set)
for u, v in edges:
graph[u].add(v)
graph[v].add(u)
qubits = sorted(graph) # all qubit indices that appear
# greedy search for 4-long linear chains (blocks) ────────────
used = set() # qubits already placed in a block
blocks = [] # each block is a four-qubit list
for q in qubits: # deterministic order for reproducibility
if q in used:
continue # already consumed by earlier block
# depth-first "straight" walk of length 3 without revisiting nodes
def extend(path):
if len(path) == 4:
return path
tip = path[-1]
for nbr in sorted(graph[tip]): # deterministic
if nbr not in path and nbr not in used:
maybe = extend(path + [nbr])
if maybe:
return maybe
return None
block = extend([q])
if block: # found a 4-node path
blocks.append(block)
used.update(block)
# bundle four four-qubit blocks into one 16-qubit stripe (max number of measurement compatible with if-else)
stripes = [
list(chain.from_iterable(blocks[i : i + 4]))
for i in range(0, len(blocks) // 4 * 4, 4) # full groups of four
]
leftovers = set(qubits) - set(chain.from_iterable(stripes))
return stripes, leftovers
initial_layouts, leftover = stripes16_from_backend(backend)
Susunod, binubuo natin ang circuit para sa bawat 16-qubit stripe. Ginagawa ng routine ang sumusunod para sa bawat chain:
- Maghanda ng middle Bell pair: Maglapat ng Hadamard sa qubit 1 at isang CNOT mula sa qubit 1 hanggang qubit 2. Ito ay nag-entangle sa mga qubit 1 at 2 (lumilikha ng Bell state).
- I-entangle ang edge qubits: Maglapat ng CNOT mula sa qubit 0 hanggang qubit 1, at isang CNOT mula sa qubit 2 hanggang qubit 3. Ito ay nag-uugnay sa mga paunang hiwalay na pairs upang ang mga qubit 0 at 3 ay maging entangled pagkatapos ng mga susunod na hakbang. Ang isang Hadamard sa qubit 2 ay inilalapat din (ito, na pinagsama sa mga naunang CNOT, ay bumubuo ng bahagi ng Bell measurement sa mga qubit 1 at 2). Sa puntong ito, ang mga qubit 0 at 3 ay hindi pa nag-entangled, ngunit ang mga qubit 1 at 2 ay nag-entangled sa kanila sa isang mas malaking apat-na-qubit state.
- Mid-circuit measurements at feedforward: Ang mga qubit 1 at 2 (ang gitnang mga qubit) ay sinusukat sa computational basis, na nagbubunga ng dalawang classical bits. Batay sa mga resulta ng measurement, naglalapat tayo ng mga conditional operations: kung ang qubit 1 measurement (tawagin nating bit na ito na ) ay 1, naglalapat tayo ng gate sa qubit 3; kung ang qubit 2 measurement () ay 1, naglalapat tayo ng gate sa qubit 0. Ang mga conditional gates na ito (na naisasakatuparan sa pamamagitan ng paggamit ng Qiskit
if_test/if_elseconstruct) ay nagpapatupad ng standard teleportation corrections. Ina-undo nila ang mga random na Pauli flips na nangyayari dahil sa projection ng mga qubit 1 at 2, na sinisiguro na ang mga qubit 0 at 3 ay nagtatapos sa kilalang Bell state, anuman ang mga resulta ng measurement. Pagkatapos ng hakbang na ito, ang mga qubit 0 at 3 ay dapat na idealyang nag-entangled sa Bell state na . - Sukatin ang Bell pair stabilizers: Pagkatapos ay nahahati tayo sa dalawang bersyon ng circuit. Sa unang bersyon, sinusukat natin ang stabilizer sa mga qubit 0 at 3. Sa pangalawang bersyon, sinusukat natin ang stabilizer sa mga qubits na ito.
Para sa bawat apat-na-qubit initial layout, ang function sa itaas ay nagbabalik ng dalawang circuits (isa para sa , isa para sa stabilizer measurement). Sa katapusan ng hakbang na ito, mayroon tayong listahan ng mga circuit na sumasaklaw sa bawat apat-na-qubit chain sa device. Ang mga circuits na ito ay may kasamang mga mid-circuit measurements at conditional (if/else) operations, na siyang mga pangunahing instruksiyon ng dynamic circuit.
circuits = create_bell_stab(initial_layouts)
circuits[-1].draw("mpl", fold=-1)

Hakbang 2: I-optimize ang problema para sa quantum hardware execution​
Bago isagawa ang ating mga circuit sa tunay na hardware, kailangan nating i-transpile ang mga ito upang tumugma sa mga physical constraints ng device. Ang transpilation ay mag-map ng abstract circuit sa mga physical qubits at gate set ng piniling device. Dahil pumili na tayo ng mga tukoy na physical qubits para sa bawat chain (sa pamamagitan ng pagbibigay ng initial_layout sa circuit generator), ginagamit natin ang transpiler optimization_level=0 na may fixed layout na iyon. Sinasabi nito sa Qiskit na huwag muling mag-assign ng mga qubit o magsagawa ng anumang mabibigat na optimizations na maaaring magbago sa istraktura ng circuit. Nais nating panatilihin ang sequence ng mga operasyon (lalo na ang mga conditional gates) eksaktong gaya ng tinukoy.
isa_circuits = []
for ind, init_layout in enumerate(initial_layouts):
pm = generate_preset_pass_manager(
optimization_level=0, backend=backend, initial_layout=init_layout
)
isa_circ = pm.run(circuits[ind * 2 : ind * 2 + 2])
isa_circuits.extend(isa_circ)
isa_circuits[1].draw("mpl", fold=-1, idle_wires=False)

Hakbang 3: Isagawa gamit ang Qiskit primitives​
Maaari na nating patakbuhin ang eksperimento sa quantum device. Ginagamit natin ang Qiskit Runtime at ang Sampler primitive nito upang mabisa na maisagawa ang batch ng mga circuit.
sampler = Sampler(mode=backend)
sampler.options.environment.job_tags = ["cut-bell-pair-test"]
job = sampler.run(isa_circuits)
Hakbang 4: Mag-post-process at ibalik ang resulta sa nais na classical format​
Ang huling hakbang ay kalkulahin ang mean squared error metric (MSE) para sa bawat nasubukang grupo ng qubit at buuin ang mga resulta. Para sa bawat chain, mayroon na tayong sinukat na at . Kung ang mga qubit 0 at 3 ay perpektong nag-entangled sa isang Bell state, inaasahan natin na ang parehong mga ito ay +1. Sinusukat natin ang deviation gamit ang MSE:
Ang halagang ito ay 0 para sa perpektong Bell pair, at tumataas habang ang entangled state ay nagiging mas maingay (sa mga random outcomes na nagbibigay ng expectation na humigit-kumulang 0, ang MSE ay lalapit sa 1). Kinakalkulan ng code ang MSE na ito para sa bawat apat-na-qubit group.
Ang mga resulta ay naglalantad ng malawak na saklaw ng kalidad ng entanglement sa buong device. Kinukumpirma nito ang natuklasan ng papel na maaaring magkaroon ng mahigit isang order of magnitude variation sa Bell-state fidelity depende sa kung aling mga physical qubits ang ginagamit. Sa praktikal na termino, nangangahulugan ito na ang ilang mga rehiyon o link sa chip ay mas mahusay sa paggawa ng mid-circuit measurement at feedforward operations kaysa sa iba. Ang mga salik tulad ng qubit readout error, qubit lifetime, at crosstalk ay malamang na nag-aambag sa mga pagkakaibang ito. Halimbawa, kung ang isang chain ay may kasamang partikular na maingay na readout qubit, ang mid-circuit measurement ay maaaring hindi maaasahan, na humahantong sa mahinang fidelity para sa entangled pair na iyon (mataas na MSE).
layouts_mse = get_mse(job.result(), initial_layouts)
layout [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
qubits: [0, 1, 2, 3], mse:, 0.0312
qubits: [4, 5, 6, 7], mse:, 0.0491
qubits: [8, 9, 10, 11], mse:, 0.0711
qubits: [12, 13, 14, 15], mse:, 0.0436
layout [16, 23, 22, 21, 17, 27, 26, 25, 18, 31, 30, 29, 19, 35, 34, 33]
qubits: [16, 23, 22, 21], mse:, 0.0197
qubits: [17, 27, 26, 25], mse:, 0.113
qubits: [18, 31, 30, 29], mse:, 0.0287
qubits: [19, 35, 34, 33], mse:, 0.0433
layout [36, 41, 42, 43, 37, 45, 46, 47, 38, 49, 50, 51, 39, 53, 54, 55]
qubits: [36, 41, 42, 43], mse:, 0.1645
qubits: [37, 45, 46, 47], mse:, 0.0409
qubits: [38, 49, 50, 51], mse:, 0.0519
qubits: [39, 53, 54, 55], mse:, 0.0829
layout [56, 63, 62, 61, 57, 67, 66, 65, 58, 71, 70, 69, 59, 75, 74, 73]
qubits: [56, 63, 62, 61], mse:, 0.8663
qubits: [57, 67, 66, 65], mse:, 0.0375
qubits: [58, 71, 70, 69], mse:, 0.0664
qubits: [59, 75, 74, 73], mse:, 0.0291
layout [76, 81, 82, 83, 77, 85, 86, 87, 78, 89, 90, 91, 79, 93, 94, 95]
qubits: [76, 81, 82, 83], mse:, 0.0598
qubits: [77, 85, 86, 87], mse:, 0.313
qubits: [78, 89, 90, 91], mse:, 0.0679
qubits: [79, 93, 94, 95], mse:, 0.0505
layout [96, 103, 102, 101, 97, 107, 106, 105, 98, 111, 110, 109, 99, 115, 114, 113]
qubits: [96, 103, 102, 101], mse:, 0.0302
qubits: [97, 107, 106, 105], mse:, 0.0384
qubits: [98, 111, 110, 109], mse:, 0.0375
qubits: [99, 115, 114, 113], mse:, 0.1051
layout [116, 121, 122, 123, 117, 125, 126, 127, 118, 129, 130, 131, 119, 133, 134, 135]
qubits: [116, 121, 122, 123], mse:, 0.1624
qubits: [117, 125, 126, 127], mse:, 0.7246
qubits: [118, 129, 130, 131], mse:, 0.5919
qubits: [119, 133, 134, 135], mse:, 0.5277
layout [136, 143, 142, 141, 137, 147, 146, 145, 138, 151, 150, 149, 139, 155, 154, 153]
qubits: [136, 143, 142, 141], mse:, 0.0383
qubits: [137, 147, 146, 145], mse:, 1.0187
qubits: [138, 151, 150, 149], mse:, 0.1531
qubits: [139, 155, 154, 153], mse:, 0.0471
Sa wakas, ipa-visualize natin ang pangkalahatang pagganap sa pamamagitan ng pag-plot ng cumulative distribution function (CDF) ng mga halaga ng MSE para sa lahat ng chains. Ang CDF plot ay nagpapakita ng MSE threshold sa x-axis, at ang fraction ng mga qubit pairs na mayroong higit sa MSE na iyon sa y-axis. Ang curve na ito ay nagsisimula sa zero at lumalapit sa isa habang ang threshold ay lumalaki upang masama ang lahat ng mga data points. Ang matarik na pagtaas malapit sa mababang MSE ay nagpapahiwatig na maraming pairs ay may mataas na fidelity; ang mabagal na pagtaas ay nangangahulugan na maraming pairs ay may mas malalaking error. Nag-annotate tayo ng CDF ng mga pagkakakilanlan ng pinakamahusay na pairs. Sa plot, ang bawat punto sa CDF ay tumutugma sa MSE ng isang apat-na-qubit chain, at nila-label natin ang punto ng pair ng mga qubit indices na nag-entangled sa eksperimentong iyon. Ginagawang madali nito ang pagtukoy kung aling mga physical qubit pairs ang mga nangungunang performers (ang mga pinakakaliwang mga punto sa CDF).
plot_mse_ecdfs(layouts_mse, combine_layouts=True)