Benchmark sirkuit dinamis dengan pasangan Bell yang dipotong
Estimasi penggunaan: 22 detik pada prosesor Heron r2 (CATATAN: Ini hanya estimasi. Waktu aktual mungkin berbeda.)
Latar Belakang​
Perangkat keras kuantum umumnya terbatas pada interaksi lokal, namun banyak algoritma yang membutuhkan entanglement antara Qubit yang berjauhan atau bahkan Qubit pada prosesor yang berbeda. Sirkuit dinamis — yaitu, Circuit dengan pengukuran di tengah sirkuit dan feedforward — menyediakan cara untuk mengatasi keterbatasan ini dengan menggunakan komunikasi klasik secara real-time guna mengimplementasikan operasi kuantum non-lokal secara efektif. Dalam pendekatan ini, hasil pengukuran dari satu bagian sirkuit (atau satu QPU) dapat memicu Gate secara kondisional pada bagian lain, memungkinkan kita menteleportasi entanglement lintas jarak jauh. Inilah yang menjadi dasar skema local operations and classical communication (LOCC), di mana kita menggunakan resource state yang sudah ter-entangle (pasangan Bell) dan mengkomunikasikan hasil pengukuran secara klasik untuk menghubungkan Qubit yang berjauhan.
Salah satu penggunaan menjanjikan dari LOCC adalah merealisasikan Gate CNOT jarak jauh virtual melalui teleportasi, seperti yang ditunjukkan dalam tutorial long-range entanglement. Alih-alih menggunakan CNOT jarak jauh secara langsung (yang mungkin tidak didukung konektivitas perangkat keras), kita membuat pasangan Bell dan melakukan implementasi Gate berbasis teleportasi. Namun, fidelitas operasi semacam ini bergantung pada karakteristik perangkat keras. Dekoherensi Qubit selama jeda yang diperlukan (saat menunggu hasil pengukuran) dan latensi komunikasi klasik dapat menurunkan kualitas state yang ter-entangle. Selain itu, kesalahan pada pengukuran di tengah sirkuit lebih sulit dikoreksi dibanding kesalahan pada pengukuran akhir karena kesalahan tersebut merambat ke sisa sirkuit melalui Gate kondisional.
Dalam eksperimen referensi, para penulis memperkenalkan benchmark fidelitas pasangan Bell untuk mengidentifikasi bagian perangkat mana yang paling cocok untuk entanglement berbasis LOCC. Idenya adalah menjalankan sirkuit dinamis kecil pada setiap grup empat Qubit yang terhubung dalam prosesor. Sirkuit empat Qubit ini pertama-tama membuat pasangan Bell pada dua Qubit tengah, lalu menggunakannya sebagai resource untuk meng-entangle dua Qubit tepi dengan menggunakan LOCC. Secara konkret, Qubit 1 dan 2 disiapkan ke dalam pasangan Bell yang tidak dipotong secara lokal (menggunakan Hadamard dan CNOT), kemudian rutinitas teleportasi menggunakan pasangan Bell tersebut untuk meng-entangle Qubit 0 dan 3. Qubit 1 dan 2 diukur selama eksekusi sirkuit, dan berdasarkan hasilnya, koreksi Pauli (X pada Qubit 3 dan Z pada Qubit 0) diterapkan. Qubit 0 dan 3 kemudian berada dalam keadaan Bell di akhir sirkuit.
Untuk mengukur kualitas pasangan yang ter-entangle ini, kita mengukur stabilizernya: khususnya, paritas dalam basis () dan dalam basis (). Untuk pasangan Bell yang sempurna, kedua ekspektasi ini sama dengan +1. Dalam praktiknya, noise perangkat keras akan mengurangi nilai-nilai ini. Oleh karena itu, kita mengulangi sirkuit dua kali untuk setiap pasangan Qubit: satu sirkuit mengukur Qubit 0 dan 3 dalam basis , dan satu lagi mengukurnya dalam basis . Dari hasilnya, kita mendapatkan estimasi dan untuk pasangan Qubit tersebut. Kita menggunakan mean squared error (MSE) dari stabilizer-stabilizer ini terhadap nilai ideal (1) sebagai metrik sederhana fidelitas entanglement. MSE yang lebih rendah berarti kedua Qubit mencapai keadaan Bell yang lebih mendekati ideal (fidelitas lebih tinggi), sedangkan MSE yang lebih tinggi mengindikasikan lebih banyak kesalahan. Dengan memindai eksperimen ini di seluruh perangkat, kita dapat melakukan benchmark kemampuan pengukuran-dan-feedforward dari berbagai grup Qubit serta mengidentifikasi pasangan Qubit terbaik untuk operasi LOCC.
Tutorial ini mendemonstrasikan eksperimen pada perangkat IBM Quantum® untuk mengilustrasikan bagaimana sirkuit dinamis dapat digunakan untuk menghasilkan dan mengevaluasi entanglement antara Qubit yang berjauhan. Kita akan memetakan semua rantai empat Qubit linear pada perangkat, menjalankan Circuit teleportasi pada masing-masing, kemudian memvisualisasikan distribusi nilai MSE. Prosedur end-to-end ini menunjukkan cara memanfaatkan Qiskit Runtime dan fitur sirkuit dinamis untuk membuat pilihan yang peka terhadap perangkat keras dalam pemotongan Circuit atau pendistribusian algoritma kuantum di seluruh sistem modular.
Persyaratan​
Sebelum memulai tutorial ini, pastikan kamu telah menginstal hal-hal berikut:
- Qiskit SDK v2.0 atau lebih baru, dengan dukungan visualisasi
- Qiskit Runtime v0.40 atau lebih baru (
pip install qiskit-ibm-runtime)
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()
Langkah 1: Petakan input klasik ke masalah kuantum​
Langkah pertama adalah membuat sekumpulan Circuit kuantum untuk membenchmark semua kandidat tautan Bell pair yang disesuaikan dengan topologi perangkat. Kita akan mencari secara terprogram pada peta pasangan perangkat untuk semua rantai empat Qubit yang terhubung secara linier. Setiap rantai seperti itu (dilabeli dengan indeks Qubit ) berfungsi sebagai kasus uji untuk Circuit pertukaran entanglement. Dengan mengidentifikasi semua jalur panjang 4 yang mungkin, kita memastikan cakupan maksimum untuk kemungkinan pengelompokan Qubit yang dapat merealisasikan protokol ini.
service = QiskitRuntimeService()
backend = service.least_busy(operational=True)
Kita menghasilkan rantai-rantai ini dengan menggunakan fungsi pembantu yang melakukan pencarian greedy pada graf perangkat. Fungsi ini mengembalikan "stripe" berisi empat rantai empat-Qubit yang dibundel menjadi grup 16-Qubit (Circuit dinamis saat ini membatasi ukuran register pengukuran menjadi 16 Qubit). Pembundalan memungkinkan kita menjalankan beberapa eksperimen empat-Qubit secara paralel pada bagian chip yang berbeda, sehingga penggunaan seluruh perangkat menjadi lebih efisien. Setiap stripe 16-Qubit berisi empat rantai yang tidak saling tumpang-tindih, artinya tidak ada Qubit yang digunakan kembali dalam satu grup. Misalnya, satu stripe bisa terdiri dari rantai , , , dan yang semuanya dikemas bersama. Qubit yang tidak dimasukkan dalam stripe mana pun dikembalikan dalam variabel 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)
Selanjutnya, kita membangun Circuit untuk setiap stripe 16-Qubit. Rutinitas ini melakukan hal berikut untuk setiap rantai:
- Siapkan Bell pair tengah: Terapkan Hadamard pada Qubit 1 dan CNOT dari Qubit 1 ke Qubit 2. Ini menentanglement Qubit 1 dan 2 (membuat state Bell ).
- Entangle Qubit tepi: Terapkan CNOT dari Qubit 0 ke Qubit 1, dan CNOT dari Qubit 2 ke Qubit 3. Ini menghubungkan pasangan yang awalnya terpisah sehingga Qubit 0 dan 3 akan menjadi terentanglement setelah langkah-langkah berikutnya. Hadamard pada Qubit 2 juga diterapkan (ini, dikombinasikan dengan CNOT sebelumnya, membentuk bagian dari pengukuran Bell pada Qubit 1 dan 2). Pada titik ini, Qubit 0 dan 3 belum terentanglement, tetapi Qubit 1 dan 2 terentanglement dengan keduanya dalam state empat-Qubit yang lebih besar.
- Pengukuran mid-circuit dan feedforward: Qubit 1 dan 2 (Qubit tengah) diukur dalam basis komputasi, menghasilkan dua bit klasik. Berdasarkan hasil pengukuran tersebut, kita menerapkan operasi kondisional: jika pengukuran Qubit 1 (sebut bit ini ) bernilai 1, kita menerapkan Gate pada Qubit 3; jika pengukuran Qubit 2 () bernilai 1, kita menerapkan Gate pada Qubit 0. Gate kondisional ini (direalisasikan menggunakan konstruk
if_test/if_elseQiskit) mengimplementasikan koreksi teleportasi standar. Koreksi ini "membatalkan" flip Pauli acak yang terjadi akibat proyeksi Qubit 1 dan 2, memastikan bahwa Qubit 0 dan 3 berakhir pada state Bell yang diketahui, terlepas dari hasil pengukuran. Setelah langkah ini, Qubit 0 dan 3 seharusnya secara ideal terentanglement dalam state Bell . - Ukur stabilizer Bell pair: Kita kemudian membagi menjadi dua versi Circuit. Pada versi pertama, kita mengukur stabilizer pada Qubit 0 dan 3. Pada versi kedua, kita mengukur stabilizer pada Qubit-Qubit tersebut.
Untuk setiap layout awal empat-Qubit, fungsi di atas mengembalikan dua Circuit (satu untuk pengukuran stabilizer , satu untuk ). Di akhir langkah ini, kita memiliki daftar Circuit yang mencakup setiap rantai empat-Qubit di perangkat. Circuit-Circuit ini mencakup pengukuran mid-circuit dan operasi kondisional (if/else), yang merupakan instruksi kunci dari Circuit dinamis.
circuits = create_bell_stab(initial_layouts)
circuits[-1].draw("mpl", fold=-1)

