Перейти до основного вмісту

Фазовий перехід Нішіморі

Оцінка використання: 3 хвилини на процесорі Heron r2 (ПРИМІТКА: Це лише оцінка. Ваш час виконання може відрізнятися.)

Передумови

Цей посібник демонструє, як реалізувати фазовий перехід Нішіморі на квантовому процесорі IBM®. Цей експеримент було спочатку описано в роботі Realizing the Nishimori transition across the error threshold for constant-depth quantum circuits.

Фазовий перехід Нішіморі стосується переходу між фазами з далекодіючим та короткодіючим порядком у моделі Ізінга з випадковими зв'язками. На квантовому комп'ютері фаза з далекодіючим порядком проявляється як стан, у якому кубіти заплутані по всьому пристрою. Цей сильно заплутаний стан підготовлюється за допомогою протоколу генерації заплутаності вимірюванням (GEM). Використовуючи вимірювання всередині схеми, протокол GEM здатний заплутувати кубіти по всьому пристрою за допомогою схем лише сталої глибини. У цьому посібнику використовується реалізація протоколу GEM із програмного пакету GEM Suite.

Вимоги

Перш ніж починати цей посібник, переконайся, що у тебе встановлено наступне:

  • Qiskit SDK v1.0 або новіший, з підтримкою візуалізації
  • Qiskit Runtime v0.22 або новіший ( pip install qiskit-ibm-runtime )
  • GEM Suite ( pip install gem-suite )

Налаштування

# 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

Крок 1: Відображення класичних вхідних даних на квантову задачу

Протокол GEM працює на квантовому процесорі зі зв'язністю кубітів, описаною ґраткою. Сучасні квантові процесори IBM використовують ґратку heavy hex. Кубіти процесора групуються в плакетки залежно від того, до якої елементарної комірки ґратки вони належать. Оскільки кубіт може входити до більш ніж однієї елементарної комірки, плакетки не є неперетинними. На ґратці heavy hex плакетка містить 12 кубітів. Самі плакетки також утворюють ґратку, де дві плакетки з'єднані, якщо вони мають спільні кубіти. На ґратці heavy hex сусідні плакетки мають 3 спільних кубіти.

У програмному пакеті GEM Suite фундаментальним класом для реалізації протоколу GEM є PlaquetteLattice, який представляє ґратку плакеток (відмінну від ґратки heavy hex). PlaquetteLattice можна ініціалізувати з карти зв'язності кубітів. Наразі підтримуються лише карти зв'язності heavy hex.

Наступна комірка коду ініціалізує ґратку плакеток із карти зв'язності квантового процесора IBM. Ґратка плакеток не завжди охоплює весь апаратний засіб. Наприклад, ibm_torino має загалом 133 кубіти, але найбільша ґратка плакеток, що вміщується на пристрої, використовує лише 125 з них і складається з 18 плакеток. Подібне можна спостерігати і для пристроїв IBM Quantum® з іншою кількістю кубітів.

# 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

Ви можете візуалізувати ґратку плакеток, згенерувавши діаграму її графового представлення. На діаграмі плакетки представлені позначеними шестикутниками, а дві плакетки з'єднані ребром, якщо вони мають спільні кубіти.

plaquette_lattice.draw_plaquettes()

Output of the previous code cell

Ви можете отримати інформацію про окремі плакетки, наприклад, які кубіти вони містять, за допомогою методу 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])

Ви також можете створити діаграму базових кубітів, які формують ґратку плакеток.

plaquette_lattice.draw_qubits()

Output of the previous code cell

Окрім міток кубітів та ребер, що вказують на з'єднані кубіти, діаграма містить три додаткових елементи інформації, що стосуються протоколу GEM:

  • Кожен кубіт є або зафарбованим (сірим), або незафарбованим. Зафарбовані кубіти — це кубіти «вузлів» (site), які представляють вузли моделі Ізінга, а незафарбовані кубіти — це кубіти «зв'язків» (bond), що використовуються для опосередкування взаємодій між кубітами вузлів.
  • Кожен кубіт вузла позначений або (A), або (B), що вказує на одну з двох ролей, які кубіт вузла може виконувати в протоколі GEM (ролі пояснюються далі).
  • Кожне ребро пофарбоване одним із шести кольорів, що розбиває ребра на шість груп. Це розбиття визначає, як можна розпаралелити двокубітні вентилі, а також різні схеми планування, які, ймовірно, матимуть різну кількість помилок на зашумленому квантовому процесорі. Оскільки ребра в одній групі не перетинаються, шар двокубітних вентилів може бути застосований на цих ребрах одночасно. Фактично, можна розбити шість кольорів на три групи по два кольори так, що об'єднання кожної групи з двох кольорів також буде неперетинним. Тому для активації кожного ребра потрібні лише три шари двокубітних вентилів. Існує 12 способів такого розбиття шести кольорів, і кожне таке розбиття дає інший 3-шаровий розклад вентилів.

