Перейти до основного вмісту
Цей проєкт у бета-версії. Знайшов(-ла) помилку? Відкрити issue на GitHub. Є запитання чи ідея? Запитати в Discussions — будемо раді твоєму відгуку!
Яка якість перекладу на цій сторінці?

Dynamics Simulator - Qiskit Function від Q-CTRL Fire Opal

Див. довідник API.

примітка

Qiskit Functions є експериментальною функцією, доступною лише користувачам планів IBM Quantum® Premium Plan, Flex Plan та On-Prem (через IBM Quantum Platform API). Вони перебувають у статусі попереднього випуску та можуть змінюватися.

Огляд​

Q-CTRL Dynamics Simulator є прикладною Qiskit Function для симулювання часової еволюції підтримуваних квантових моделей багатьох тіл на обладнанні IBM Quantum. Замість того щоб будувати квантові схеми самостійно, ти вказуєш фізичну модель, початковий стан, параметри часової еволюції та observable, які потрібно виміряти.

Функція будує та виконує потрібні динамічні схеми й застосовує апаратно-орієнтовану оптимізацію Fire Opal та робочий процес придушення помилок. Результатом є часова траса очікуваних значень запитаних тобою observable. Оскільки функція застосовує придушення помилок автоматично, ти можеш запускати схеми з рекордною глибиною й усе одно бачити змістовні сигнали. Dynamics Simulator забезпечує точність розв'язку, що збігається з наявними передовими класичними інструментами, і дає демонстровану перевагу у швидкості.

Реальне тестування досягло узгодженості в межах 1% середньоквадратичної похибки (RMSE) порівняно з класичними симуляціями тензорних мереж найвищої роздільності. Незалежні тести дослідницької спільноти підтвердили, що квантовий комп'ютер залишається точним навіть за межами початкових демонстрацій Q-CTRL.

Two plots of classical tensor-network simulations at bond dimensions χ from 64 to 4096. The left plot shows the RMSE against time t, which stays near 0.01 until it rises sharply, later for larger bond dimensions. The right plot shows the simulation time in minutes against time t on a logarithmic scale, which increases with bond dimension.

Бенчмарки​

Кількість вузлів ґратки визначає, скільки потрібно кубітів, тоді як кількість кроків Троттера керує глибиною схем часової еволюції. Кожен вузол ґратки використовує два кубіти для подання заповнень зі спіном угору та спіном униз.

Цей робочий процес було продемонстровано для ланцюжків із 60 вузлів (120 кубітів) з 30 кроками Троттера та для ланцюжків із 31 вузла (62 кубіти) з 90 кроками Троттера. У таблиці нижче показано ресурси схем і час виконання на QPU із повідомлених експериментів, виконаних на пристрої IBM® Heron r3 (ibm_boston) з 20 000 шотів на схему.

Розмір системиКроки ТроттераДвокубітна глибинаКількість двокубітних гейтівЧас QPUЧас QPU з REM + DR
10 вузлів (20 кубітів)301521,4572m 46s4m 25s
10 вузлів (20 кубітів)603022,8975m 36s8m 42s
10 вузлів (20 кубітів)904524,3378m 46s13m 26s
31 вузол (62 кубіти)301524,6492m 46s4m 25s
31 вузол (62 кубіти)603029,2395m 36s8m 42s
31 вузол (62 кубіти)9045213,8298m 46s13m 26s
60 вузлів (120 кубітів)301529,0572m 46s4m 25s

Для фіксованої кількості кроків Троттера повідомлена глибина схеми та час QPU залишаються однаковими для всіх протестованих розмірів системи, тоді як кількість двокубітних гейтів зростає. Збільшення кількості кроків дає глибші схеми та потребує більше часу QPU.

Тут час QPU є сукупним часом виконання на обладнанні для основних схем симулювання. Останній стовпець також включає час QPU для характеризації шуму, що використовується в пом'якшенні помилок зчитування (REM) та відновленні після розпаду (DR). Цей посібник використовує невеликий одновимірний приклад Фермі-Габбарда, щоб показати повний робочий процес від визначення моделі до побудови графіка виміряної динаміки.

Опис функції​

Квантова динаміка описує, як квантова система змінюється з часом. Вивчення цієї еволюції допомагає зрозуміти, як рухаються частинки, як розвиваються кореляції та як система реагує на зміну свого стану чи гамільтоніана.

