QUICK-PDE: Una Qiskit Function de ColibriTD
Las Qiskit Functions son una funcionalidad experimental disponible para los usuarios de los planes IBM Quantum® Premium, Flex y On-Prem (mediante la API de IBM Quantum Platform). Se encuentran en estado de versión preliminar y están sujetas a cambios.
Descripción general
El solucionador de Ecuaciones Diferenciales Parciales (PDE) que se presenta aquí forma parte de nuestra plataforma Quantum Innovative Computing Kit (QUICK) (QUICK-PDE) y está empaquetado como una Qiskit Function. Con la función QUICK-PDE puedes resolver ecuaciones diferenciales parciales específicas de dominio en QPUs de IBM Quantum. Esta función se basa en el algoritmo descrito en el artículo de descripción del H-DES de ColibriTD. Este algoritmo puede resolver problemas complejos de múltiples físicas, comenzando con Dinámica de Fluidos Computacional (CFD) y Deformación de Materiales (MD), con más casos de uso próximamente.
Para abordar las ecuaciones diferenciales, las soluciones de prueba se codifican como combinaciones lineales de funciones ortogonales (típicamente polinomios de Chebyshev, y más específicamente de ellos, donde es el número de qubits que codifican tu función), parametrizadas por los ángulos de un Circuito Cuántico Variable (VQC). El ansatz genera un estado que codifica la función, que se evalúa mediante observables cuyas combinaciones permiten evaluar la función en todos los puntos. Luego puedes evaluar la función de pérdida en la que se codifican las ecuaciones diferenciales y ajustar los ángulos en un bucle híbrido, como se muestra a continuación. Las soluciones de prueba se acercan gradualmente a las soluciones reales hasta alcanzar un resultado satisfactorio.
Además de este bucle híbrido, también puedes encadenar distintos optimizadores. Esto es útil cuando quieres que un optimizador global encuentre un buen conjunto de ángulos y luego un optimizador más fino siga un gradiente hasta el mejor conjunto de ángulos vecinos. En el caso de la dinámica de fluidos computacional (CFD), la secuencia de optimización predeterminada produce los mejores resultados; en el caso de la deformación de materiales (MD), aunque la opción predeterminada proporciona buenos resultados, puedes configurarla con mayor detalle para obtener beneficios específicos del problema.
Ten en cuenta que para cada variable de la función especificamos el número de qubits (con el que puedes experimentar). Al apilar 10 circuitos idénticos y evaluar los 10 observables idénticos en diferentes qubits a lo largo de un gran circuito, puedes aplicar mitigación de ruido dentro del proceso de optimización CMA, apoyándote en el método del noise learner, y reducir significativamente el número de shots necesarios.
Entrada/salida
Dinámica de Fluidos Computacional
La ecuación de Burgers no viscosa modela fluidos no viscosos en movimiento de la siguiente manera:
representa el campo de velocidad del fluido. Este caso de uso tiene una condición de frontera temporal: puedes seleccionar la condición inicial y luego permitir que el sistema se relaje. Actualmente, las únicas condiciones iniciales aceptadas son funciones lineales: .
Los argumentos para las ecuaciones diferenciales de CFD se encuentran en una cuadrícula fija, de la siguiente manera:
- está entre 0 y 0.95 con 30 puntos de muestreo. está entre 0 y 0.95 con un tamaño de paso de 0.2375.
Deformación de Materiales
Este caso de uso se centra en la deformación hipoelástica con el ensayo de tracción unidimensional, en el que una barra fija en el espacio es jalada por su otro extremo. Describimos el problema de la siguiente manera:
representa el módulo volumétrico del material que se estira, el exponente de una ley de potencias, la fuerza por unidad de masa, el límite de tensión proporcional, el límite de deformación proporcional, la función de tensión y la función de deformación.
La barra considerada tiene longitud unitaria. Este caso de uso tiene una condición de frontera para la tensión superficial , es decir, la cantidad de trabajo necesaria para estirar la barra.
Los argumentos para las ecuaciones diferenciales de MD se encuentran en una cuadrícula fija, de la siguiente manera:
- está entre 0 y 1 con un tamaño de paso de 0.04.
Entrada
Para ejecutar la Qiskit Function QUICK-PDE, puedes ajustar los siguientes parámetros:
| Nombre | Tipo | Descripción | Específico del caso de uso | Ejemplo |
|---|---|---|---|---|
| use_case | Literal["MD", "CFD"] | Selecciona el sistema de ecuaciones diferenciales a resolver | No | "CFD" |
| parameters | dict[str, Any] | Parámetros de la ecuación diferencial (consulta la siguiente tabla para más detalles) | No | {"a": 1.0, "b": 1.0} |
| nb_qubits | Optional[dict[str, dict[str, int]]] | Número de qubits por función y por variable. La función elige valores optimizados, pero si quieres probar una combinación diferente, puedes reemplazar los valores predeterminados | No | {"u": {"x": 1, "t":3}} |
| depth | Optional[dict[str, int]] | Profundidad del ansatz por función. La función elige valores optimizados, pero si quieres probar una combinación diferente, puedes reemplazar los valores predeterminados | No | {"u": 4} |
| optimizer | Optional[list[str]] | Optimizadores a utilizar, ya sea "CMAES" de la biblioteca Python cma o uno de los optimizadores de scipy | MD | "SLSQP" |
| shots | Optional[list[int]] | Número de shots utilizados para ejecutar cada circuito. Como se necesitan varios pasos de optimización, la longitud de la lista debe ser igual al número de optimizadores usados (4 en el caso de CFD). Por defecto es [50_000] * nb_optimizers para MD y [5_00, 2_000, 5_000, 10_000] para CFD | No | [15_000, 30_000] |
| optimizer_options | Optional[dict[str, Any]] | Opciones para pasar al optimizador. Los detalles de esta entrada dependen del optimizador usado; para más información consulta la documentación del optimizador correspondiente | MD | {"maxiter": 50 } |
| initialization | Optional[Literal["RANDOM", "PHYSICALLY_INFORMED"]] | Indica si empezar con ángulos aleatorios o ángulos elegidos de forma inteligente. Ten en cuenta que los ángulos elegidos de forma inteligente pueden no funcionar en el 100% de los casos. Por defecto es "PHYSICALLY_INFORMED". | No | "RANDOM" |
| backend_name | Optional[str] | El nombre del backend a utilizar. | No | "ibm_torino" |
| mode | Optional[Literal["job", "session", "batch"]] | El modo de ejecución a utilizar. Por defecto es "job". | No | "job" |
Los parámetros de la ecuación diferencial (parámetros físicos y condición de frontera) deben seguir el siguiente formato:
| Caso de uso | Clave | Tipo de valor | Descripción | Ejemplo |
|---|---|---|---|---|
| CFD | a | float | Coeficiente de los valores iniciales de | 1.0 |
| CFD | b | float | Desplazamiento de los valores iniciales de | 1.0 |
| MD | t | float | tensión superficial | 12.0 |
| MD | K | float | módulo volumétrico | 100.0 |
| MD | n | int | ley de potencias | 4.0 |
| MD | b | float | fuerza por unidad de masa | 10.0 |
| MD | epsilon_0 | float | límite de tensión proporcional | 0.1 |
| MD | sigma_0 | float | límite de deformación proporcional | 5.0 |
Salida
La salida es un diccionario con la lista de puntos de muestreo, así como los valores de las funciones en cada uno de esos puntos:
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit-ibm-catalog
from numpy import array
solution = {
"functions": {
"u": array(
[
[0.01, 0.1, 1],
[0.02, 0.2, 2],
[0.03, 0.3, 3],
[0.04, 0.4, 4],
]
),
},
"samples": {
"t": array([0.1, 0.2, 0.3, 0.4]),
"x": array([0.5, 0.6, 0.7]),
},
}
La forma de un array de solución depende de los muestreos de las variables:
assert len(solution["functions"]["u"].shape) == len(solution["samples"])
for col_size, samples in zip(
solution["functions"]["u"].shape, solution["samples"].values()
):
assert col_size == len(samples)
La correspondencia entre los puntos de muestreo de las variables de la función y la dimensión del array de solución se establece en orden alfanumérico del nombre de la variable. Por ejemplo, si las variables son "t" y "x", una fila de solution["functions"]["u"] representa los valores de la solución para un "t" fijo, y una columna de solution["functions"]["u"] representa los valores de la solución para un "x" fijo.
A continuación se muestra un ejemplo de cómo obtener el valor de la función para un conjunto específico de coordenadas:
# u(t=0.2, x=0.7) == 2
assert solution["samples"]["t"][1] == 0.2
assert solution["samples"]["x"][2] == 0.7
assert solution["functions"]["u"][1, 2] == 2
Benchmarks
La siguiente tabla presenta estadísticas de varias ejecuciones de nuestra función.
| Ejemplo | Número de qubits | Inicialización | Error | Tiempo total (min) | Uso de runtime (min) |
|---|---|---|---|---|---|
| Ecuación de Burgers no viscosa | 50 | PHYSICALLY_INFORMED | 66 | 25 | |
| Ensayo de tracción hipoelástica 1D | 18 | RANDOM | 123 | 100 |
Comenzar
Rellena el formulario para solicitar acceso a la función QUICK-PDE. Luego, suponiendo que ya has guardado tu cuenta en tu entorno local, selecciona la función de la siguiente manera:
from qiskit_ibm_catalog import QiskitFunctionsCatalog
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
quick = catalog.load("colibritd/quick-pde")
Ejemplos
Para empezar, prueba uno de los siguientes ejemplos:
Dinámica de Fluidos Computacional (CFD)
Cuando las condiciones iniciales se establecen como , los resultados son los siguientes:
# launch the simulation with initial conditions u(0,x) = a*x + b
job = quick.run(use_case="cfd", physical_parameters={"a": 1.0, "b": 0.0})
Verifica el estado de la carga de trabajo de tu Qiskit Function u obtén los resultados de la siguiente manera:
print(job.status())
solution = job.result()
'QUEUED'
import numpy as np
import matplotlib.pyplot as plt
_ = plt.figure()
ax = plt.axes(projection="3d")
# plot the solution using the 3d plotting capabilities of pyplot
t, x = np.meshgrid(solution["samples"]["t"], solution["samples"]["x"])
ax.plot_surface(
t,
x,
solution["functions"]["u"],
edgecolor="royalblue",
lw=0.25,
rstride=26,
cstride=26,
alpha=0.3,
)
ax.scatter(t, x, solution["functions"]["u"], marker=".")
ax.set(xlabel="t", ylabel="x", zlabel="u(t,x)")
plt.show()

