Dynamics Simulator - eine Qiskit Function von Q-CTRL Fire Opal
Siehe die API-Referenz.
Qiskit Functions sind eine experimentelle Funktion, die nur Nutzern der Tarife IBM Quantum® Premium Plan, Flex Plan und On-Prem (über die IBM Quantum Platform API) zur Verfügung steht. Sie befinden sich im Preview-Status und können sich ändern.
Überblick
Der Q-CTRL Dynamics Simulator ist eine Application-Qiskit-Function zur Simulation der Zeitentwicklung unterstützter Quanten-Vielteilchenmodelle auf IBM Quantum-Hardware. Statt selbst Quantenschaltkreise zu konstruieren, gibst du das physikalische Modell, den Anfangszustand, die Parameter der Zeitentwicklung und die zu messenden Observablen an.
Die Funktion konstruiert und führt die erforderlichen dynamischen Circuits aus und wendet den hardwarebewussten Optimierungs- und Fehlerunterdrückungs-Workflow von Fire Opal an. Das Ergebnis ist ein Zeitverlauf von Erwartungswerten für die angeforderten Observablen. Da die Funktion die Fehlerunterdrückung automatisch anwendet, kannst du Circuits mit Rekordtiefen ausführen und dennoch aussagekräftige Signale sehen. Der Dynamics Simulator liefert eine Lösungsgenauigkeit, die mit den bestehenden klassischen Spitzenwerkzeugen übereinstimmt, und bietet einen nachweisbaren Geschwindigkeitsvorteil.
Praxistests erzielten eine Übereinstimmung innerhalb von 1 % quadratischem Mittelwertfehler (RMSE) im Vergleich zu den höchstauflösenden klassischen Tensornetzwerk-Simulationen. Unabhängige Tests aus der Forschungsgemeinschaft haben bestätigt, dass der Quantencomputer auch über die ersten Demonstrationen von Q-CTRL hinaus genau bleibt.
Benchmarks
Die Anzahl der Gitterplätze bestimmt, wie viele Qubits benötigt werden, während die Anzahl der Trotter-Schritte die Tiefe der Circuits für die Zeitentwicklung steuert. Jeder Gitterplatz verwendet zwei Qubits, um die Besetzungen mit Spin nach oben und Spin nach unten darzustellen.
Dieser Workflow wurde für Ketten mit 60 Gitterplätzen (120 Qubits) bei 30 Trotter-Schritten und für Ketten mit 31 Gitterplätzen (62 Qubits) bei 90 Trotter-Schritten demonstriert. Die folgende Tabelle zeigt die Circuit-Ressourcen und QPU-Ausführungszeiten aus den berichteten Experimenten, die auf einem IBM® Heron r3 (ibm_boston) Gerät mit 20.000 Shots pro Circuit durchgeführt wurden.
| Systemgröße | Trotter-Schritte | Zwei-Qubit-Tiefe | Anzahl der Zwei-Qubit-Gates | QPU-Zeit | QPU-Zeit mit REM + DR |
|---|---|---|---|---|---|
| 10 Gitterplätze (20 Qubits) | 30 | 152 | 1.457 | 2m 46s | 4m 25s |
| 10 Gitterplätze (20 Qubits) | 60 | 302 | 2.897 | 5m 36s | 8m 42s |
| 10 Gitterplätze (20 Qubits) | 90 | 452 | 4.337 | 8m 46s | 13m 26s |
| 31 Gitterplätze (62 Qubits) | 30 | 152 | 4.649 | 2m 46s | 4m 25s |
| 31 Gitterplätze (62 Qubits) | 60 | 302 | 9.239 | 5m 36s | 8m 42s |
| 31 Gitterplätze (62 Qubits) | 90 | 452 | 13.829 | 8m 46s | 13m 26s |
| 60 Gitterplätze (120 Qubits) | 30 | 152 | 9.057 | 2m 46s | 4m 25s |
Bei einer festen Anzahl von Trotter-Schritten bleiben die berichtete Circuit-Tiefe und die QPU-Zeit über die getesteten Systemgrößen hinweg gleich, während die Anzahl der Zwei-Qubit-Gates zunimmt. Eine höhere Anzahl von Schritten erzeugt tiefere Circuits und erfordert mehr QPU-Zeit.
Dabei ist die QPU-Zeit die kumulierte Hardware-Ausführungszeit für die Haupt-Simulations-Circuits. Die letzte Spalte enthält zusätzlich die QPU-Zeit für die Rauschcharakterisierung, die für die Auslesefehlermitigation (REM) und die Zerfallswiederherstellung (DR) verwendet wird. Diese Anleitung verwendet ein kleines eindimensionales Fermi-Hubbard-Beispiel, um den vollständigen Workflow von der Definition des Modells bis zum Plotten der gemessenen Dynamik zu zeigen.
Funktionsbeschreibung
Quantendynamik beschreibt, wie sich ein Quantensystem im Lauf der Zeit verändert. Das Studium dieser Entwicklung hilft dir zu verstehen, wie sich Teilchen bewegen, wie sich Korrelationen entwickeln und wie ein System auf eine Änderung seines Zustands oder seines Hamilton-Operators reagiert.
Das Fermi-Hubbard-Modell beschreibt Fermionen, die sich zwischen Gitterplätzen bewegen und wechselwirken, wenn sie denselben Platz besetzen. Der Wettstreit zwischen Hopping und Wechselwirkungen macht es zu einem nützlichen Modell für die Untersuchung stark korrelierter Elektronen. Seine Zeitentwicklung kann zeigen, wie sich Spin und Ladung ausbreiten und wie ein anfangs geordnetes System relaxiert.
Modell
Der Dynamics Simulator unterstützt eine eindimensionale Fermi-Hubbard-Kette mit offenen Rändern. Für eine Kette mit Gitterplätzen ist der Hamilton-Operator wie folgt definiert:
Hier erzeugen und vernichten und ein Fermion mit Spin am Platz . Der Teilchenzahloperator misst die Besetzung dieses Spin-Orbitals.
Die Modelleingaben legen die folgenden Koeffizienten fest:
-
hopping_amplitude: , das das Hopping zwischen benachbarten Plätzen und steuert. -
on_site_interaction: , die Wechselwirkung zwischen Fermionen mit Spin nach oben und Spin nach unten, die denselben Platz besetzen. -
chemical_potential: , das lokale chemische Potential, das mit negativem Vorzeichen in den Hamilton-Operator eingeht.
Gib einen Skalar an, um in der gesamten Kette denselben Koeffizienten zu verwenden, oder eine Liste, um Koeffizienten für einzelne Bindungen oder Plätze festzulegen.
In Einheiten mit entwickelt sich der Anfangszustand wie folgt:
Die Funktion schätzt die Erwartungswerte der von dir angegebenen Observablen zu aufeinanderfolgenden Simulationszeiten ab.
Workflow
Der Workflow der Funktion besteht aus den folgenden Schritten:
-
Algorithmische Synthese: Die Funktion verwendet den Hamilton-Operator und die Einstellungen zur Simulationszeit, um eine optimierte Trotter-Suzuki-Sequenz zu konstruieren, die die Circuit-Tiefe verringert und dabei die Simulationsgenauigkeit berücksichtigt.
-
Hardwarebewusstes Mapping: Die Funktion bildet die Circuits ab und routet sie anhand der Qubit-Konnektivität und der Fehlercharakteristik des ausgewählten IBM Quantum Backend.
-
Fehlerunterdrückung auf der physikalischen Ebene: Fire Opal setzt dynamische Entkopplung und Korrekturen auf Pulsebene ein, um Rauschen aus der Umgebung und Übersprechen während der Hardware-Ausführung zu unterdrücken.
Die Funktion verwaltet diese Phasen automatisch und gibt die Erwartungswerte der angeforderten Observablen über die Zeit zurück.
Du definierst das physikalische Problem und die Simulationseinstellungen über die Eingaben der Funktion. Die aktuelle Schnittstelle unterstützt Trotter-Zeitentwicklung, wobei time_step die Dauer jedes Schritts und step_count die Anzahl der Schritte festlegt.
Weitere Details findest du in der Übersicht zum Fire Opal Dynamics Simulator und in der API-Referenz zu simulate_dynamics.
Erste Schritte
Zugangsinformationen zu dieser Qiskit Function findest du im Qiskit Functions Catalog.
Diese Anleitung zeigt, wie du den Dynamics Simulator lädst und eine Fermi-Hubbard-Kette mit vier Gitterplätzen simulierst. Der folgende Code setzt voraus, dass du deinen IBM Quantum Platform API-Schlüssel und die Instanz-CRN bereits in deiner lokalen Umgebung gespeichert hast.
Anweisungen zur Kontoeinrichtung und Client-Installation findest du unter Erste Schritte mit 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")
Beispiel: Eine Fermi-Hubbard-Kette mit vier Gitterplätzen simulieren
Betrachte eine eindimensionale Fermi-Hubbard-Kette mit vier Gitterplätzen, mit der Hopping-Amplitude , ohne Wechselwirkung am Platz und mit chemischem Potential null. Ein einzelnes Fermion mit Spin nach oben beginnt am Platz 0 und entwickelt sich über die Kette.
Dieses kleine Problem hält den Fokus auf dem Workflow des Dynamics Simulator:
-
Definiere das Modell und die Simulation.
-
Definiere den Anfangszustand und die Observablen.
-
Reiche den Job der Qiskit Function ein.
-
Rufe die Erwartungswerte ab.
-
Plotte die Dynamik.
1. Das Problem definieren
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
Die Observablenliste misst die Besetzung mit Spin nach oben
an jedem Platz. Die Observablen werden in derselben Reihenfolge zurückgegeben, in der sie angegeben wurden.
2. Die Dynamiksimulation ausführen
Reiche das Problem über die Qiskit Function ein. Der Qiskit Functions Catalog übernimmt die IBM Quantum-Authentifizierung, daher musst du keine separaten Fire Opal- oder Hardware-Anbieter-Zugangsdaten an sim_qf.run() übergeben.
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
Das zurückgegebene Objekt ist ein Qiskit Function-Job. Du kannst die Job-ID aufbewahren, um die Arbeitslast später abzurufen oder zu untersuchen.
3. Das Ergebnis abrufen
result = job.result()
print("Result keys:", sorted(result.keys()))
print("Warnings:", result.get("warnings", []))
Result keys: ['metadata', 'observable_expectation_values', 'observables', 'warnings']
Warnings: []
Wandle die Erwartungswerte der Observablen in ein NumPy-Array um. Jede Zeile entspricht einer Observablen und jede Spalte einer aufgezeichneten Simulationszeit, beginnend bei . In diesem Beispiel enthalten die vier Zeilen die Spin-up-Besetzungen der Plätze 0 bis 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. Die Dynamik visualisieren
Der Anfangszustand enthält ein Spin-up-Fermion und kein Spin-down-Fermion. Seine Entwicklung bleibt daher im Einteilchen-Unterraum, dessen vier Basiszustände dem Fermion auf den Plätzen 0, 1, 2 und 3 entsprechen.
In diesem Unterraum verbindet der Hamiltonoperator benachbarte Plätze mit der Hopping-Amplitude . Für die hier verwendeten Parameter gilt
Diagonalisiere diese Matrix mit NumPy und entwickle den Anfangszustand zu denselben Zeiten, die der Dynamics Simulator zurückgegeben hat. Das Betragsquadrat jeder Zustandsamplitude ergibt die Spin-up-Besetzung des entsprechenden Platzes.
Diese Berechnung liefert die exakte Hamiltonsche Zeitentwicklung. Unterschiede zwischen den Hardware-Schätzungen und dieser Referenz können vom endlichen Trotter-Schritt, von Messstatistiken und von verbleibenden Hardwarefehlern herrühren.
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
Zeichne ein Diagramm für jeden Platz. Die durchgezogenen Kurven zeigen die exakte Referenz zu den aufgezeichneten Zeiten, die Marker zeigen die vom Dynamics Simulator zurückgegebenen Hardware-Schätzungen.
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()