Модель Фермі-Габбарда описує ферміони, що переміщуються між вузлами ґратки та взаємодіють, коли займають один і той самий вузол. Конкуренція між стрибками та взаємодіями робить її корисною моделлю для вивчення сильно корельованих електронів. Її часова еволюція може показати, як поширюються спін і заряд та як релаксує початково впорядкована система.

Модель​

Dynamics Simulator підтримує одновимірний ланцюжок Фермі-Габбарда з відкритими межами. Для ланцюжка з LL вузлів гамільтоніан визначається так:

H=−∑i=0L−2∑σ∈{↑,↓}th,i(ciσ†ci+1,σ+ci+1,σ†ciσ)+∑i=0L−1Uini↑ni↓−∑i=0L−1∑σ∈{↑,↓}μiniσ.H = -\sum_{i=0}^{L-2}\sum_{\sigma\in\{\uparrow,\downarrow\}} t_{h,i} \left( c^\dagger_{i\sigma}c_{i+1,\sigma} + c^\dagger_{i+1,\sigma}c_{i\sigma} \right) +\sum_{i=0}^{L-1}U_i n_{i\uparrow}n_{i\downarrow} -\sum_{i=0}^{L-1}\sum_{\sigma\in\{\uparrow,\downarrow\}} \mu_i n_{i\sigma}.

Тут ciσ†c^\dagger_{i\sigma} і ciσc_{i\sigma} створюють і знищують ферміон зі спіном σ\sigma у вузлі ii. Оператор числа niσ=ciσ†ciσn_{i\sigma}=c^\dagger_{i\sigma}c_{i\sigma} вимірює заповнення цієї спін-орбіталі.

Вхідні дані моделі задають такі коефіцієнти:

  • hopping_amplitude: th,it_{h,i}, що керує стрибками між сусідніми вузлами ii та i+1i+1.

  • on_site_interaction: UiU_i, взаємодія між ферміонами зі спіном угору та спіном униз, що займають один і той самий вузол.

  • chemical_potential: μi\mu_i, локальний хімічний потенціал, який входить до гамільтоніана зі знаком мінус.

Передай скаляр, щоб використати той самий коефіцієнт у всьому ланцюжку, або список, щоб задати коефіцієнти для окремих зв'язків чи вузлів.

В одиницях, де ℏ=1\hbar=1, початковий стан еволюціонує так:

∣ψ(t)⟩=e−iHt∣ψ(0)⟩.|\psi(t)\rangle=e^{-iHt}|\psi(0)\rangle.

Функція оцінює очікувані значення вказаних тобою observable в послідовні моменти часу симулювання.

Робочий процес​

Робочий процес функції складається з таких кроків:

  1. Алгоритмічний синтез: функція використовує гамільтоніан і налаштування часу симуляції, щоб побудувати оптимізовану послідовність Троттера-Сузукі, яка зменшує глибину схеми з урахуванням точності симуляції.

  2. Відображення з урахуванням апаратного забезпечення: функція відображає й маршрутизує схеми, використовуючи зв'язність кубітів і характеристики помилок вибраного бекенда IBM Quantum.

  3. Придушення помилок на фізичному рівні: Fire Opal застосовує динамічне розв'язування та корекції на рівні імпульсів, щоб придушити шум від середовища та перехресні завади під час виконання на обладнанні.

Функція керує цими етапами автоматично та повертає з часом очікувані значення запитаних спостережуваних.

Ти задаєш фізичну задачу та налаштування симуляції через вхідні дані функції. Поточний інтерфейс підтримує еволюцію за часом за методом Троттера, де time_step задає тривалість кожного кроку, а step_count задає кількість кроків.

Додаткові відомості дивись в огляді симулятора динаміки Fire Opal і в довіднику API simulate_dynamics.

Початок роботи​

Інформацію про доступ до цієї функції Qiskit знайдеш у каталозі Qiskit Functions.

Цей посібник показує, як завантажити Dynamics Simulator і змоделювати чотирьохвузловий ланцюжок Фермі-Хаббарда. Наведений нижче код припускає, що ти вже зберіг свій ключ API IBM Quantum Platform і CRN екземпляра у локальному середовищі.