Deformación de Materiales
El caso de uso de deformación de materiales requiere los parámetros físicos del material y la fuerza aplicada, de la siguiente manera:
import matplotlib.pyplot as plt
# select the properties of your material
job = quick.run(
use_case="md",
physical_parameters={
"t": 12.0,
"K": 100.0,
"n": 4.0,
"b": 10.0,
"epsilon_0": 0.1,
"sigma_0": 5.0,
},
)
# plot the result
solution = job.result()
_ = plt.figure()
stress_plot = plt.subplot(211)
plt.plot(solution["samples"]["x"], solution["functions"]["u"])
strain_plot = plt.subplot(212)
plt.plot(solution["samples"]["x"], solution["functions"]["sigma"])
plt.show()
Obtener mensajes de error
Si el estado de tu carga de trabajo es ERROR, usa job.error_message() para obtener el mensaje de error que te ayude a depurar, de la siguiente manera:
job = quick.run(use_case="mdf", physical_params={})
print(job.error_message())
# or write a wrapper around it for a more human readable version
def pprint_error(job):
print("".join(eval(job.error_message())["error"]))
print("___")
pprint_error(job)
{"error": ["qiskit.exceptions.QiskitError: 'Unknown argument \"physical_params\", did you make a typo? -- https://docs.quantum.ibm.com/errors#1804'\n"]}
___
qiskit.exceptions.QiskitError: 'Unknown argument "physical_params", did you make a typo? -- https://docs.quantum.ibm.com/errors#1804'
Obtener soporte
Para obtener soporte, contacta a qiskit-function-support@colibritd.com.
Próximos pasos
- Rellena el formulario para solicitar acceso a la función QUICK-PDE.
- Prueba modelar un fluido no viscoso en movimiento con QUICK-PDE en el tutorial.
- Consulta Jaffali, H., et al. (2025). H-DES: a Quantum-Classical Hybrid Differential Equation Solver. arXiv preprint arXiv:2410.01130.