מעבר פאזה של Nishimori
הערכת שימוש: 3 דקות על מעבד Heron r2 (הערה: זוהי הערכה בלבד. זמן הריצה שלך עשוי להשתנות.)
תוצאות למידה
לאחר מעבר על מדריך זה, המשתמשים יכולים לצפות לתוצאות הבאות:
- הבנת מעבר הפאזה של Nishimori וכיצד הוא בא לידי ביטוי כהופעת שזירה ארוכת טווח במודל Ising עם קשרים אקראיים.
- מימוש פרוטוקול generation of entanglement by measurement (GEM) על חומרת קוונטום באמצעות מדידות אמצע-מעגל ומעגלים בעומק קבוע.
- אפיון המעבר על ידי חילוץ קורלציית שתי הנקודות והשונות המנורמלת של המגנטיזציה מנתוני ניסוי.
דרישות מוקדמות
אנו ממליצים להכיר את הנושאים הבאים לפני מעבר על מדריך זה:
- המדריך מדידת קיוביטים, במיוחד הסעיף על מדידת אמצע-מעגל עליו מסתמך פרוטוקול GEM.
- סימולציה מדויקת ורועשת עם Qiskit Aer primitives, שזה הדרך בה מורץ הסעיף הקטן-בסקאלה.
- שזירה ארוכת טווח עם מעגלים דינמיים, מדריך משלים המשתמש באותה פרדיגמת שזירה מבוססת מדידה.
- Heavy-hex lattice, טופולוגיית החומרה של IBM® שעליה בנוי סריג הפלאקטות.
רקע
מדריך זה מדגים כיצד להגשים מעבר פאזה של Nishimori על מעבד קוונטי. ניסוי זה תואר במקור במאמר Realizing the Nishimori transition across the error threshold for constant-depth quantum circuits.
מעבר הפאזה של Nishimori מתייחס למעבר בין פאזות מסודרות בטווח קצר לטווח ארוך במודל Ising עם קשרים אקראיים. במחשב קוונטי, הפאזה המסודרת בטווח ארוך באה לידי ביטוי במצב בו קיוביטים משולבים קוונטית על פני כל המכשיר. מצב משולב קוונטית זה מוכן באמצעות פרוטוקול generation of entanglement by measurement (GEM). באמצעות מדידות אמצע-מעגל, פרוטוקול GEM מסוגל לשלב קוונטית קיוביטים על פני כל המכשיר באמצעות מעגלים בעומק קבוע בלבד. מדריך זה משתמש במימוש של פרוטוקול GEM מחבילת התוכנה GEM Suite.
דרישות
לפני שמתחילים מדריך זה, ודאו שיש לכם את הדברים הבאים מותקנים:
- Qiskit SDK v1.0 ומעלה, עם תמיכה ב-visualization
- Qiskit Runtime v0.22 ומעלה (
pip install qiskit-ibm-runtime) - Qiskit Aer v0.14 ומעלה (
pip install qiskit-aer) - GEM Suite (
pip install gem-suite)
הכנה
# Added by doQumentation — required packages for this notebook
!pip install -q gem-suite matplotlib qiskit qiskit-aer qiskit-ibm-runtime
import matplotlib.pyplot as plt
import warnings
from collections import defaultdict
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_aer import AerSimulator
from qiskit.transpiler import generate_preset_pass_manager
from gem_suite import PlaquetteLattice
from gem_suite.experiments import GemExperiment
דוגמה קטנה-בסקאלה עם סימולטור
בסעיף זה, מעבירים על כל תהליך העבודה על גבי ה-AerSimulator ללא רעש. סריג הפלאקטות מוגבל לפלאקט בודד (12 קיוביטים) כדי שהסימולציה תישאר קטנה ומהירה, תוך כדי בחינת כל חלקי פרוטוקול GEM: מדידת אמצע-מעגל, סריקת זוויות , פענוח, וניתוח השונות המנורמלת. אותו תהליך עבודה מוגדל מאוחר יותר למספר פלאקטות ולסריג המלא על חומרה אמיתית.
שלב 1: מיפוי קלטים קלאסיים לבעיה קוונטית
פרוטוקול GEM פועל על מעבד קוונטי עם קישוריות קיוביטים המתוארת על ידי סריג. מעבדים קוונטיים של IBM Quantum® כיום משתמשים ב-heavy-hex lattice. הקיוביטים של המעבד מקובצים ל-פלאקטות (plaquettes) על בסיס תא היחידה של הסריג בו הם שוכנים. מכיוון שקיוביט עשוי להופיע ביותר מתא יחידה אחד, הפלאקטות אינן זרות. בסריג heavy-hex, פלאקט מכיל 12 קיוביטים. הפלאקטות עצמן גם יוצרות סריג, שבו שתי פלאקטות מחוברות אם הן חולקות קיוביטים כלשהם. בסריג heavy-hex, פלאקטות שכנות חולקות שלושה קיוביטים.
בחבילת התוכנה GEM Suite, המחלקה הבסיסית למימוש פרוטוקול GEM היא PlaquetteLattice, המייצגת את סריג הפלאקטות (שונה מסריג heavy-hex). ניתן לאתחל PlaquetteLattice ממפת צימוד קיוביטים. כרגע, רק מפות צימוד heavy-hex נתמכות.
תא הקוד הבא מאתחל סריג פלאקטות ממפת הצימוד של מעבד לעיבוד קוונטי (QPU). סריג הפלאקטות לא תמיד מקיף את כל החומרה. לדוגמה, ל-ibm_torino יש 133 קיוביטים בסך הכל, אך סריג הפלאקטות הגדול ביותר שמתאים למכשיר משתמש רק ב-125 מהם, ומכיל 18 פלאקטות; ל-ibm_pittsburgh (156 קיוביטים) מתאים באופן דומה 144 קיוביטים ל-21 פלאקטות. אותו דפוס תקף גם למעבדי QPU heavy-hex אחרים עם ספירות קיוביטים שונות.
# QiskitRuntimeService.save_account(channel="ibm_quantum", token="<YOUR_API_KEY>", overwrite=True,
# set_as_default=True)
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
aer_backend = AerSimulator.from_backend(backend)
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()))}")
ניתן לדמיין את סריג הפלאקטות על ידי יצירת דיאגרמה של ייצוג הגרף שלו. בדיאגרמה, הפלאקטות מיוצגות על ידי משושים מסומנים, ושתי פלאקטות מחוברות בקצה אם הן חולקות קיוביטים.
plaquette_lattice.draw_plaquettes()