Langkah 2: Optimalkan masalah untuk eksekusi pada perangkat keras kuantum​
Sebelum menjalankan Circuit kita pada perangkat keras nyata, kita perlu melakukan transpilasi agar sesuai dengan batasan fisik perangkat. Transpilasi akan memetakan Circuit abstrak ke Qubit fisik dan set Gate perangkat yang dipilih. Karena kita sudah memilih Qubit fisik tertentu untuk setiap rantai (dengan menyediakan initial_layout ke generator Circuit), kita menggunakan optimization_level=0 pada Transpiler dengan layout tetap tersebut. Ini memberi tahu Qiskit untuk tidak menetapkan ulang Qubit atau melakukan optimasi berat yang dapat mengubah struktur Circuit. Kita ingin mempertahankan urutan operasi (terutama Gate kondisional) persis seperti yang ditentukan.
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)

Langkah 3: Eksekusi menggunakan primitif Qiskit​
Kita sekarang bisa menjalankan eksperimen pada perangkat kuantum. Kita menggunakan Qiskit Runtime dan primitif Sampler-nya untuk mengeksekusi sekumpulan Circuit secara efisien.
sampler = Sampler(mode=backend)
sampler.options.environment.job_tags = ["cut-bell-pair-test"]
job = sampler.run(isa_circuits)
Langkah 4: Pasca-proses dan kembalikan hasil dalam format klasik yang diinginkan​
Langkah terakhir adalah menghitung metrik mean squared error (MSE) untuk setiap grup Qubit yang diuji dan merangkum hasilnya. Untuk setiap rantai, kita sekarang memiliki dan yang terukur. Jika Qubit 0 dan 3 terentanglement sempurna dalam state Bell , kita akan mengharapkan keduanya bernilai +1. Kita mengkuantifikasi penyimpangan menggunakan MSE:
Nilai ini adalah 0 untuk Bell pair sempurna, dan meningkat seiring state terentanglement menjadi lebih berisik (dengan hasil acak memberikan ekspektasi sekitar 0, MSE akan mendekati 1). Kode ini menghitung MSE untuk setiap grup empat-Qubit.
Hasilnya mengungkapkan rentang kualitas entanglement yang luas di seluruh perangkat. Hal ini mengonfirmasi temuan makalah bahwa variasi kualitas Bell state bisa lebih dari satu orde besarnya tergantung pada Qubit fisik mana yang digunakan. Secara praktis, ini berarti bahwa wilayah atau tautan tertentu pada chip jauh lebih baik dalam melakukan operasi pengukuran mid-circuit dan feedforward dibandingkan yang lain. Faktor-faktor seperti kesalahan readout Qubit, masa hidup Qubit, dan crosstalk kemungkinan berkontribusi pada perbedaan-perbedaan ini. Misalnya, jika satu rantai mencakup Qubit readout yang sangat berisik, pengukuran mid-circuit bisa tidak dapat diandalkan, sehingga menghasilkan fidelitas yang buruk untuk pasangan terentanglement tersebut (MSE tinggi).
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
Terakhir, kita memvisualisasikan performa keseluruhan dengan memplot cumulative distribution function (CDF) dari nilai-nilai MSE untuk semua rantai. Plot CDF menampilkan ambang batas MSE pada sumbu-x, dan proporsi pasangan Qubit yang memiliki MSE paling banyak sebesar itu pada sumbu-y. Kurva ini dimulai dari nol dan mendekati satu seiring ambang batas berkembang untuk mencakup semua titik data. Kenaikan curam di dekat MSE rendah akan menunjukkan bahwa banyak pasangan memiliki fidelitas tinggi; kenaikan lambat berarti banyak pasangan memiliki kesalahan lebih besar. Kita memberi anotasi pada CDF dengan identitas pasangan terbaik. Dalam plot tersebut, setiap titik pada CDF sesuai dengan MSE satu rantai empat-Qubit, dan kita memberi label titik tersebut dengan pasangan indeks Qubit yang terentanglement dalam eksperimen itu. Ini memudahkan untuk menemukan pasangan Qubit fisik mana yang menjadi pemain terbaik (titik paling kiri pada CDF).
plot_mse_ecdfs(layouts_mse, combine_layouts=True)