Nishimori Phasenövergang
Bruukstiet: Ruum 3 Minuten op en Heron r2 Prozessor (ACHTUNG: Dat is blots en Schattung. Dien Looptiet kann anners ween.)
Achtergrund
Dit Tutorial wiest, wo een Nishimori Phasenövergang op en IBM® Quantenprozessor dörchföhrt. Dit Experiment wurr oorspröönglich beschreven in Realizing the Nishimori transition across the error threshold for constant-depth quantum circuits.
De Nishimori Phasenövergang bedüüdt den Övergang twischen kort- un langstrecken ordneerte Phasen in dat Tofalls-Binnung-Ising-Modell. Op en Quantencomputer wiest sik de langstrecken ordneerte Phase as en Tostand, wo de Qubits över dat ganze Gerät verstrengelt sünd. Düssen hooch verstrengelte Tostand warrt mit dat generation of entanglement by measurement (GEM) Protokoll opbuut. Dör dat Bruken vun Metungen binnen in den Schaltkreis kann dat GEM-Protokoll Qubits över dat ganze Gerät verstrengeln mit Schaltkresen vun blots konstante Deepde. Hier bruken wi de Implementeerung vun dat GEM-Protokoll ut dat GEM Suite Software-Paket.
Vörutsettungen
Ehrdat du mit dit Tutorial anfängst, sörg dor för, dat du dit installiert hest:
- Qiskit SDK v1.0 oder neeger, mit Visualiseerung Ünnerstütten
- Qiskit Runtime v0.22 oder neeger (
pip install qiskit-ibm-runtime) - GEM Suite (
pip install gem-suite)
Vörbereeden
# Added by doQumentation — installs packages not in the Binder environment
!pip install -q gem-suite
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
Steg 1: Klassische Ingaben op en Quantenproblem afbillen
Dat GEM-Protokoll arbeidt op en Quantenprozessor mit Qubit-Konnektivität, de dör en Gitter beschreven warrt. De hüdigen IBM Quantenprozessoren bruukt dat Heavy-Hex-Gitter. De Qubits vun den Prozessor warrt in Plaquetten indeelit, na welke Eenheitstsell vun dat Gitter se liggt. Wieldat en Qubit in mehr as ene Eenheitstsell vörkamen kann, sünd de Plaquetten nich disjunkt. Op dat Heavy-Hex-Gitter hett en Plaquette 12 Qubits. De Plaquetten sülvst billt ok en Gitter, wo twee Plaquetten verbunnen sünd, wenn se welke Qubits deilt. Op dat Heavy-Hex-Gitter deelt Nobber-Plaquetten 3 Qubits.
In dat GEM Suite Software-Paket is de Grundklass för dat Implementeren vun dat GEM-Protokoll PlaquetteLattice, wat dat Gitter vun de Plaquetten dorstellt (wat anners is as dat Heavy-Hex-Gitter). En PlaquetteLattice kann ut en Qubit Coupling Map initialisiert warrn. Opstunns warrt blots Heavy-Hex Coupling Maps ünnerstützt.
De nakamen Code-Tsell initialisiert en Plaquette-Gitter ut de Coupling Map vun en IBM Quantenprozessor. Dat Plaquette-Gitter ümfaten nich jümmers de ganze Hardware. Bispill, ibm_torino hett 133 Qubits tosamen, aver dat gröttste Plaquette-Gitter, wat op dat Gerät passt, bruukt blots 125 dorvun un ümfaten tosamen 18 Plaquetten. Dat Glieke kann een ok bi IBM Quantum® Geräten mit anner Qubit-Antallen beovachten.
# 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
Du kannst dat Plaquette-Gitter visualiseren, indem du en Diagramm vun sien Graph-Dorstellen genereert. In dat Diagramm warrt de Plaquetten as betekente Sessecken dorstellt, un twee Plaquetten sünd dör en Kant verbunnen, wenn se Qubits deilt.
plaquette_lattice.draw_plaquettes()
Du kannst Informatschonen över enkelte Plaquetten ophalen, as de Qubits, de se inhollt, mit de plaquettes Methode.
# 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])
Du kannst ok en Diagramm vun de to Grund liggende Qubits genereren, de dat Plaquette-Gitter billt.
plaquette_lattice.draw_qubits()