ניתן לאחזר מידע על פלאקטות בודדות, כגון הקיוביטים שהן מכילות, באמצעות המתודה plaquettes.
# Get a list of the plaquettes
plaquettes = list(plaquette_lattice.plaquettes())
# Display information about plaquette 0
plaquettes[0]
PyPlaquette(index=0, qubits=[3, 4, 5, 6, 7, 16, 17, 23, 24, 25, 26, 27], neighbors=[4, 3, 1])
ניתן גם לייצר דיאגרמה של הקיוביטים הבסיסיים שיוצרים את סריג הפלאקטות.
plaquette_lattice.draw_qubits()

בנוסף לתוויות הקיוביטים והקצוות המציינים אילו קיוביטים מחוברים, הדיאגרמה מכילה שלוש פיסות מידע נוספות הרלוונטיות לפרוטוקול GEM:
- כל קיוביט הוא מוצל (אפור) או לא מוצל. הקיוביטים המוצללים הם קיוביטי "אתר" (site) המייצגים את האתרים של מודל Ising, והקיוביטים הלא מוצללים הם קיוביטי "קשר" (bond) המשמשים לתיווך אינטראקציות בין קיוביטי האתר.
- כל קיוביט אתר מסומן כ-(A) או (B), המציין אחד משני תפקידים שקיוביט אתר יכול למלא בפרוטוקול GEM (התפקידים מוסברים מאוחר יותר).
- כל קצה צבוע באחד משישה צבעים, ובכך מחלק את הקצוות לשש קבוצות. חלוקה זו קובעת כיצד ניתן לבצע שערים דו-קיוביטיים במקביל, כמו גם תבניות תזמון שונות שסביר שיגרמו לכמויות שונות של שגיאה על מעבד קוונטי רועש. מכיוון שקצוות בקבוצה זרים, ניתן להחיל שכבת שערים דו-קיוביטיים על אותם קצוות בו-זמנית. למעשה, ניתן לחלק את ששת הצבעים לשלוש קבוצות של שני צבעים כך שהאיחוד של כל קבוצה של שני צבעים עדיין זר. לכן, יש צורך רק בשלוש שכבות של שערים דו-קיוביטיים כדי להפעיל כל קצה. ישנן 12 דרכים לחלק את ששת הצבעים כך, וכל חלוקה כזו מניבה לוח זמנים שונה של 3 שכבות שערים.
כעת לאחר שיצרתם סריג פלאקטות, השלב הבא הוא לאתחל אובייקט GemExperiment, תוך העברת סריג הפלאקטות וה-backend שבו אתם מתכננים להריץ את הניסוי. המחלקה GemExperiment מנהלת את המימוש בפועל של פרוטוקול GEM, כולל יצירת מעגלים, הגשת עבודות וניתוח הנתונים. תא הקוד הבא מאתחל את מחלקת הניסוי תוך הגבלת סריג הפלאקטות לפלאקט בודד (12 קיוביטים), מה שמשאיר את הסימולציה קטנה ומהירה. הסריג המלא של הפלאקטות משמש מאוחר יותר כשמגדילים את הניסוי לחומרה אמיתית.
# Filter the plaquette lattice down to a single plaquette (12 qubits)
# so the AerSimulator run stays fast. The full lattice is used later
# in the large-scale hardware example.
gem_exp = GemExperiment(plaquette_lattice.filter([9]), backend=aer_backend)
# visualize the plaquette lattice after filtering
plaquette_lattice.filter([9]).draw_qubits()
מעגל פרוטוקול GEM נבנה באמצעות השלבים הבאים:
- הכנת מצב all- על ידי החלת שער Hadamard על כל קיוביט.
- החלת שער בין כל זוג קיוביטים מחוברים. ניתן להשיג זאת באמצעות שלוש שכבות של שערים. כל שער פועל על קיוביט אתר וקיוביט קשר. אם קיוביט האתר מסומן (B), אז הזווית קבועה ל-. אם קיוביט האתר מסומן (A), אז הזווית מורשית להשתנות, ומייצרת מעגלים שונים. כברירת מחדל, טווח הזוויות מוגדר ל-21 נקודות מרווחות שווה בין ל-, כולל.
- מדידת כל קיוביט קשר בבסיס Pauli . מכיוון שקיוביטים נמדדים בבסיס Pauli , ניתן לבצע זאת על ידי החלת שער Hadamard לפני מדידת הקיוביט.
שימו לב שהמאמר המצוטט בהקדמה למדריך זה משתמש באמנה שונה לזווית , השונה מהאמנה המשמשת במדריך זה בפקטור של 2.
בשלב שלוש, רק קיוביטי הקשר נמדדים. כדי להבין באיזה מצב נשארים קיוביטי האתר, מועיל לשקול את המקרה שבו זווית המוחלת על קיוביטי אתר (A) בשלב שתיים שווה ל-. במקרה זה, קיוביטי האתר נשארים במצב משולב קוונטית מאוד הדומה למצב GHZ,
בשל האקראיות בתוצאות המדידה, המצב בפועל של קיוביטי האתר עשוי להיות מצב שונה עם סדר ארוך טווח, לדוגמה, . עם זאת, ניתן לשחזר את מצב GHZ על ידי החלת פעולת פענוח המבוססת על תוצאות המדידה. כאשר זווית מכוונת כלפי מטה מ-, ניתן עדיין לשחזר את הסדר ארוך הטווח עד לזווית קריטית, שבהיעדר רעש, היא בקירוב . מתחת לזווית זו, המצב המתקבל כבר אינו מציג שזירה ארוכת טווח. מעבר זה בין נוכחות והיעדר סדר ארוך טווח הוא מעבר הפאזה של Nishimori.
בתיאור לעיל, קיוביטי האתר נותרו ללא מדידה, וניתן לבצע את פעולת הפענוח על ידי החלת שערים קוונטיים. בניסוי כפי שמיושם בחבילת GEM, קיוביטי האתר נמדדים למעשה, ופעולת הפענוח מוחלת בשלב עיבוד קלאסי לאחר מכן.
בתיאור לעיל, ניתן לבצע את פעולת הפענוח על ידי החלת שערים קוונטיים על קיוביטי האתר כדי לשחזר את המצב הקוונטי. עם זאת, אם המטרה היא למדוד מיד את המצב (לדוגמה, למטרות אפיון), אז ניתן למדוד את קיוביטי האתר יחד עם קיוביטי הקשר, ולהחיל את פעולת הפענוח בשלב עיבוד קלאסי לאחר מכן.
בנוסף להיותו תלוי בזווית בשלב שתיים, שכברירת מחדל סוקרת 21 ערכים, מעגל פרוטוקול GEM תלוי גם בתבנית התזמון המשמשת ליישום שלוש שכבות שערי . כפי שנדון קודם לכן, ישנן 12 תבניות תזמון כאלה. לכן, המספר הכולל של מעגלים בניסוי הוא .
ניתן ליצור את המעגלים של הניסוי באמצעות המתודה circuits של המחלקה GemExperiment.
circuits = gem_exp.circuits()
print(f"Total number of circuits: {len(circuits)}")
Total number of circuits: 252
למטרות מדריך זה, מספיק לשקול רק תבנית תזמון בודדת. תא הקוד הבא מגביל את הניסוי לתבנית התזמון הראשונה. כתוצאה מכך, לניסוי יש רק 21 מעגלים, אחד לכל זווית שעליה סורקים.
# 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]
תא הקוד הבא מצייר דיאגרמה של המעגל באינדקס 5. כדי לצמצם את גודל הדיאגרמה, שערי המדידה בסוף המעגל מוסרים.
# 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)
שלב 2: אופטימיזציה של הבעיה עבור הרצה על חומרה קוונטית
Transpiling של מעגלים קוונטיים להרצה על חומרה בדרך כלל כרוך במספר שלבים. בדרך כלל, השלבים הכרוכים בעומס חישובי רב ביותר הם בחירת פריסת הקיוביטים, ניתוב השערים הדו-קיוביטיים כדי להתאים לקישוריות הקיוביטים של החומרה, ואופטימיזציה של המעגל כדי למזער את ספירת השערים והעומק שלו. בפרוטוקול GEM, שלבי הפריסה והניתוב אינם נחוצים מכיוון שהקישוריות של החומרה כבר משולבת בעיצוב הפרוטוקול. למעגלים כבר יש פריסת קיוביטים, והשערים הדו-קיוביטיים כבר ממופים על חיבורים מקוריים. יותר מכך, כדי לשמר את המבנה של המעגל בזמן שינוי זווית , יש לבצע רק אופטימיזציה בסיסית מאוד של המעגל.
המחלקה GemExperiment מבצעת transpile במעגלים בשקיפות בזמן ביצוע הניסוי. שלבי הפריסה והניתוב כבר מוחלפים כברירת מחדל כך שלא יעשו דבר, ואופטימיזציה של המעגל מבוצעת ברמה שמטפלת רק בשערים חד-קיוביטיים. עם זאת, ניתן לעקוף או להעביר אפשרויות נוספות באמצעות המתודה set_transpile_options. למטרות הדמיה, תא הקוד הבא מבצע transpile ידני למעגל שהוצג קודם לכן, ומצייר את המעגל ה-transpiled.
# 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=aer_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)
שלב 3: הרצה באמצעות Qiskit primitives
כדי להריץ את מעגלי פרוטוקול GEM על החומרה, קראו למתודה run של אובייקט GemExperiment. ניתן לציין את מספר ה-shots שברצונכם לדגום מכל מעגל. המתודה run מחזירה אובייקט ExperimentData שכדאי לשמור במשתנה. שימו לב שהמתודה run רק מגישה עבודות מבלי לחכות שהן יסתיימו, ולכן זוהי קריאה לא חוסמת.
exp_data = gem_exp.run(shots=10_000)
כדי לחכות לתוצאות, קראו למתודה block_for_results של אובייקט ExperimentData. קריאה זו תגרום למפרש להיתלות עד שהעבודות יסתיימו.
# The noiseless AerSimulator produces zero-variance UFloat objects in the
# analysis, which triggers a harmless warning from the `uncertainties`
# library. Suppress it so the output stays clean.
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore", message="Using UFloat objects with std_dev==0"
)
exp_data.block_for_results()
exp_data
ExperimentData(GemExperiment, 90bf2a90-f729-4c4e-a6da-664aecb11039, job_ids=['04a7c405-47fd-46ca-aa4b-aaf7e339cfbe'], metadata=<5 items>, figure_names=['two_point_correlation.svg', 'normalized_variance.svg', 'plaquette_ops.svg', 'bond_ops.svg'])
שלב 4: עיבוד לאחר והחזרת תוצאה בפורמט קלאסי רצוי
בזווית של , המצב המפוענח יהיה מצב GHZ בהיעדר רעש. ניתן לדמיין את הסדר ארוך הטווח של מצב GHZ על ידי שרטוט המגנטיזציה של מחרוזות הביטים הנמדדות. המגנטיזציה מוגדרת כסכום של אופרטורי Pauli חד-קיוביטיים,
כאשר הוא מספר קיוביטי האתר. הערך שלה עבור מחרוזת ביטים שווה להפרש בין מספר האפסים ומספר האחדים. מדידת מצב GHZ מניבה את מצב כל האפסים או את מצב כל האחדים בהסתברות שווה, כך שהמגנטיזציה תהיה מחצית מהזמן ו- את המחצית האחרת. בנוכחות שגיאות עקב רעש, ערכים אחרים יופיעו גם כן, אך אם הרעש אינו גדול מדי, ההתפלגות עדיין תהיה מרוכזת ליד ו-.
עבור מחרוזות הביטים הגולמיות לפני הפענוח, התפלגות המגנטיזציה תהיה שווה ערך לזו של מחרוזות ביטים אקראיות אחידות, בהיעדר רעש.
תא הקוד הבא מצייר את המגנטיזציה של מחרוזות הביטים הגולמיות ומחרוזות הביטים המפוענחות בזווית של .
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')
כדי לאפיין בצורה קפדנית יותר את הסדר ארוך הטווח, ניתן לבחון את קורלציית שתי הנקודות הממוצעת , המוגדרת כ-
ערך גבוה יותר מצביע על דרגת שזירה גדולה יותר. המחלקה GemExperiment מחשבת אוטומטית ערך זה עבור מחרוזות הביטים המפוענחות כחלק מעיבוד נתוני הניסוי. היא מאחסנת תמונה שניתן לגשת אליה דרך המתודה figure של מחלקת נתוני הניסוי. במקרה זה, שם התמונה הוא two_point_correlation.
exp_data.figure("two_point_correlation")
כדי לקבוע את הנקודה הקריטית של מעבר הפאזה של Nishimori, ניתן להסתכל על השונות המנורמלת של , המוגדרת כ-
שמכמתת את כמות התנודה במגנטיזציה בריבוע. ערך זה ממוקסם בנקודה הקריטית של מעבר הפאזה של Nishimori. בהיעדר רעש, הנקודה הקריטית מתרחשת בקירוב . בנוכחות רעש, הנקודה הקריטית נדחפת גבוה יותר, אך מעבר הפאזה עדיין נצפה כל עוד הנקודה הקריטית מתרחשת מתחת ל-.
exp_data.figure("normalized_variance")
דוגמה בסקאלה גדולה על חומרה אמיתית
לאחר אימות הפרוטוקול על סימולטור, ניתן כעת להגדיל את הניסוי ולהריץ אותו על backend החומרה הקוונטית האמיתי שנבחר בסעיף הכנה. דוגמה זו משתמשת בשני גדלי בעיה גדולים יותר:
- שש פלאקטות (כ-49 קיוביטים): ריצה בגודל ביניים שכבר מראה את ההזזה ימינה של הנקודה הקריטית תחת רעש חומרה.
- סריג הפלאקטות המלא: כל פלאקט שטופולוגיית ה-heavy-hex של המכשיר תומכת בו (לדוגמה, 18 פלאקטות / 125 קיוביטים על
ibm_torinoאו 21 פלאקטות / 144 קיוביטים עלibm_pittsburgh), ושוזר קיוביטים על פני כל המכשיר עם מעגלים בעומק קבוע.
תא הקוד הבודד למטה הוא עצמאי: הוא בונה את סריג הפלאקטות ממפת הצימוד של ה-backend ומריץ את שני הניסויים, כך שניתן להריץ סעיף זה לאחר תאי הכנה מבלי להריץ תחילה את הסעיף הקטן-בסקאלה.
# -------------------------Step 1-------------------------
# Initialize the runtime service, pick a real quantum hardware backend,
# and build the plaquette lattice from its coupling map. This is repeated
# from the small-scale example so this cell can run standalone after the
# Setup section. The full plaquette lattice is the "large-scale" target;
# a six-plaquette subset (range(3, 9)) is also used to show an intermediate
# scaling step.
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
plaquette_lattice = PlaquetteLattice.from_coupling_map(backend.coupling_map)
# Build a GemExperiment for the full plaquette lattice and one for the
# six-plaquette subset, each restricted to a single scheduling pattern so
# the experiment has one circuit per RZZ angle (21 circuits total).
gem_exp_full = GemExperiment(plaquette_lattice, backend=backend)
gem_exp_full.set_experiment_options(schedule_idx=0)
gem_exp_6 = GemExperiment(
plaquette_lattice.filter(range(3, 9)), backend=backend
)
gem_exp_6.set_experiment_options(schedule_idx=0)
circuits = gem_exp_full.circuits()
print(f"Total number of circuits (full lattice): {len(circuits)}")
# -------------------------Step 2-------------------------
# GemExperiment transpiles internally for the target backend: the layout
# and routing stages are overridden because the plaquette lattice already
# matches the hardware connectivity, and optimization is restricted so the
# RZZ angle structure is preserved. The code below manually transpiles one
# circuit from the six-plaquette experiment with the same settings this
# experiment will use, and draws it for inspection. (The full-lattice
# transpiled circuit has too many qubits to visualize cleanly, so the
# six-plaquette circuit is used here as a representative example.)
gem_exp_6.set_transpile_options(optimization_level=1)
circuits_6 = gem_exp_6.circuits()
pass_manager = generate_preset_pass_manager(
backend=backend,
initial_layout=list(gem_exp_6.physical_qubits),
**dict(gem_exp_6.transpile_options),
)
transpiled = pass_manager.run(circuits_6[5])
display(transpiled.draw("mpl", idle_wires=False, fold=-1, scale=0.5))
# -------------------------Step 3-------------------------
# Run both problem sizes on real hardware:
# 1. Six plaquettes (~49 qubits) — an intermediate scale-up.
# 2. The full plaquette lattice — every plaquette the device supports.
exp_data_6 = gem_exp_6.run(shots=10_000, job_tags=["TUT_NPT"])
exp_data_full = gem_exp_full.run(shots=10_000, job_tags=["TUT_NPT"])
exp_data_6.block_for_results()
exp_data_full.block_for_results()
# -------------------------Step 4-------------------------
# Plot the normalized variance at each scale. The peak marks the critical
# point of the Nishimori transition; as the system grows, hardware noise
# shifts the peak rightward.
display(exp_data_6.figure("normalized_variance"))
exp_data_full.figure("normalized_variance")
Total number of circuits (full lattice): 21

