To't Hauptinholt springen

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()

Output of the previous code cell

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()

Output of the previous code cell

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()

Output of the previous code cell

En GEM-Protokoll-Schaltkreis warrt mit düsse Stegen buut:

  1. Buut den all-+|+\rangle Tostand op, indem een en Hadamard-Gattern op jedes Qubit anleggt.
  2. Leggt en RZZR_{ZZ} Gattern twischen jedes Poor vun verbunnen Qubits an. Dat kann een mit 3 Schichten vun Gattern bereiken. Jedes RZZR_{ZZ} Gattern warkt op en Site-Qubit un en Bond-Qubit. Wenn dat Site-Qubit (B) betekent is, denn is de Winkel fast op π2\frac{\pi}{2} 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 00 un π2\frac{\pi}{2},inklusive, sett.
  3. Meet jedes Bond-Qubit in de Pauli XX Basis. Wieldat Qubits in de Pauli ZZ 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 RZZR_{ZZ} 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 RZZR_{ZZ} Winkel, de in Steg 2 op Site-Qubits (A) anleggt warrt, gliek π2\frac{\pi}{2} is. In düssen Fall blivt de Site-Qubits in en hooch verstrengelten Tostand, ähnlich as bi den GHZ-Tostand,

GHZ=0000+1111.\lvert \text{GHZ} \rangle = \lvert 00 \cdots 00 \rangle + \lvert 11 \cdots 11 \rangle.

Wegen de Tofall in de Metungsergebnissen kunn de egentliche Tostand vun de Site-Qubits en annern Tostand mit langstrecken Ordnung ween, to Bispill, 00110+11001\lvert 00110 \rangle + \lvert 11001 \rangle. Aver de GHZ-Tostand kann wedder herstellt warrn, indem een en Dekodeer-Operatschon basert op de Metungsergebnissen anleggt. Wenn de RZZR_{ZZ} Winkel vun π2\frac{\pi}{2} 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 0.3π0.3 \pi 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 RZZR_{ZZ} 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 RZZR_{ZZ} Gattern to implementeren. As vörheer bespraken gifft dat 12 so Tietplaan-Mustern. Dorüm is de totale Antall vun Schaltkresen in dat Experiment 21×12=25221 \times 12 = 252.

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 RZZR_{ZZ} 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)

Output of the previous code cell

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 RZZR_{ZZ} 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)

Output of the previous code cell

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 RZZR_{ZZ} Winkel vun π2\frac{\pi}{2} 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 MM warrt defineert as de Summ vun de Een-Qubit-Pauli ZZ Operatoren,

M=j=1NZj,M = \sum_{j=1}^N Z_j,

wo NN 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 +N+N de halve Tiet un N-N 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 +N+N un N-N 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 RZZR_{ZZ} Winkel vun π2\frac{\pi}{2}.

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')

Output of the previous code cell

Üm de langstrecken Ordnung rigoroser to karakteriseren, kannst du de döörsnittliche Twee-Punkt-Korrelatschon ff betrachten, defineert as

f=1N2(M2M2).f = \frac{1}{N^2} \left(\langle M^2 \rangle - \langle M \rangle ^2\right).

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")

Output of the previous code cell

Üm den kritischen Punkt vun den Nishimori Phasenövergang to bestimmen, kannst du op de normaliseerte Varianz vun M2/NM^2 / N kieken, defineert as

g=1N3(M4M22),g = \frac{1}{N^3} \left(\langle M^4 \rangle - \langle M^2 \rangle^2\right),

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 0.3π0.3 \pi 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 0.5π0.5 \pi liggt.

exp_data.figure("normalized_variance")

Output of the previous code cell

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")

Output of the previous code cell

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")

Output of the previous code cell

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.

Link to de Ümmfraag