Tosätzlich to de Qubit-Betekeningen un de Kanten, de wiest, welke Qubits verbunnen sünd, inhöllt dat Diagramm dree wiedere Informatschonen, de för dat GEM-Protokoll relevant sünd:
- Jedes Qubit is entweder schaddeert (grau) oder nich schaddeert. De schaddeerten Qubits sünd "Site"-Qubits, de de Plaatsen vun dat Ising-Modell dorstellt, un de nich schaddeerten Qubits sünd "Bond"-Qubits, de bruukt warrt, üm Interaktschonen twischen de Site-Qubits to vermiddeln.
- Jedes Site-Qubit is entweder (A) oder (B) betekent, wat eene vun twee Rollen wiest, de en Site-Qubit in dat GEM-Protokoll spelen kann (de Rollen warrt später verklort).
- Jede Kant is mit eene vun sess Farven inkleurt, wat de Kanten in sess Gruppen opdeelt. Düsse Opdelen bestimmt, wo Twee-Qubit-Gattern paralleliseert warrn künnt, as ok verschedene Tietplaanen, de wohrschienlich verscheden Fehlerhoochten op en ruschenden Quantenprozessor verursaakt. Wieldat de Kanten in en Grupp disjunkt sünd, kann en Schicht vun Twee-Qubit-Gattern op düsse Kanten gliektietig anleggt warrn. In't Fakt kann een de sess Farven in dree Gruppen vun twee Farven opdeeln, so dat de Vereenigung vun jede Grupp vun twee Farven noch jümmers disjunkt is. Dorüm warrt blots dree Schichten vun Twee-Qubit-Gattern bruukt, üm jede Kant to aktiveren. Dat gifft 12 Wegen, de sess Farven so optodeeln, un jede so en Opdelen levvt en annern 3-Schichten-Gattern-Tietplaan.
Nadem du en Plaquette-Gitter opbuut hest, is de nakamen Steg, en GemExperiment Objekt to initialiseren, wo du sowohl dat Plaquette-Gitter as ok dat Backend ringeevst, op dat du dat Experiment dörchföhren wullst. De GemExperiment Klass verwalltet de egentliche Implementeerung vun dat GEM-Protokoll, wat ok Schaltkresen generert, Jobs inreekt un Daten analyseert. De nakamen Code-Tsell initialisiert de Experiment-Klass un begrenzt dat Plaquette-Gitter op blots twee vun de Plaquetten (21 Qubits), üm de Grött vun dat Experiment to vermindern un seker to stellen, dat dat Ruschen in de Hardware nich dat Signal överwälligt.
gem_exp = GemExperiment(plaquette_lattice.filter([9, 12]), backend=backend)
# visualize the plaquette lattice after filtering
plaquette_lattice.filter([9, 12]).draw_qubits()