Тепер, коли ти створив ґратку плакеток, наступним кроком є ініціалізація об'єкта GemExperiment, передавши як ґратку плакеток, так і бекенд, на якому ти маєш намір запустити експеримент. Клас GemExperiment керує фактичною реалізацією протоколу GEM, включаючи генерацію схем, надсилання завдань та аналіз даних. Наступна комірка коду ініціалізує клас експерименту, обмежуючи ґратку плакеток лише двома плакетками (21 кубіт), зменшуючи розмір експерименту, щоб шум в апаратурі не перекрив сигнал.

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

Схема протоколу GEM будується за такими кроками:

  1. Підготовка стану «всі +|+\rangle» шляхом застосування вентиля Адамара до кожного кубіта.
  2. Застосування вентиля RZZR_{ZZ} між кожною парою з'єднаних кубітів. Це можна досягти за допомогою 3 шарів вентилів. Кожен вентиль RZZR_{ZZ} діє на кубіт вузла та кубіт зв'язку. Якщо кубіт вузла позначений (B), то кут фіксовано на π2\frac{\pi}{2}. Якщо кубіт вузла позначений (A), то кут може змінюватися, створюючи різні схеми. За замовчуванням діапазон кутів встановлюється як 21 рівномірно розподілена точка від 00 до π2\frac{\pi}{2} включно.
  3. Вимірювання кожного кубіта зв'язку в базисі Паулі XX. Оскільки кубіти вимірюються в базисі Паулі ZZ, це можна досягти, застосувавши вентиль Адамара перед вимірюванням кубіта.

Зверніть увагу, що в статті, на яку посилається вступ до цього посібника, використовується інша конвенція для кута RZZR_{ZZ}, яка відрізняється від конвенції, використаної в цьому посібнику, у 2 рази.

У кроці 3 вимірюються лише кубіти зв'язків. Щоб зрозуміти, в якому стані залишаються кубіти вузлів, корисно розглянути випадок, коли кут RZZR_{ZZ}, застосований до кубітів вузлів (A) у кроці 2, дорівнює π2\frac{\pi}{2}. У цьому випадку кубіти вузлів залишаються у сильно заплутаному стані, подібному до стану GHZ,

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

Через випадковість результатів вимірювання фактичний стан кубітів вузлів може бути іншим станом з далекодіючим порядком, наприклад, 00110+11001\lvert 00110 \rangle + \lvert 11001 \rangle. Однак стан GHZ можна відновити, застосувавши операцію декодування на основі результатів вимірювання. Коли кут RZZR_{ZZ} зменшується від π2\frac{\pi}{2}, далекодіючий порядок все ще можна відновити аж до критичного кута, який за відсутності шуму становить приблизно 0.3π0.3 \pi. Нижче цього кута результуючий стан більше не демонструє далекодіючу заплутаність. Цей перехід між наявністю та відсутністю далекодіючого порядку і є фазовим переходом Нішіморі.

В описі вище кубіти вузлів залишалися невиміряними, і операція декодування може бути виконана застосуванням квантових вентилів. В експерименті, реалізованому в GEM Suite, якого дотримується цей посібник, кубіти вузлів фактично вимірюються, а операція декодування застосовується на етапі класичної постобробки.

В описі вище операція декодування може бути виконана застосуванням квантових вентилів до кубітів вузлів для відновлення квантового стану. Однак, якщо метою є негайне вимірювання стану, наприклад, для цілей характеризації, тоді кубіти вузлів вимірюються разом з кубітами зв'язків, і операція декодування може бути застосована на етапі класичної постобробки. Саме так експеримент реалізовано в GEM Suite, якого дотримується цей посібник.

Окрім залежності від кута RZZR_{ZZ} у кроці 2, який за замовчуванням охоплює 21 значення, схема протоколу GEM також залежить від шаблону планування, що використовується для реалізації 3 шарів вентилів RZZR_{ZZ}. Як обговорювалося раніше, існує 12 таких шаблонів планування. Тому загальна кількість схем в експерименті становить 21×12=25221 \times 12 = 252.

Схеми експерименту можна згенерувати за допомогою методу circuits класу GemExperiment.

circuits = gem_exp.circuits()
print(f"Total number of circuits: {len(circuits)}")
Total number of circuits: 252

Для цілей цього посібника достатньо розглянути лише один шаблон планування. Наступна комірка коду обмежує експеримент першим шаблоном планування. У результаті експеримент має лише 21 схему, по одній для кожного кута RZZR_{ZZ}.

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

Output of the previous code cell

Крок 2: Оптимізація задачі для виконання на квантовому обладнанні

Трансляція квантових схем для виконання на обладнанні зазвичай включає кілька етапів. Як правило, етапи, що потребують найбільших обчислювальних витрат, — це вибір розташування кубітів, маршрутизація двокубітних вентилів відповідно до зв'язності кубітів обладнання та оптимізація схеми для мінімізації кількості вентилів та глибини. У протоколі GEM етапи розташування та маршрутизації є непотрібними, оскільки зв'язність обладнання вже враховано в дизайні протоколу. Схеми вже мають розташування кубітів, а двокубітні вентилі вже відображені на нативні з'єднання. Крім того, для збереження структури схеми при зміні кута RZZR_{ZZ} слід виконувати лише дуже базову оптимізацію схеми.