שימו לב שבהתאם לרמת הרעש של ה-backend שנמשך, עקומות השונות המנורמלת בגדלים הגדולים יותר עשויות שלא להראות שיא ברור בטווח הזוויות שנסרק. בריצות לעיל, השיא נדחף כל הדרך עד , הקצה הימני של הסריקה (הניתוח מדווח critical_angle = 0.5000 הן לריצות שש הפלאקטות והן לריצות הסריג המלא). זה אומר שרעש החומרה דחף את הנקודה הקריטית עד (או ממש מעבר ל) גבול טווח הזוויות הפיזיקלי הבעל משמעות של הפרוטוקול, כך שהמעבר נמצא בשולי מה שסריקה זו יכולה לפתור.
סיכום
במדריך זה, הגשמתם מעבר פאזה של Nishimori על מעבד קוונטי באמצעות פרוטוקול GEM. המדדים שבדקתם במהלך העיבוד לאחר מכן — במיוחד קורלציית שתי הנקודות והשונות המנורמלת — משמשים כמדדי ייחוס של יכולת המכשיר ליצור מצבים משולבים קוונטית ארוכי טווח. מדדי ייחוס אלו מרחיבים את התועלת של פרוטוקול GEM מעבר לחקר פיזיקה מעניינת. כחלק מהפרוטוקול, שזרתם קוונטית קיוביטים על פני כל המכשיר באמצעות מעגלים בעומק קבוע בלבד. הישג זה אפשרי רק בשל השימוש של הפרוטוקול במדידות אמצע-מעגל. בניסוי זה, המצב המשולב קוונטית נמדד מיד, אך שקלו לחקור עוד על ידי שימוש במצב זה בעיבוד קוונטי נוסף.
צעדים הבאים
אם מצאתם עבודה זו מעניינת, ייתכן שתתעניינו בחומר הבא:
מקורות
[1] E. H. Chen, G.-Y. Zhu, R. Verresen, A. Seif, E. Bäumer, D. Layden, N. Tantivasadakarn, G. Zhu, S. Sheldon, A. Vishwanath, S. Trebst, A. Kandala. Realizing the Nishimori transition across the error threshold for constant-depth quantum circuits. arXiv:2309.02863 (2023).
[2] GEM Suite software package.