Інструкції з налаштування облікового запису та встановлення клієнта дивись у розділі Початок роботи з Qiskit Functions.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"matplotlib": "matplotlib", "numpy": "numpy", "qctrlvisualizer": "qctrlvisualizer", "qiskit_ibm_catalog": "qiskit-ibm-catalog"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
# Access the Q-CTRL Dynamics Simulator Qiskit Function.
sim_qf = catalog.load("q-ctrl/dynamics-simulator")
# Check the list of backends you have access to
catalog.backends()
[<IBMBackend('ibm_boston')>,
<IBMBackend('ibm_fez')>,
<IBMBackend('ibm_kingston')>,
<IBMBackend('ibm_marrakesh')>,
<IBMBackend('ibm_miami')>,
<IBMBackend('ibm_phoenix')>,
<IBMBackend('ibm_pittsburgh')>]
# Select the backend you want to use
backend = catalog.backend("ibm_phoenix")

Приклад: симуляція чотирьохвузлового ланцюжка Фермі-Хаббарда​

Розглянь чотирьохвузловий одновимірний ланцюжок Фермі-Хаббарда з амплітудою стрибка th=1t_h=1, без взаємодії на вузлі та з нульовим хімічним потенціалом. Один ферміон зі спіном угору починає з вузла 0 і еволюціонує вздовж ланцюжка.

Ця невелика задача зосереджує увагу на робочому процесі Dynamics Simulator:

  1. Визнач модель і симуляцію.

  2. Визнач початковий стан і спостережувані.

  3. Надішли завдання Qiskit Function.

  4. Отримай очікувані значення.

  5. Побудуй графік динаміки.

1. Визнач задачу​

site_count = 4

model = {
"hopping_amplitude": 1.0,
"on_site_interaction": 0.0,
"chemical_potential": 0.0,
}

simulation = {
"time_step": 0.2,
"step_count": 8,
}

initial_state = "eeeu"

observables = [
{
"operators": [[["Nup", site]]],
"coefficients": [1.0],
}
for site in range(site_count)
]

shot_count = 2048

Список спостережуваних вимірює заселеність зі спіном угору

⟨ni↑⟩\langle n_{i\uparrow} \rangle

на кожному вузлі. Спостережувані повертаються в тому самому порядку, в якому вони були передані.

2. Запусти симуляцію динаміки​

Надішли задачу через Qiskit Function. Каталог Qiskit Functions обробляє автентифікацію IBM Quantum, тому тобі не потрібно передавати до sim_qf.run() окремі облікові дані Fire Opal чи постачальника обладнання.

job = sim_qf.run(
model=model,
simulation=simulation,
observables=observables,
initial_state=initial_state,
shots=shot_count,
backend_name=backend.name,
)
print(job.job_id, job.status())
68202fad-6919-425d-8fd2-c1c649cd15b1 DONE

Повернений об'єкт є завданням Qiskit Function. Ти можеш зберегти ідентифікатор завдання, щоб пізніше отримати або переглянути робоче навантаження.

3. Отримай результат​

result = job.result()

print("Result keys:", sorted(result.keys()))
print("Warnings:", result.get("warnings", []))
Result keys: ['metadata', 'observable_expectation_values', 'observables', 'warnings']
Warnings: []

Перетвори очікувані значення спостережуваних на масив NumPy. Кожен рядок відповідає одній спостережуваній, а кожен стовпець відповідає записаному моменту часу симуляції, починаючи з t=0t=0. У цьому прикладі чотири рядки містять заселеності вузлів 0–3 зі спіном угору.

import numpy as np

expectation_values = np.asarray(
result["observable_expectation_values"],
dtype=float,
)

print("Expectation-value array shape:", expectation_values.shape)
Expectation-value array shape: (4, 9)

4. Візуалізуй динаміку​

Початковий стан містить один ферміон зі спіном угору і жодного зі спіном униз. Тому його еволюція залишається в одночастинковому підпросторі, чотири базисні стани якого відповідають ферміону на вузлах 0, 1, 2 і 3.

У цьому підпросторі гамільтоніан з'єднує сусідні вузли з амплітудою стрибка −th-t_h. Для використаних тут параметрів

H1p=−th(0100101001010010).H_{\mathrm{1p}} = -t_h \begin{pmatrix} 0 & 1 & 0 & 0 \\ 1 & 0 & 1 & 0 \\ 0 & 1 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{pmatrix}.

Діагоналізуй цю матрицю за допомогою NumPy та еволюціонуй початковий стан у ті самі моменти часу, які повернув Dynamics Simulator. Квадрат модуля амплітуди кожного стану дає заселеність відповідного вузла зі спіном угору.

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

times = np.arange(expectation_values.shape[1]) * simulation["time_step"]

# This reference is specific to a single spin-up fermion.
if (
len(initial_state) != site_count
or initial_state.count("u") != 1
or initial_state.count("e") != site_count - 1
):
raise ValueError(
"This reference requires one spin-up fermion and otherwise empty sites."
)

