Tranziția de fază Nishimori
Estimare de utilizare: 3 minute pe un procesor Heron r2 (NOTĂ: Aceasta este doar o estimare. Timpul tău de execuție poate varia.)
Context
Acest tutorial demonstrează cum se realizează o tranziție de fază Nishimori pe un procesor cuantic IBM®. Experimentul a fost descris inițial în Realizing the Nishimori transition across the error threshold for constant-depth quantum circuits.
Tranziția de fază Nishimori se referă la tranziția dintre fazele cu ordine pe distanță scurtă și lungă în modelul Ising cu legături aleatoare. Pe un calculator cuantic, faza cu ordine pe distanță lungă se manifestă ca o stare în care qubiții sunt imbricați pe întregul dispozitiv. Această stare puternic imbricată este pregătită folosind protocolul generarea imbricării prin măsurătoare (GEM). Prin utilizarea măsurătorilor în mijlocul circuitului, protocolul GEM poate imbrica qubiții pe întregul dispozitiv folosind circuite de adâncime constantă. Acest tutorial folosește implementarea protocolului GEM din pachetul software GEM Suite.
Cerințe
Înainte de a începe acest tutorial, asigură-te că ai instalate următoarele:
- Qiskit SDK v1.0 sau mai recent, cu suport pentru vizualizare
- Qiskit Runtime v0.22 sau mai recent (
pip install qiskit-ibm-runtime) - GEM Suite (
pip install gem-suite)
Configurare
# Added by doQumentation — required packages for this notebook
!pip install -q gem-suite matplotlib qiskit qiskit-ibm-runtime
import matplotlib.pyplot as plt
from collections import defaultdict
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler import generate_preset_pass_manager
from gem_suite import PlaquetteLattice
from gem_suite.experiments import GemExperiment
Pasul 1: Maparea intrărilor clasice la o problemă cuantică
Protocolul GEM funcționează pe un procesor cuantic cu conectivitate a qubiților descrisă de o rețea. Procesoarele cuantice IBM actuale folosesc rețeaua hex grea. Qubiții procesorului sunt grupați în plachete în funcție de celula unitară a rețelei pe care o ocupă. Deoarece un qubit poate apărea în mai mult de o celulă unitară, plachetele nu sunt disjuncte. Pe rețeaua hex grea, o plachetă conține 12 qubiți. Plachetele înseși formează și ele o rețea, în care două plachete sunt conectate dacă împart qubiți. Pe rețeaua hex grea, plachetele vecine împart 3 qubiți.
În pachetul software GEM Suite, clasa fundamentală pentru implementarea protocolului GEM este PlaquetteLattice, care reprezintă rețeaua de plachete (distinctă de rețeaua hex grea). Un PlaquetteLattice poate fi inițializat dintr-o hartă de cuplare a qubiților. În prezent, sunt suportate doar hărțile de cuplare hex grele.
Următoarea celulă de cod inițializează o rețea de plachete din harta de cuplare a unui procesor cuantic IBM. Rețeaua de plachete nu acoperă întotdeauna întregul hardware. De exemplu, ibm_torino are 133 de qubiți în total, dar cea mai mare rețea de plachete care se potrivește pe dispozitiv folosește doar 125 dintre ei și cuprinde un total de 18 plachete. Situații similare pot fi observate și pentru dispozitivele IBM Quantum® cu numere diferite de qubiți.
# QiskitRuntimeService.save_account(channel="ibm_quantum", token="<YOUR_API_KEYN>", overwrite=True, set_as_default=True)
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
plaquette_lattice = PlaquetteLattice.from_coupling_map(backend.coupling_map)
print(f"Number of qubits in backend: {backend.num_qubits}")
print(
f"Number of qubits in plaquette lattice: {len(list(plaquette_lattice.qubits()))}"
)
print(f"Number of plaquettes: {len(list(plaquette_lattice.plaquettes()))}")
Number of qubits in backend: 133
Number of qubits in plaquette lattice: 125
Number of plaquettes: 18
Poți vizualiza rețeaua de plachete generând o diagramă a reprezentării sale grafice. În diagramă, plachetele sunt reprezentate de hexagoane etichetate, iar două plachete sunt conectate printr-o muchie dacă împart qubiți.
plaquette_lattice.draw_plaquettes()
Poți obține informații despre plachete individuale, cum ar fi qubiții pe care îi conțin, folosind metoda plaquettes.
# Get a list of the plaquettes
plaquettes = list(plaquette_lattice.plaquettes())
# Display information about plaquette 0
plaquettes[0]
PyPlaquette(index=0, qubits=[0, 1, 2, 3, 4, 15, 16, 19, 20, 21, 22, 23], neighbors=[3, 1])
Poți produce și o diagramă a qubiților de bază care formează rețeaua de plachete.
plaquette_lattice.draw_qubits()

