Przejdź do głównej treści
Ten projekt jest w wersji beta. Znalazłeś błąd? Otwórz zgłoszenie na GitHub. Masz pytanie lub pomysł? Zapytaj w Discussions — chętnie poznamy Twoją opinię!
Jak oceniasz jakość tłumaczenia tej strony?

Dynamics Simulator - Qiskit Function od Q-CTRL Fire Opal

Zobacz dokumentację API.

uwaga

Qiskit Functions to funkcja eksperymentalna dostępna tylko dla użytkowników planów IBM Quantum® Premium, Flex i On-Prem (przez API IBM Quantum Platform). Mają status wersji zapoznawczej i mogą ulec zmianie.

Przegląd​

Dynamics Simulator firmy Q-CTRL to aplikacyjna Qiskit Function do symulacji ewolucji czasowej obsługiwanych kwantowych modeli wielociałowych na sprzęcie IBM Quantum. Zamiast samodzielnie konstruować obwody kwantowe, określasz model fizyczny, stan początkowy, parametry ewolucji czasowej i obserwable do zmierzenia.

Funkcja konstruuje i wykonuje wymagane obwody dynamiczne oraz stosuje przepływ pracy Fire Opal obejmujący optymalizację uwzględniającą sprzęt i tłumienie błędów. Wynikiem jest przebieg czasowy wartości oczekiwanych dla żądanych obserwabli. Ponieważ funkcja stosuje tłumienie błędów automatycznie, możesz uruchamiać obwody o rekordowych głębokościach i nadal widzieć znaczące sygnały. Dynamics Simulator zapewnia dokładność rozwiązań zgodną z istniejącymi najnowocześniejszymi narzędziami klasycznymi i daje wykazalną przewagę w szybkości.

Testy w warunkach rzeczywistych osiągnęły zgodność w granicach 1% błędu średniokwadratowego (RMSE) w porównaniu z klasycznymi symulacjami sieci tensorowych o najwyższej rozdzielczości. Niezależne testy ze społeczności badawczej potwierdziły, że komputer kwantowy pozostaje dokładny nawet poza początkowymi demonstracjami 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.

Testy wydajności​

Liczba węzłów sieci określa, ile kubitów jest potrzebnych, a liczba kroków Trottera kontroluje głębokość obwodów ewolucji czasowej. Każdy węzeł sieci używa dwóch kubitów do reprezentowania obsadzeń ze spinem w górę i w dół.

Ten przepływ pracy zademonstrowano dla łańcuchów o 60 węzłach (120 kubitów) z 30 krokami Trottera oraz dla łańcuchów o 31 węzłach (62 kubity) z 90 krokami Trottera. Poniższa tabela pokazuje zasoby obwodów i czasy wykonania na QPU z zgłoszonych eksperymentów, przeprowadzonych na urządzeniu IBM® Heron r3 (ibm_boston) z 20 000 shotów na obwód.

Rozmiar układuKroki TrotteraGłębokość dwukubitowaLiczba bramek dwukubitowychCzas QPUCzas QPU z REM + DR
10 węzłów (20 kubitów)301521,4572m 46s4m 25s
10 węzłów (20 kubitów)603022,8975m 36s8m 42s
10 węzłów (20 kubitów)904524,3378m 46s13m 26s
31 węzłów (62 kubity)301524,6492m 46s4m 25s
31 węzłów (62 kubity)603029,2395m 36s8m 42s
31 węzłów (62 kubity)9045213,8298m 46s13m 26s
60 węzłów (120 kubitów)301529,0572m 46s4m 25s

Dla stałej liczby kroków Trottera zgłaszana głębokość obwodu i czas QPU pozostają takie same dla testowanych rozmiarów układu, podczas gdy liczba bramek dwukubitowych rośnie. Zwiększenie liczby kroków daje głębsze obwody i wymaga więcej czasu QPU.

Tutaj czas QPU to łączny czas wykonania na sprzęcie głównych obwodów symulacji. Ostatnia kolumna obejmuje też czas QPU na charakteryzację szumu używaną w łagodzeniu błędów odczytu (REM) i odzyskiwaniu po zaniku (DR). Ten przewodnik używa małego jednowymiarowego przykładu Fermiego-Hubbarda, aby pokazać kompletny przepływ pracy od zdefiniowania modelu do wykreślenia zmierzonej dynamiki.

Opis funkcji​

