Saltar al contenido principal
Este proyecto está en fase beta. ¿Encontraste un error? Abre un issue en GitHub. ¿Tienes una pregunta o una idea? Pregunta en Discussions — ¡nos encantaría tu opinión!
¿Cómo es la calidad de la traducción en esta página?

Dynamics Simulator: una Qiskit Function de Q-CTRL Fire Opal

Consulta la referencia de la API.

nota

Qiskit Functions es una función experimental disponible solo para usuarios del Plan Premium, el Plan Flex y el Plan On-Prem (a través de la API de IBM Quantum Platform) de IBM Quantum®. Se encuentra en estado de versión preliminar y está sujeta a cambios.

Descripción general​

El Dynamics Simulator de Q-CTRL es una Qiskit Function de aplicación para simular la evolución temporal de modelos cuánticos de muchos cuerpos compatibles en hardware de IBM Quantum. En lugar de construir tú mismo los circuitos cuánticos, especificas el modelo físico, el estado inicial, los parámetros de evolución temporal y los observables que se van a medir.

La función construye y ejecuta los circuitos dinámicos necesarios y aplica el flujo de optimización y supresión de errores de Fire Opal, consciente del hardware. El resultado es una traza temporal de valores esperados de los observables que solicitaste. Como la función aplica la supresión de errores automáticamente, puedes ejecutar circuitos con profundidades récord y aun así ver señales significativas. El Dynamics Simulator ofrece una precisión de solución que iguala a las herramientas clásicas de vanguardia existentes y aporta una ventaja demostrable en velocidad.

Las pruebas en condiciones reales lograron una concordancia dentro del 1 % de error cuadrático medio (RMSE) al compararlas con las simulaciones clásicas de redes tensoriales de mayor resolución. Las pruebas independientes de la comunidad investigadora han validado que el ordenador cuántico sigue siendo preciso incluso más allá de las demostraciones iniciales de 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.

Pruebas de rendimiento​

El número de sitios determina cuántos qubits se necesitan, mientras que el número de pasos de Trotter controla la profundidad de los circuitos de evolución temporal. Cada sitio de la red usa dos qubits para representar las ocupaciones de espín arriba y espín abajo.

Este flujo de trabajo se ha demostrado para cadenas de 60 sitios (120 qubits) con 30 pasos de Trotter, y para cadenas de 31 sitios (62 qubits) con 90 pasos de Trotter. La siguiente tabla muestra los recursos de los circuitos y los tiempos de ejecución en la QPU de los experimentos reportados, realizados en un dispositivo IBM® Heron r3 (ibm_boston) con 20 000 shots por circuito.

Tamaño del sistemaPasos de TrotterProfundidad de dos qubitsNúmero de puertas de dos qubitsTiempo de QPUTiempo de QPU con REM + DR
10 sitios (20 qubits)301521,4572m 46s4m 25s
10 sitios (20 qubits)603022,8975m 36s8m 42s
10 sitios (20 qubits)904524,3378m 46s13m 26s
31 sitios (62 qubits)301524,6492m 46s4m 25s
31 sitios (62 qubits)603029,2395m 36s8m 42s
31 sitios (62 qubits)9045213,8298m 46s13m 26s
60 sitios (120 qubits)301529,0572m 46s4m 25s

Para un número fijo de pasos de Trotter, la profundidad del circuito y el tiempo de QPU reportados se mantienen iguales en los tamaños de sistema probados, mientras que el número de puertas de dos qubits aumenta. Aumentar el número de pasos produce circuitos más profundos y requiere más tiempo de QPU.

Aquí, el tiempo de QPU es el tiempo acumulado de ejecución en el hardware de los circuitos principales de simulación. La última columna incluye además el tiempo de QPU de la caracterización de ruido usada en la mitigación de errores de lectura (REM) y la recuperación de decaimiento (DR). Esta guía usa un pequeño ejemplo unidimensional de Fermi-Hubbard para mostrar el flujo de trabajo completo, desde la definición del modelo hasta la representación gráfica de la dinámica medida.