Pe lângă etichetele qubiților și muchiile care indică qubiții conectați, diagrama conține trei informații suplimentare relevante pentru protocolul GEM:
- Fiecare qubit este fie umbrit (gri), fie neumbrit. Qubiții umbriți sunt qubiți de „sit" care reprezintă siturile modelului Ising, iar qubiții neumbriți sunt qubiți de „legătură" folosiți pentru a media interacțiunile dintre qubiții de sit.
- Fiecare qubit de sit este etichetat fie (A), fie (B), indicând unul dintre cele două roluri pe care un qubit de sit le poate juca în protocolul GEM (rolurile sunt explicate mai târziu).
- Fiecare muchie este colorată cu una din șase culori, împărțind astfel muchiile în șase grupe. Această împărțire determină modul în care porțile cu doi qubiți pot fi paralelizate, precum și diferite tipare de planificare care pot produce cantități diferite de erori pe un procesor cuantic zgomotos. Deoarece muchiile dintr-o grupă sunt disjuncte, un strat de porți cu doi qubiți poate fi aplicat simultan pe acele muchii. De fapt, este posibil să se împartă cele șase culori în trei grupe de câte două culori astfel încât reuniunea fiecărei grupe de două culori să fie în continuare disjunctă. Prin urmare, sunt necesare doar trei straturi de porți cu doi qubiți pentru a activa fiecare muchie. Există 12 moduri de a împărți astfel cele șase culori, iar fiecare astfel de împărțire produce un program diferit de porți cu 3 straturi.
Acum că ai creat o rețea de plachete, pasul următor este să inițializezi un obiect GemExperiment, transmițând atât rețeaua de plachete, cât și Backend-ul pe care intenționezi să rulezi experimentul. Clasa GemExperiment gestionează implementarea efectivă a protocolului GEM, inclusiv generarea circuitelor, trimiterea joburilor și analiza datelor. Următoarea celulă de cod inițializează clasa de experiment, restricționând totodată rețeaua de plachete la doar două dintre plachete (21 de qubiți), reducând dimensiunea experimentului pentru a se asigura că zgomotul din hardware nu depășește semnalul.
gem_exp = GemExperiment(plaquette_lattice.filter([9, 12]), backend=backend)
# visualize the plaquette lattice after filtering
plaquette_lattice.filter([9, 12]).draw_qubits()