En GEM-Protokoll-Schaltkreis warrt mit düsse Stegen buut:
- Buut den all- Tostand op, indem een en Hadamard-Gattern op jedes Qubit anleggt.
- Leggt en Gattern twischen jedes Poor vun verbunnen Qubits an. Dat kann een mit 3 Schichten vun Gattern bereiken. Jedes Gattern warkt op en Site-Qubit un en Bond-Qubit. Wenn dat Site-Qubit (B) betekent is, denn is de Winkel fast op sett. Wenn dat Site-Qubit (A) betekent is, denn dörf de Winkel variern, wat verschedene Schaltkresen levvt. Standaardmäßig is de Bereich vun Winkels op 21 glikmäßig verdeelte Punkten twischen un ,inklusive, sett.
- Meet jedes Bond-Qubit in de Pauli Basis. Wieldat Qubits in de Pauli Basis meten warrt, kann een dat maken, indem een en Hadamard-Gattern vör de Metung anleggt.
Beacht, dat dat Paper, wat in de Inleitung vun dit Tutorial ziteert warrt, en anner Konventschon för de Winkel bruukt, de sik dör en Faktor vun 2 vun de Konventschon in dit Tutorial ünnerscheedt.
In Steg 3 warrt blots de Bond-Qubits meten. Üm to verstahn, in welken Tostand de Site-Qubits blivt, is dat hülpfull, den Fall to betrachten, dat de Winkel, de in Steg 2 op Site-Qubits (A) anleggt warrt, gliek is. In düssen Fall blivt de Site-Qubits in en hooch verstrengelten Tostand, ähnlich as bi den GHZ-Tostand,
Wegen de Tofall in de Metungsergebnissen kunn de egentliche Tostand vun de Site-Qubits en annern Tostand mit langstrecken Ordnung ween, to Bispill, . Aver de GHZ-Tostand kann wedder herstellt warrn, indem een en Dekodeer-Operatschon basert op de Metungsergebnissen anleggt. Wenn de Winkel vun rundaal dreht warrt, kann de langstrecken Ordnung noch jümmers wedder herstellt warrn bet to en kritischen Winkel, de in Afwesenheit vun Ruschen ungefähr is. Ünner düssen Winkel wiest de Tostand, de opbuut warrt, nich mehr langstrecken Verstrengelung. Düsse Övergang twischen de Anwesenheit un Afwesenheit vun langstrecker Ordnung is de Nishimori Phasenövergang.
In de Beschrieven hier baven wurr de Site-Qubits nich meten, un de Dekodeer-Operatschon kann dörchföhrt warrn, indem een Quantengattern anleggt. In dat Experiment, as dat in de GEM Suite implementeert is, wat dit Tutorial folgt, warrt de Site-Qubits tatsächlich meten, un de Dekodeer-Operatschon warrt in en klassischen Naverarbeitung-Steg anleggt.
In de Beschrieven hier baven kann de Dekodeer-Operatschon dörchföhrt warrn, indem een Quantengattern op de Site-Qubits anleggt, üm den Quantentostand wedder herto to kriegen. Aver, wenn dat Teel is, den Tostand glieks to meten, to Bispill för Karakteriseerungszweck, denn warrt de Site-Qubits tosamen mit de Bond-Qubits meten, un de Dekodeer-Operatschon kann in en klassischen Naverarbeitung-Steg anleggt warrn. So is dat Experiment in de GEM Suite implementeert, wat dit Tutorial folgt.
Tosätzlich doto, dat dat vun de Winkel in Steg 2 afhängig is, de standaardmäßig över 21 Werten geiht, hänggt de GEM-Protokoll-Schaltkreis ok vun dat Tietplaan-Muster af, dat bruukt warrt, üm de 3 Schichten vun Gattern to implementeren. As vörheer bespraken gifft dat 12 so Tietplaan-Mustern. Dorüm is de totale Antall vun Schaltkresen in dat Experiment .
De Schaltkresen vun dat Experiment künnt mit de circuits Methode vun de GemExperiment Klass genereert warrn.
circuits = gem_exp.circuits()
print(f"Total number of circuits: {len(circuits)}")
Total number of circuits: 252
För de Zweck vun dit Tutorial is dat noog, blots en enkeltet Tietplaan-Muster to betrachten. De nakamen Code-Tsell begrenzt dat Experiment op dat eerste Tietplaan-Muster. Domet hett dat Experiment blots 21 Schaltkresen, een för jede Winkel, över de gahn warrt.
# 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]
De nakamen Code-Tsell wiest en Diagramm vun den Schaltkreis bi Index 5. Üm de Grött vun dat Diagramm to vermindern, warrt de Metungs-Gattern an't End vun den Schaltkreis wegnahmen.
# 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)
Steg 2: Problem för Quanten-Hardware-Utföhrung optimeren
Transpileren Quantenschaltkresen för de Utföhrung op Hardware ümfaten typischerwiese en ganze Reeg vun Etappen. Typischerwiese sünd de Etappen, de am meisten rekenintensiv sünd, de Utwahl vun dat Qubit-Layout, dat Routing vun de Twee-Qubit-Gattern, üm sik an de Qubit-Konnektivität vun de Hardware antopassen, un de Optimeerung vun den Schaltkreis, üm sien Gattern-Antall un Deepde to minimeren. In dat GEM-Protokoll sünd de Layout- un Routing-Etappen onnödig, wieldat de Hardware-Konnektivität al in dat Design vun dat Protokoll inbuut is. De Schaltkresen hebbt al en Qubit-Layout, un de Twee-Qubit-Gattern sünd al op native Verbindungen afbillt. Doröver henüt schull blots sehr eenfache Schaltkreis-Optimeerung dörchföhrt warrn, üm de Struktur vun den Schaltkreis to erhollen, wenn de Winkel varieert warrt.
De GemExperiment Klass transpileert Schaltkresen transparent, wenn dat Experiment dörchföhrt warrt. De Layout- un Routing-Etappen sünd standaardmäßig al överschreven, üm nix to doon, un Schaltkreis-Optimeerung warrt op en Niveau dörchföhrt, dat blots Een-Qubit-Gattern optimiert. Aver du kannst tosätzliche Optschen överschrieven oder overgeven, indem du de set_transpile_options Methode bruukst. För de Zweck vun de Visualiseerung transpileert de nakamen Code-Tsell manuell den Schaltkreis, de vörheer wiest wurr, un wiest den transpileerten Schaltkreis.
# 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)