Dynamika kwantowa opisuje, jak układ kwantowy zmienia się w czasie. Badanie tej ewolucji pomaga zrozumieć, jak poruszają się cząstki, jak rozwijają się korelacje i jak układ reaguje na zmianę swojego stanu lub hamiltonianu.

Model Fermiego-Hubbarda opisuje fermiony przemieszczające się między węzłami sieci i oddziałujące ze sobą, gdy zajmują ten sam węzeł. Współzawodnictwo między przeskokami a oddziaływaniami czyni go użytecznym modelem do badania silnie skorelowanych elektronów. Jego ewolucja czasowa może ujawnić, jak propagują się spin i ładunek oraz jak relaksuje się układ początkowo uporządkowany.

Model​

Dynamics Simulator obsługuje jednowymiarowy łańcuch Fermiego-Hubbarda z otwartymi brzegami. Dla łańcucha o LL węzłach hamiltonian jest zdefiniowany następująco:

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}.

Tutaj ciσ†c^\dagger_{i\sigma} i ciσc_{i\sigma} tworzą i anihilują fermion o spinie σ\sigma w węźle ii. Operator liczby niσ=ciσ†ciσn_{i\sigma}=c^\dagger_{i\sigma}c_{i\sigma} mierzy obsadzenie tego orbitalu spinowego.

Dane wejściowe modelu określają następujące współczynniki:

  • hopping_amplitude: th,it_{h,i}, który kontroluje przeskoki między sąsiednimi węzłami ii i i+1i+1.

  • on_site_interaction: UiU_i, oddziaływanie między fermionami o spinie w górę i w dół zajmującymi ten sam węzeł.

  • chemical_potential: μi\mu_i, lokalny potencjał chemiczny, który występuje w hamiltonianie ze znakiem minus.

Podaj skalar, aby użyć tego samego współczynnika w całym łańcuchu, lub listę, aby określić współczynniki dla poszczególnych wiązań lub węzłów.

W jednostkach, w których ℏ=1\hbar=1, stan początkowy ewoluuje następująco:

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

Funkcja szacuje wartości oczekiwane określonych przez ciebie obserwabli w kolejnych czasach symulacji.

Przepływ pracy​

Przepływ pracy funkcji składa się z następujących kroków:

  1. Synteza algorytmiczna: Funkcja używa hamiltonianu i ustawień czasu symulacji, aby skonstruować zoptymalizowaną sekwencję Trottera-Suzukiego, co zmniejsza głębokość obwodu przy uwzględnieniu dokładności symulacji.

  2. Mapowanie uwzględniające sprzęt: Funkcja mapuje i trasuje obwody, używając łączności kubitów i charakterystyk błędów wybranego backendu IBM Quantum.

  3. Tłumienie błędów w warstwie fizycznej: Fire Opal stosuje sprzężenie dynamiczne (dynamical decoupling) i korekty na poziomie impulsów, aby tłumić szum ze środowiska i przesłuchy podczas wykonania na sprzęcie.

Funkcja zarządza tymi etapami automatycznie i zwraca wartości oczekiwane żądanych obserwabli w czasie.

Problem fizyczny i ustawienia symulacji definiujesz za pomocą danych wejściowych funkcji. Obecny interfejs obsługuje ewolucję czasową Trottera, gdzie time_step ustawia czas trwania każdego kroku, a step_count ustawia liczbę kroków.

Dodatkowe szczegóły znajdziesz w przeglądzie symulatora dynamiki Fire Opal oraz w dokumentacji API simulate_dynamics.

Rozpoczęcie pracy​

Informacje o dostępie do tej Qiskit Function znajdziesz w Qiskit Functions Catalog.

Ten przewodnik pokazuje, jak załadować Dynamics Simulator i zasymulować czterowęzłowy łańcuch Fermiego-Hubbarda. Poniższy kod zakłada, że klucz API IBM Quantum Platform i CRN instancji zostały już zapisane w twoim środowisku lokalnym.

Instrukcje konfiguracji konta i instalacji klienta znajdziesz w Pierwsze kroki z 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")

Przykład: symulacja czterowęzłowego łańcucha Fermiego-Hubbarda​

Rozważ czterowęzłowy jednowymiarowy łańcuch Fermiego-Hubbarda z amplitudą przeskoku th=1t_h=1, bez oddziaływania na węźle i z zerowym potencjałem chemicznym. Pojedynczy fermion ze spinem w górę zaczyna w węźle 0 i ewoluuje wzdłuż łańcucha.