Клас GemExperiment прозоро транслює схеми під час виконання експерименту. Етапи розташування та маршрутизації за замовчуванням перевизначені для бездіяльності, а оптимізація схеми виконується на рівні, що оптимізує лише однокубітні вентилі. Однак ти можеш перевизначити або передати додаткові параметри за допомогою методу set_transpile_options. Для цілей візуалізації наступна комірка коду вручну транслює раніше відображену схему та малює трансльовану схему.

# 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

Крок 3: Виконання за допомогою примітивів Qiskit

Для виконання схем протоколу GEM на обладнанні викличте метод run об'єкта GemExperiment. Ти можеш вказати кількість зразків (shots), які потрібно отримати з кожної схеми. Метод run повертає об'єкт ExperimentData, який слід зберегти у змінну. Зверніть увагу, що метод run лише надсилає завдання без очікування їх завершення, тому це неблокуючий виклик.

exp_data = gem_exp.run(shots=10_000)

Щоб дочекатися результатів, викличте метод block_for_results об'єкта ExperimentData. Цей виклик призведе до зависання інтерпретатора до завершення завдань.

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

Крок 4: Постобробка та повернення результату в бажаному класичному форматі

При куті RZZR_{ZZ}, що дорівнює π2\frac{\pi}{2}, декодований стан був би станом GHZ за відсутності шуму. Далекодіючий порядок стану GHZ можна візуалізувати, побудувавши графік намагніченості виміряних бітових рядків. Намагніченість MM визначається як сума однокубітних операторів Паулі ZZ,

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

де NN — кількість кубітів вузлів. Її значення для бітового рядка дорівнює різниці між кількістю нулів та кількістю одиниць. Вимірювання стану GHZ дає стан «всі нулі» або стан «всі одиниці» з рівною ймовірністю, тому намагніченість становитиме +N+N половину часу та N-N іншу половину часу. За наявності помилок через шум також з'являтимуться інші значення, але якщо шум не надто великий, розподіл все ще матиме піки біля +N+N та N-N.

Для необроблених бітових рядків до декодування розподіл намагніченості був би еквівалентним розподілу рівномірно випадкових бітових рядків за відсутності шуму.

Наступна комірка коду будує графік намагніченості необроблених бітових рядків та декодованих бітових рядків при куті RZZR_{ZZ}, що дорівнює π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

Для більш строгої характеризації далекодіючого порядку можна дослідити середню двоточкову кореляцію ff, визначену як

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

Більше значення вказує на більший ступінь заплутаності. Клас GemExperiment автоматично обчислює це значення для декодованих бітових рядків як частину обробки експериментальних даних. Він зберігає графік, доступний через метод figure класу експериментальних даних. У цьому випадку назва графіка — two_point_correlation.

exp_data.figure("two_point_correlation")

Output of the previous code cell

Для визначення критичної точки фазового переходу Нішіморі можна розглянути нормовану дисперсію M2/NM^2 / N, визначену як

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

яка кількісно визначає рівень флуктуацій квадрата намагніченості. Це значення максимізується в критичній точці фазового переходу Нішіморі. За відсутності шуму критична точка знаходиться приблизно при 0.3π0.3 \pi. За наявності шуму критична точка зсувається вище, але фазовий перехід все ще спостерігається, поки критична точка знаходиться нижче 0.5π0.5 \pi.

exp_data.figure("normalized_variance")

Output of the previous code cell

Масштабування експерименту

Наступні комірки коду запускають експеримент для шести плакеток (49 кубітів) та повних 12 плакеток (125 кубітів) і будують графік нормованої дисперсії. При масштабуванні експерименту до більших розмірів більша кількість шуму зсуває критичну точку вправо.

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

Висновок

У цьому посібнику ти реалізував фазовий перехід Нішіморі на квантовому процесорі за допомогою протоколу GEM. Метрики, які ти дослідив під час постобробки, зокрема двоточкова кореляція та нормована дисперсія, слугують еталонними показниками здатності пристрою генерувати стани з далекодіючою заплутаністю. Ці еталонні показники розширюють застосування протоколу GEM за межі дослідження цікавої фізики. У рамках протоколу ти заплутав кубіти по всьому пристрою за допомогою схем лише сталої глибини. Цей подвиг можливий лише завдяки використанню протоколом вимірювань усередині схеми. У цьому експерименті заплутаний стан було одразу виміряно, але цікавим напрямком для дослідження було б продовження використання цього стану в подальшій квантовій обробці!

Опитування щодо посібника

Будь ласка, пройди це коротке опитування, щоб надати відгук про цей посібник. Твої думки допоможуть нам покращити наші матеріали та досвід користувачів.

Посилання на опитування