Descripción de la función​

La dinámica cuántica describe cómo cambia un sistema cuántico a lo largo del tiempo. Estudiar esta evolución te ayuda a comprender cómo se mueven las partículas, cómo se desarrollan las correlaciones y cómo responde un sistema a un cambio en su estado o en su hamiltoniano.

El modelo de Fermi-Hubbard describe fermiones que se mueven entre sitios de una red e interactúan cuando ocupan el mismo sitio. La competencia entre el salto y las interacciones lo convierte en un modelo útil para estudiar electrones fuertemente correlacionados. Su evolución temporal puede revelar cómo se propagan el espín y la carga, y cómo se relaja un sistema inicialmente ordenado.

Modelo​

El Dynamics Simulator admite una cadena unidimensional de Fermi-Hubbard con bordes abiertos. Para una cadena de LL sitios, el hamiltoniano se define como sigue:

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

Aquí, ciσ†c^\dagger_{i\sigma} y ciσc_{i\sigma} crean y aniquilan un fermión con espín σ\sigma en el sitio ii. El operador número niσ=ciσ†ciσn_{i\sigma}=c^\dagger_{i\sigma}c_{i\sigma} mide la ocupación de ese orbital de espín.

Las entradas del modelo especifican los siguientes coeficientes:

  • hopping_amplitude: th,it_{h,i}, que controla el salto entre los sitios vecinos ii e i+1i+1.

  • on_site_interaction: UiU_i, la interacción entre fermiones de espín arriba y espín abajo que ocupan el mismo sitio.

  • chemical_potential: μi\mu_i, el potencial químico local, que entra en el hamiltoniano con signo menos.

Proporciona un escalar para usar el mismo coeficiente en toda la cadena, o una lista para especificar coeficientes para enlaces o sitios individuales.

En unidades donde ℏ=1\hbar=1, el estado inicial evoluciona de la siguiente manera:

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

La función estima los valores esperados de los observables que especificas en tiempos de simulación sucesivos.

Flujo de trabajo​

El flujo de trabajo de la función consta de los siguientes pasos:

  1. Síntesis algorítmica: La función usa el hamiltoniano y los ajustes de tiempo de simulación para construir una secuencia de Trotter-Suzuki optimizada, que reduce la profundidad del circuito teniendo en cuenta la precisión de la simulación.

  2. Mapeo consciente del hardware: La función mapea y enruta los circuitos usando la conectividad de los qubits y las características de error del Backend de IBM Quantum seleccionado.

  3. Supresión de errores en la capa física: Fire Opal incorpora desacoplamiento dinámico y correcciones a nivel de pulso para suprimir el ruido del entorno y la diafonía durante la ejecución en el hardware.

La función gestiona estas etapas automáticamente y devuelve los valores esperados de los observables solicitados a lo largo del tiempo.

Defines el problema físico y los ajustes de simulación mediante las entradas de la función. La interfaz actual admite la evolución temporal de Trotter, donde time_step establece la duración de cada paso y step_count establece el número de pasos.

Para obtener más detalles, consulta la descripción general del simulador de dinámica de Fire Opal y la referencia de la API de simulate_dynamics.

Primeros pasos​

Encuentra la información de acceso a esta Qiskit Function en el Qiskit Functions Catalog.

Esta guía muestra cómo cargar el Dynamics Simulator y simular una cadena de Fermi-Hubbard de cuatro sitios. El siguiente código supone que ya guardaste tu clave de API de IBM Quantum Platform y el CRN de tu instancia en tu entorno local.

Para obtener instrucciones sobre la configuración de la cuenta y la instalación del cliente, consulta Get started with 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")

Ejemplo: simular una cadena de Fermi-Hubbard de cuatro sitios​

Considera una cadena unidimensional de Fermi-Hubbard de cuatro sitios con amplitud de salto th=1t_h=1, sin interacción en el sitio y con potencial químico cero. Un único fermión de espín arriba comienza en el sitio 0 y evoluciona a lo largo de la cadena.