Ten mały problem pozwala skupić się na przepływie pracy Dynamics Simulator:

  1. Zdefiniuj model i symulację.

  2. Zdefiniuj stan początkowy i obserwable.

  3. Prześlij zadanie Qiskit Function.

  4. Pobierz wartości oczekiwane.

  5. Wykreśl dynamikę.

1. Zdefiniuj problem​

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

Lista obserwabli mierzy obsadzenie stanu spin w górę

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

w każdym węźle. Obserwable są zwracane w tej samej kolejności, w jakiej zostały podane.

2. Uruchom symulację dynamiki​

Prześlij problem za pomocą Qiskit Function. Qiskit Functions Catalog obsługuje uwierzytelnianie IBM Quantum, więc nie musisz przekazywać osobnych danych uwierzytelniających Fire Opal ani dostawcy sprzętu do sim_qf.run().

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

Zwrócony obiekt jest zadaniem Qiskit Function. Możesz zachować identyfikator zadania, aby później pobrać lub sprawdzić obciążenie.

3. Pobierz wynik​

result = job.result()

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

Przekonwertuj wartości oczekiwane obserwabli na tablicę NumPy. Każdy wiersz odpowiada jednej obserwabli, a każda kolumna odpowiada zarejestrowanemu czasowi symulacji, zaczynając od t=0t=0. W tym przykładzie cztery wiersze zawierają obsadzenia stanu spin w górę węzłów od 0 do 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. Zwizualizuj dynamikę​

Stan początkowy zawiera jeden fermion ze spinem w górę i żadnych fermionów ze spinem w dół. Jego ewolucja pozostaje zatem w podprzestrzeni jednocząstkowej, której cztery stany bazowe odpowiadają fermionowi zajmującemu węzły 0, 1, 2 i 3.

W tej podprzestrzeni hamiltonian łączy sąsiednie węzły z amplitudą przeskoku −th-t_h. Dla parametrów użytych tutaj,

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}.

Zdiagonalizuj tę macierz za pomocą NumPy i wyznacz ewolucję stanu początkowego w tych samych chwilach, które zwrócił Dynamics Simulator. Kwadrat modułu każdej amplitudy stanu daje obsadzenie spin w górę odpowiedniego węzła.

To obliczenie daje dokładną ewolucję hamiltonianu. Różnice między oszacowaniami ze sprzętu a tym odniesieniem mogą wynikać ze skończonego kroku Trottera, statystyki pomiarów i resztkowych błędów sprzętu.

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

Narysuj jeden panel dla każdego węzła. Ciągłe krzywe pokazują dokładne odniesienie w zarejestrowanych chwilach, a znaczniki pokazują oszacowania ze sprzętu zwrócone przez 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

Dla t=0t=0 dokładne obsadzenie spin w górę wynosi 1 w węźle 0 i 0 w pozostałych węzłach. W miarę ewolucji układu przeskoki rozprowadzają prawdopodobieństwo obecności cząstki wzdłuż łańcucha. Najpierw rośnie obsadzenie węzła 1, a następnie rosną obsadzenia węzłów 2 i 3. Dla parametrów w tym przykładzie ostatnia zarejestrowana chwila to t=1.6t=1.6. Dokładne obsadzenia węzłów od 0 do 3 wynoszą odpowiednio około 0,026, 0,370, 0,392 i 0,211.

Dokładne obsadzenia spełniają w każdej chwili następujące równanie, co odzwierciedla zachowanie liczby cząstek:

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

Obsadzenia poszczególnych węzłów mogą rosnąć i maleć, gdy cząstka ewoluuje w skończonym łańcuchu.

Pobieranie komunikatów o błędach​

Jeśli obciążenie przejdzie w stan ERROR, wywołaj job.result(), aby pobrać komunikat o błędzie. Możesz też sprawdzić logi funkcji, jeśli są dostępne.

print(job.status())

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

Typowe problemy z walidacją danych wejściowych to nieobsługiwany model lub metoda symulacji, zbyt długi ciąg stanu początkowego, niedopasowane człony i współczynniki obserwabli albo obserwabla odwołująca się do węzła spoza ciągu stanu początkowego.

Uzyskaj pomoc​

W razie pytań o działanie Dynamics Simulator lub Fire Opal zobacz dokumentację Q-CTRL lub skontaktuj się z Q-CTRL.

W sprawach uwierzytelniania Qiskit Functions, zarządzania zadaniami lub dostępu do IBM Quantum Platform zobacz dokumentację Qiskit Functions.

Kolejne kroki​

Zalecenia