Un Circuit al protocolului GEM este construit urmând pașii de mai jos:
- Pregătește starea totală aplicând o poartă Hadamard fiecărui qubit.
- Aplică o poartă între fiecare pereche de qubiți conectați. Aceasta poate fi realizată folosind 3 straturi de porți. Fiecare poartă acționează pe un qubit de sit și un qubit de legătură. Dacă qubit-ul de sit este etichetat (B), atunci unghiul este fixat la . Dacă qubit-ul de sit este etichetat (A), atunci unghiul poate varia, producând circuite diferite. În mod implicit, intervalul unghiurilor este setat la 21 de puncte egal distanțate între și , inclusiv.
- Măsoară fiecare qubit de legătură în baza Pauli . Deoarece qubiții sunt măsurați în baza Pauli , aceasta poate fi realizată aplicând o poartă Hadamard înainte de a măsura qubit-ul.
Rețineți că articolul citat în introducerea acestui tutorial folosește o convenție diferită pentru unghiul , care diferă de convenția folosită în acest tutorial printr-un factor de 2.
La pasul 3, sunt măsurați doar qubiții de legătură. Pentru a înțelege în ce stare rămân qubiții de sit, este instructiv să considerăm cazul în care unghiul aplicat qubiților de sit (A) la pasul 2 este egal cu . În acest caz, qubiții de sit rămân într-o stare puternic imbricată similară stării GHZ,
Din cauza aleatoriei în rezultatele măsurătorilor, starea reală a qubiților de sit ar putea fi o stare diferită cu ordine pe distanță lungă, de exemplu, . Cu toate acestea, starea GHZ poate fi recuperată prin aplicarea unei operații de decodare bazate pe rezultatele măsurătorilor. Când unghiul este redus față de , ordinea pe distanță lungă poate fi în continuare recuperată până la un unghi critic, care în absența zgomotului este aproximativ . Sub acest unghi, starea rezultată nu mai prezintă imbricare pe distanță lungă. Această tranziție dintre prezența și absența ordinii pe distanță lungă este tranziția de fază Nishimori.
În descrierea de mai sus, qubiții de sit au rămas nemăsurați, iar operația de decodare poate fi efectuată aplicând porți cuantice. În experimentul implementat în GEM Suite, pe care îl urmează acest tutorial, qubiții de sit sunt de fapt măsurați, iar operația de decodare este aplicată într-un pas de post-procesare clasică.
În descrierea de mai sus, operația de decodare poate fi efectuată aplicând porți cuantice qubiților de sit pentru a recupera starea cuantică. Cu toate acestea, dacă scopul este de a măsura imediat starea, de exemplu în scopuri de caracterizare, atunci qubiții de sit sunt măsurați împreună cu qubiții de legătură, iar operația de decodare poate fi aplicată într-un pas de post-procesare clasică. Aceasta este modalitatea în care experimentul este implementat în GEM Suite, pe care îl urmează acest tutorial.
Pe lângă dependența de unghiul de la pasul 2, care în mod implicit parcurge 21 de valori, Circuitul protocolului GEM depinde și de tiparul de planificare folosit pentru a implementa cele 3 straturi de porți . Așa cum s-a discutat anterior, există 12 astfel de tipare de planificare. Prin urmare, numărul total de circuite din experiment este .
Circuitele experimentului pot fi generate folosind metoda circuits a clasei GemExperiment.
circuits = gem_exp.circuits()
print(f"Total number of circuits: {len(circuits)}")
Total number of circuits: 252
În scopul acestui tutorial, este suficient să considerăm un singur tipar de planificare. Următoarea celulă de cod restricționează experimentul la primul tipar de planificare. Ca urmare, experimentul are doar 21 de circuite, câte unul pentru fiecare unghi parcurs.
# Restrict experiment to the first scheduling pattern
gem_exp.set_experiment_options(schedule_idx=0)
# There are less circuits now
circuits = gem_exp.circuits()
print(f"Total number of circuits: {len(circuits)}")
# Print the RZZ angles swept over
print(f"RZZ angles:\n{gem_exp.parameters()}")
Total number of circuits: 21
RZZ angles:
[0. 0.07853982 0.15707963 0.23561945 0.31415927 0.39269908
0.4712389 0.54977871 0.62831853 0.70685835 0.78539816 0.86393798
0.9424778 1.02101761 1.09955743 1.17809725 1.25663706 1.33517688
1.41371669 1.49225651 1.57079633]
Următoarea celulă de cod desenează o diagramă a circuitului de la indexul 5. Pentru a reduce dimensiunea diagramei, porțile de măsurare de la sfârșitul circuitului sunt eliminate.
# Get the circuit at index 5
circuit = circuits[5]
# Remove the final measurements to ease visualization
circuit.remove_final_measurements()
# Draw the circuit
circuit.draw("mpl", fold=-1, scale=0.5)
Pasul 2: Optimizarea problemei pentru execuția pe hardware cuantic
Transpilarea circuitelor cuantice pentru execuție pe hardware implică de obicei un număr de etape. De regulă, etapele care implică cel mai mare efort de calcul sunt alegerea layout-ului de qubiți, rutarea porților cu doi qubiți pentru a respecta conectivitatea qubiților din hardware și optimizarea circuitului pentru a minimiza numărul de porți și adâncimea. În protocolul GEM, etapele de layout și rutare sunt inutile deoarece conectivitatea hardware este deja incorporată în design-ul protocolului. Circuitele au deja un layout de qubiți, iar porțile cu doi qubiți sunt deja mapate pe conexiunile native. Mai mult, pentru a păstra structura circuitului pe măsură ce unghiul variază, ar trebui efectuată doar o optimizare de circuit foarte de bază.
Clasa GemExperiment transpilează transparent circuitele la executarea experimentului. Etapele de layout și rutare sunt deja suprascrise implicit să nu facă nimic, iar optimizarea circuitului este efectuată la un nivel care optimizează doar porțile cu un singur qubit. Cu toate acestea, poți suprascrie sau transmite opțiuni suplimentare folosind metoda set_transpile_options. De dragul vizualizării, următoarea celulă de cod transpilează manual circuitul afișat anterior și desenează circuitul transpilat.
# Demonstrate setting transpile options
gem_exp.set_transpile_options(
optimization_level=1 # This is the default optimization level
)
pass_manager = generate_preset_pass_manager(
backend=backend,
initial_layout=list(gem_exp.physical_qubits),
**dict(gem_exp.transpile_options),
)
transpiled = pass_manager.run(circuit)
transpiled.draw("mpl", idle_wires=False, fold=-1, scale=0.5)