Bei ist die exakte Spin-up-Besetzung an Platz 0 gleich 1 und an den übrigen Plätzen gleich 0. Während sich das System entwickelt, verteilt das Hopping die Wahrscheinlichkeit des Teilchens über die Kette. Die Besetzung von Platz 1 steigt zuerst, danach steigt die Besetzung an den Plätzen 2 und 3. Für die Parameter in diesem Beispiel ist die letzte aufgezeichnete Zeit . Die exakten Besetzungen der Plätze 0 bis 3 betragen jeweils ungefähr 0.026, 0.370, 0.392 und 0.211.
Die exakten Besetzungen erfüllen zu jeder Zeit die folgende Gleichung, was die Erhaltung der Teilchenzahl widerspiegelt:
Einzelne Platzbesetzungen können steigen und fallen, während sich das Teilchen durch die endliche Kette entwickelt.
Fehlermeldungen abrufen
Wenn die Arbeitslast in den Zustand ERROR übergeht, rufe job.result() auf, um die Fehlermeldung abzurufen. Du kannst auch die Logs der Function einsehen, sofern sie verfügbar sind.
print(job.status())
if job.status() == "ERROR":
print(job.result())
print(job.logs())
DONE
Häufige Probleme bei der Eingabevalidierung sind ein nicht unterstütztes Modell oder Simulationsverfahren, ein zu langer Anfangszustands-String, nicht zusammenpassende Observablen-Terme und -Koeffizienten oder eine Observable, die auf einen Platz außerhalb des Anfangszustands-Strings verweist.
Support erhalten
Bei Fragen zum Dynamics Simulator oder zum Verhalten von Fire Opal siehe die Q-CTRL-Dokumentation oder kontaktiere Q-CTRL.
Bei Fragen zur Authentifizierung bei Qiskit Functions, zur Jobverwaltung oder zum Zugriff auf IBM Quantum Platform siehe die Qiskit Functions-Dokumentation.
Nächste Schritte
- Sieh dir die
simulate_dynamics-API-Referenz für die zugrunde liegenden Definitionen von Modell, Simulation, Observablen, Ausgabe und Validierung an. - Probiere das Tutorial Spin- und Ladungsdynamik im Fermi-Hubbard-Modell aus.
- Lies die Übersicht zum Fire Opal Dynamics Simulator für mehr Details zu Trotterisierung, hardwarebewusstem Mapping und der Fehlerunterdrückung von Fire Opal.
- Ändere die Modellparameter, den Anfangszustand, den Zeitschritt, die Schrittzahl und die Observablen, um ein anderes eindimensionales Fermi-Hubbard-Dynamikproblem zu untersuchen.