Steg 3: Mit Qiskit Primitives utföhren
Üm de GEM-Protokoll-Schaltkresen op de Hardware uttofören, roop de run Methode vun dat GemExperiment Objekt op. Du kannst de Antall vun Shots angeven, de du ut jeden Schaltkreis sampeln wullst. De run Methode levvt en ExperimentData Objekt, wat du in en Variable spiekern schullst. Beacht, dat de run Methode blots Jobs inreekt, ahn op ehr to töven bet se fäärdich sünd, so dat dat en nich-blockerend Oproop is.
exp_data = gem_exp.run(shots=10_000)
Üm op de Ergebnissen to töven, roop de block_for_results Methode vun dat ExperimentData Objekt op. Düsse Oproop lett den Interpreter hangen, bet de Jobs fäärdich sünd.
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'])
Steg 4: Naverarbeiden un Ergebniss in dat wünschte klassische Format torüchgeven
Bi en Winkel vun wurr de dekodeerte Tostand de GHZ-Tostand in Afwesenheit vun Ruschen ween. De langstrecken Ordnung vun den GHZ-Tostand kann visualiseert warrn, indem een de Magnetiseerung vun de metenen Bitstrings afbillt. De Magnetiseerung warrt defineert as de Summ vun de Een-Qubit-Pauli Operatoren,
wo de Antall vun Site-Qubits is. Sien Weert för en Bitstring is gliek de Ünnerscheed twischen de Antall vun Nulls un de Antall vun Eens. Dat Meten vun den GHZ-Tostand levvt den all-Null Tostand oder den all-Eens Tostand mit glieker Wohrschienlichkeit, so dat de Magnetiseerung de halve Tiet un de anner halve Tiet wurr ween. In de Anwesenheit vun Fehlers wegen Ruschen wurr ok anner Weerten optreden, aver wenn dat Ruschen nich to groot is, wurr de Verdeling noch jümmers Spitzen bi un wiesen.
För de roh Bitstrings vör de Dekodeerung wurr de Verdeling vun de Magnetiseerung gliektobedüden mit düsse vun glikmäßig tofällige Bitstrings ween, in Afwesenheit vun Ruschen.
De nakamen Code-Tsell wiest de Magnetiseerung vun de roh Bitstrings un de dekodeerten Bitstrings bi de Winkel vun .
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')
Üm de langstrecken Ordnung rigoroser to karakteriseren, kannst du de döörsnittliche Twee-Punkt-Korrelatschon betrachten, defineert as
En högere Weert wiest en grötteren Graad vun Verstrengelung an. De GemExperiment Klass berekent düssen Weert automaatsch för de dekodeerten Bitstrings as Deel vun de Verarbeitung vun de experimentellen Daten. Se spiekert en Diagramm, wat över de figure Methode vun de Experiment-Daten-Klass toreekfohren is. In düssen Fall heet dat Diagramm two_point_correlation.
exp_data.figure("two_point_correlation")
Üm den kritischen Punkt vun den Nishimori Phasenövergang to bestimmen, kannst du op de normaliseerte Varianz vun kieken, defineert as
wat de Stärk vun de Swankung in de quadreerte Magnetiseerung quantifizeert. Düsse Weert is maximal an den kritischen Punkt vun den Nishimori Phasenövergang. In Afwesenheit vun Ruschen tritt de kritische Punkt bi ungefähr op. In Anwesenheit vun Ruschen warrt de kritische Punkt na baven verschaven, aver de Phasenövergang warrt noch jümmers beovacht, solang de kritische Punkt ünner liggt.
exp_data.figure("normalized_variance")
Dat Experiment opschalen
De nakamen Code-Tsellen föhrt dat Experiment för sess Plaquetten (49 Qubits) un de vull 12 Plaquetten (125 Qubits) dörch un wiest de normaliseerte Varianz. As dat Experiment op grötere Grötten opschalt warrt, verschuuvt de grötere Antall vun Ruschen den kritischen Punkt na rechts.
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")
Afsluss
In dit Tutorial hest du en Nishimori Phasenövergang op en Quantenprozessor mit dat GEM-Protokoll realiseert. De Metriken, de du während de Naverarbeitung ünnersöcht hest, besünners de Twee-Punkt-Korrelatschon un de normaliseerte Varianz, deent as Benchmarks för de Fähigkeit vun dat Gerät, langstrecken verstrengelten Toständ to genereren. Düsse Benchmarks verwiedert den Nutzen vun dat GEM-Protokoll över dat Utforschen vun interessante Physik henüt. As Deel vun dat Protokoll hest du Qubits över dat ganze Gerät verstrengeltt mit Schaltkresen vun blots konstante Deepde. Düsse Kunststück is blots möglich dör dat Bruken vun Metungen binnen in den Schaltkreis vun dat Protokoll. In dit Experiment wurr de verstrengelten Tostand glieks meten, aver en interessante Weg, de een utforschen kunn, wurr ween, den Tostand wieder to bruken in tosätzliche Quantenverarbeitung!
Tutorial-Ümmfraag
Bitte maak düsse korte Ümmfraag mit, üm Feedback to dit Tutorial to geven. Dien Insichten helpt uns, unse Inhalt-Anbod un Brukerfarung to verbettern.