Pasul 3: Executarea folosind primitivele Qiskit
Pentru a executa circuitele protocolului GEM pe hardware, apelează metoda run a obiectului GemExperiment. Poți specifica numărul de shot-uri pe care vrei să le eșantionezi din fiecare Circuit. Metoda run returnează un obiect ExperimentData pe care ar trebui să îl salvezi într-o variabilă. Rețineți că metoda run doar trimite joburi fără a aștepta finalizarea lor, deci este un apel neblocant.
exp_data = gem_exp.run(shots=10_000)
Pentru a aștepta rezultatele, apelează metoda block_for_results a obiectului ExperimentData. Acest apel va face ca interpretorul să aștepte până când joburile sunt finalizate.
exp_data.block_for_results()
ExperimentData(GemExperiment, d0d5880a-34c1-4aab-a7b6-c4f58516bc03, job_ids=['cwg12ptmptp00082khhg'], metadata=<5 items>, figure_names=['two_point_correlation.svg', 'normalized_variance.svg', 'plaquette_ops.svg', 'bond_ops.svg'])
Pasul 4: Post-procesarea și returnarea rezultatului în formatul clasic dorit
La un unghi de , starea decodată ar fi starea GHZ în absența zgomotului. Ordinea pe distanță lungă a stării GHZ poate fi vizualizată prin reprezentarea grafică a magnetizării șirurilor de biți măsurate. Magnetizarea este definită ca suma operatorilor Pauli cu un singur qubit,
unde este numărul de qubiți de sit. Valoarea sa pentru un șir de biți este egală cu diferența dintre numărul de zerouri și numărul de unuri. Măsurarea stării GHZ produce starea cu toți zeroii sau starea cu toți unii cu probabilitate egală, deci magnetizarea ar fi jumătate din timp și cealaltă jumătate. În prezența erorilor datorate zgomotului, ar apărea și alte valori, dar dacă zgomotul nu este prea mare, distribuția ar fi în continuare concentrată în apropierea și .
Pentru șirurile de biți brute înainte de decodare, distribuția magnetizării ar fi echivalentă cu cea a șirurilor de biți uniform aleatoare, în absența zgomotului.
Următoarea celulă de cod reprezentat grafic magnetizarea șirurilor de biți brute și a celor decodate la unghiul de .
def magnetization_distribution(
counts_dict: dict[str, int],
) -> dict[str, float]:
"""Compute magnetization distribution from counts dictionary."""
# Construct dictionary from magnetization to count
mag_dist = defaultdict(float)
for bitstring, count in counts_dict.items():
mag = bitstring.count("0") - bitstring.count("1")
mag_dist[mag] += count
# Normalize
shots = sum(counts_dict.values())
for mag in mag_dist:
mag_dist[mag] /= shots
return mag_dist
# Get counts dictionaries with and without decoding
data = exp_data.data()
# Get the last data point, which is at the angle for the GHZ state
raw_counts = data[-1]["counts"]
# Without decoding
site_indices = [
i for i, q in enumerate(gem_exp.plaquettes.qubits()) if q.role == "Site"
]
site_raw_counts = defaultdict(int)
for key, val in raw_counts.items():
site_str = "".join(key[-1 - i] for i in site_indices)
site_raw_counts[site_str] += val
# With decoding
_, site_decoded_counts = gem_exp.plaquettes.decode_outcomes(
raw_counts, return_counts=True
)
# Compute magnetization distribution
raw_magnetization = magnetization_distribution(site_raw_counts)
decoded_magnetization = magnetization_distribution(site_decoded_counts)
# Plot
plt.bar(*zip(*raw_magnetization.items()), label="raw")
plt.bar(*zip(*decoded_magnetization.items()), label="decoded", width=0.3)
plt.legend()
plt.xlabel("Magnetization")
plt.ylabel("Frequency")
plt.title("Magnetization distribution with and without decoding")
Text(0.5, 1.0, 'Magnetization distribution with and without decoding')
Pentru a caracteriza mai riguros ordinea pe distanță lungă, poți examina corelația medie pe două puncte , definită ca
O valoare mai mare indică un grad mai mare de imbricare. Clasa GemExperiment calculează automat această valoare pentru șirurile de biți decodate ca parte a procesării datelor experimentale. Stochează o figură accesibilă prin metoda figure a clasei de date experimentale. În acest caz, numele figurii este two_point_correlation.
exp_data.figure("two_point_correlation")
Pentru a determina punctul critic al tranziției de fază Nishimori, poți examina varianța normalizată a , definită ca
care cuantifică cantitatea de fluctuație în magnetizarea la pătrat. Această valoare este maximizată la punctul critic al tranziției de fază Nishimori. În absența zgomotului, punctul critic apare la aproximativ . În prezența zgomotului, punctul critic este deplasat mai sus, dar tranziția de fază este încă observată atâta timp cât punctul critic apare sub .
exp_data.figure("normalized_variance")
Scalarea experimentului
Următoarele celule de cod rulează experimentul pentru șase plachete (49 de qubiți) și cele 12 plachete complete (125 de qubiți) și reprezintă grafic varianța normalizată. Pe măsură ce experimentul este scalat la dimensiuni mai mari, cantitatea mai mare de zgomot deplasează punctul critic spre dreapta.
gem_exp = GemExperiment(
plaquette_lattice.filter(range(3, 9)), backend=backend
)
gem_exp.set_experiment_options(schedule_idx=0)
exp_data = gem_exp.run(shots=10_000)
exp_data.block_for_results()
exp_data.figure("normalized_variance")
gem_exp = GemExperiment(plaquette_lattice, backend=backend)
gem_exp.set_experiment_options(schedule_idx=0)
exp_data = gem_exp.run(shots=10_000)
exp_data.block_for_results()
exp_data.figure("normalized_variance")
Concluzie
În acest tutorial, ai realizat o tranziție de fază Nishimori pe un procesor cuantic folosind protocolul GEM. Metricile pe care le-ai examinat în timpul post-procesării, în special corelația pe două puncte și varianța normalizată, servesc drept repere pentru capacitatea dispozitivului de a genera stări puternic imbricare pe distanță lungă. Aceste repere extind utilitatea protocolului GEM dincolo de investigarea fizicii interesante. Ca parte a protocolului, ai imbricat qubiți pe întregul dispozitiv folosind circuite de adâncime constantă. Această performanță este posibilă doar datorită utilizării de către protocol a măsurătorilor în mijlocul circuitului. În acest experiment, starea imbricată a fost măsurată imediat, dar o direcție interesantă de explorat ar fi continuarea utilizării stării în procesare cuantică suplimentară!
Sondaj tutorial
Te rog să completezi acest scurt sondaj pentru a oferi feedback despre acest tutorial. Opiniile tale ne vor ajuta să îmbunătățim conținutul și experiența utilizatorilor.
Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.