# Build the Hamiltonian in the single-particle subspace.
hamiltonian = -model["hopping_amplitude"] * (
np.eye(site_count, k=1) + np.eye(site_count, k=-1)
)
hamiltonian -= model["chemical_potential"] * np.eye(site_count)

# The rightmost character of initial_state corresponds to site 0.
initial_amplitudes = np.zeros(site_count, dtype=complex)
initial_site = initial_state[::-1].index("u")
initial_amplitudes[initial_site] = 1.0

# Evolve the initial state in the Hamiltonian eigenbasis.
energies, eigenvectors = np.linalg.eigh(hamiltonian)
initial_coefficients = eigenvectors.conj().T @ initial_amplitudes

phases = np.exp(-1j * np.outer(energies, times))
states = eigenvectors @ (initial_coefficients[:, None] * phases)

ideal_expectation_values = np.abs(states) ** 2

Побудуй по одній панелі для кожного вузла. Суцільні криві показують точний еталон у записані моменти часу, а маркери показують оцінки з обладнання, повернуті Dynamics Simulator.

import matplotlib.pyplot as plt
import qctrlvisualizer as qv
from qctrlvisualizer import QCTRL_STYLE_COLORS as colors

plt.style.use(qv.get_qctrl_style())

fig, ax = plt.subplots(figsize=(10, 6))

for site in range(len(expectation_values)):
site_color = colors[site % len(colors)]

ax.plot(
times,
ideal_expectation_values[site],
color=site_color,
linewidth=2,
label=f"Site {site}: exact reference",
)

ax.plot(
times,
expectation_values[site],
color=site_color,
linestyle="--",
linewidth=1.5,
marker="o",
markersize=5,
label=f"Site {site}: hardware estimate",
)

ax.set_xlim(times[0], times[-1])
ax.set_ylim(-0.05, 1.05)

ax.set_xlabel(r"Time (units of $\hbar/t_h$)")
ax.set_ylabel(r"$\langle n_{i\uparrow} \rangle$")
ax.set_title("Spin-up occupation dynamics")

ax.legend(
ncol=2,
fontsize=10,
loc="best",
)

fig.tight_layout()
plt.show()

Output of the previous code cell

При t=0t=0 точна заселеність зі спіном угору дорівнює 1 на вузлі 0 і 0 на інших вузлах. Під час еволюції системи стрибки розподіляють ймовірність частинки вздовж ланцюжка. Спершу зростає заселеність вузла 1, а потім зростає заселеність вузлів 2 і 3. Для параметрів у цьому прикладі останній записаний момент часу дорівнює t=1.6t=1.6. Точні заселеності вузлів 0–3 становлять приблизно 0.026, 0.370, 0.392 і 0.211 відповідно.

Точні заселеності в кожен момент часу задовольняють таке рівняння, що відображає збереження кількості частинок:

∑i=03⟨ni↑(t)⟩=1\sum_{i=0}^{3}\langle n_{i\uparrow}(t)\rangle=1

Заселеності окремих вузлів можуть зростати й спадати, поки частинка еволюціонує вздовж скінченного ланцюжка.

Отримання повідомлень про помилки​

Якщо робоче навантаження переходить у стан ERROR, викличи job.result(), щоб отримати повідомлення про помилку. Також можеш переглянути журнали функції, якщо вони доступні.

print(job.status())

if job.status() == "ERROR":
print(job.result())
print(job.logs())
DONE

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

Отримання підтримки​

З питань щодо Dynamics Simulator чи поведінки Fire Opal дивись документацію Q-CTRL або зв'яжись із Q-CTRL.

З питань автентифікації Qiskit Functions, керування завданнями або доступу до IBM Quantum Platform дивись документацію Qiskit Functions.

Наступні кроки​

Рекомендації
  • Ознайомся з довідником API simulate_dynamics, щоб побачити визначення базової моделі, симуляції, спостережуваних, виводу та перевірки.
  • Спробуй навчальний посібник Динаміка спіну та заряду в моделі Фермі-Хаббарда.
  • Прочитай огляд симулятора динаміки Fire Opal, щоб дізнатися більше про тротеризацію, відображення з урахуванням апаратного забезпечення та придушення помилок Fire Opal.
  • Змінюй параметри моделі, початковий стан, крок за часом, кількість кроків і спостережувані, щоб дослідити іншу задачу одновимірної динаміки Фермі-Хаббарда.