Este pequeño problema mantiene el foco en el flujo de trabajo del Dynamics Simulator:

  1. Definir el modelo y la simulación.

  2. Definir el estado inicial y los observables.

  3. Enviar el job de la Qiskit Function.

  4. Recuperar los valores esperados.

  5. Representa gráficamente la dinámica.

1. Define el problema​

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

La lista de observables mide la ocupación de espín hacia arriba

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

en cada sitio. Los observables se devuelven en el mismo orden en que se proporcionan.

2. Ejecuta la simulación de la dinámica​

Envía el problema mediante la Qiskit Function. El Qiskit Functions Catalog gestiona la autenticación de IBM Quantum, por lo que no tienes que pasar credenciales independientes de Fire Opal ni del proveedor de hardware a 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

El objeto devuelto es un trabajo de Qiskit Function. Puedes conservar el ID del trabajo para recuperar o inspeccionar la carga de trabajo más adelante.

3. Recupera el resultado​

result = job.result()

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

Convierte los valores esperados de los observables en un arreglo de NumPy. Cada fila corresponde a un observable y cada columna corresponde a un tiempo de simulación registrado, comenzando en t=0t=0. En este ejemplo, las cuatro filas contienen las ocupaciones de espín hacia arriba de los sitios 0 a 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. Visualiza la dinámica​

El estado inicial contiene un fermión con espín hacia arriba y ningún fermión con espín hacia abajo. Por lo tanto, su evolución permanece en el subespacio de una sola partícula, cuyos cuatro estados base corresponden al fermión ocupando los sitios 0, 1, 2 y 3.

En este subespacio, el hamiltoniano conecta los sitios vecinos con amplitud de salto −th-t_h. Para los parámetros utilizados aquí,

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

Diagonaliza esta matriz con NumPy y evoluciona el estado inicial en los mismos tiempos que devolvió el Dynamics Simulator. El módulo al cuadrado de cada amplitud de estado da la ocupación de espín hacia arriba del sitio correspondiente.

Este cálculo da la evolución hamiltoniana exacta. Las diferencias entre las estimaciones del hardware y esta referencia pueden incluir el paso de Trotter finito, las estadísticas de medición y los errores residuales del hardware.

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

Representa un panel para cada sitio. Las curvas continuas muestran la referencia exacta en los tiempos registrados, y los marcadores muestran las estimaciones del hardware devueltas por el 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

En t=0t=0, la ocupación exacta de espín hacia arriba es 1 en el sitio 0 y 0 en los demás sitios. A medida que el sistema evoluciona, el salto extiende la probabilidad de la partícula por la cadena. La ocupación del sitio 1 aumenta primero, seguida del aumento de la ocupación en los sitios 2 y 3. Para los parámetros de este ejemplo, el último tiempo registrado es t=1.6t=1.6. Las ocupaciones exactas de los sitios 0 a 3 son aproximadamente 0.026, 0.370, 0.392 y 0.211, respectivamente.

Las ocupaciones exactas satisfacen la siguiente ecuación en todo momento, lo que refleja la conservación del número de partículas:

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

Las ocupaciones individuales de los sitios pueden aumentar y disminuir a medida que la partícula evoluciona por la cadena finita.

Obtener los mensajes de error​

Si la carga de trabajo entra en el estado ERROR, llama a job.result() para recuperar el mensaje de error. También puedes inspeccionar los registros de la función, si están disponibles.

print(job.status())

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

Los problemas habituales de validación de entradas incluyen un modelo o método de simulación no admitido, una cadena de estado inicial demasiado larga, términos y coeficientes de observables que no coinciden, o un observable que hace referencia a un sitio fuera de la cadena del estado inicial.

Obtener soporte​

Si tienes preguntas sobre el comportamiento del Dynamics Simulator o de Fire Opal, consulta la documentación de Q-CTRL o contacta con Q-CTRL.

Para la autenticación de Qiskit Functions, la gestión de trabajos o el acceso a IBM Quantum Platform, consulta la documentación de Qiskit Functions.

Próximos pasos​

Recomendaciones