QUICK-PDE: una Qiskit Function di ColibriTD
Le Qiskit Functions sono una funzionalità sperimentale disponibile per gli utenti dei piani IBM Quantum® Premium, Flex e On-Prem (tramite IBM Quantum Platform API). Sono in stato di anteprima e soggette a modifiche.
Panoramica​
Il risolutore di Equazioni Differenziali alle Derivate Parziali (PDE) presentato qui fa parte della nostra piattaforma Quantum Innovative Computing Kit (QUICK) (QUICK-PDE) ed è distribuito come Qiskit Function. Con la funzione QUICK-PDE puoi risolvere equazioni differenziali alle derivate parziali specifiche per dominio sui QPU IBM Quantum. Questa funzione si basa sull'algoritmo descritto nel paper descrittivo H-DES di ColibriTD. Questo algoritmo è in grado di risolvere problemi multi-fisici complessi, a partire dalla Fluidodinamica Computazionale (CFD) e dalla Deformazione dei Materiali (MD), con altri casi d'uso in arrivo.
Per affrontare le equazioni differenziali, le soluzioni di tentativo sono codificate come combinazioni lineari di funzioni ortogonali (tipicamente polinomi di Chebyshev, e più specificamente di essi, dove è il numero di qubit che codificano la tua funzione), parametrizzate dagli angoli di un Variable Quantum circuito (VQC). L'ansatz genera uno stato che codifica la funzione, valutata tramite osservabili le cui combinazioni consentono di calcolare la funzione in tutti i punti. Puoi quindi valutare la funzione di perdita in cui sono codificate le equazioni differenziali e affinare gli angoli in un ciclo ibrido, come mostrato di seguito. Le soluzioni di tentativo si avvicinano progressivamente alle soluzioni reali finché non si raggiunge un risultato soddisfacente.
Oltre a questo ciclo ibrido, puoi anche concatenare diversi ottimizzatori. Questo è utile quando vuoi che un ottimizzatore globale trovi un buon insieme di angoli e poi un ottimizzatore più fine segua un gradiente verso il miglior insieme di angoli vicini. Nel caso della fluidodinamica computazionale (CFD), la sequenza di ottimizzazione predefinita produce i migliori risultati; nel caso della deformazione dei materiali (MD), il valore predefinito fornisce buoni risultati, ma puoi configurarlo ulteriormente per ottenere vantaggi specifici per il problema.
Nota che per ogni variabile della funzione specifichiamo il numero di qubit (su cui puoi sperimentare). Impilando 10 circuiti identici e valutando i 10 osservabili identici su qubit diversi all'interno di un unico grande circuito, puoi mitigare il rumore durante il processo di ottimizzazione CMA, sfruttando il metodo noise learner, riducendo significativamente il numero di shot necessari.
Input/output​
Fluidodinamica Computazionale​
L'equazione di Burgers non viscosa modella fluidi non viscosi in moto nel modo seguente:
rappresenta il campo di velocità del fluido. Questo caso d'uso ha una condizione al contorno temporale: puoi selezionare la condizione iniziale e quindi lasciare che il sistema si rilassi. Attualmente le uniche condizioni iniziali accettate sono funzioni lineari: .
Gli argomenti delle equazioni differenziali per CFD si trovano su una griglia fissa, come segue:
- è compreso tra 0 e 0.95 con 30 punti campione. è compreso tra 0 e 0.95 con un passo di 0.2375.
Deformazione dei Materiali​
Questo caso d'uso si concentra sulla deformazione ipoelastica con il test di trazione monodimensionale, in cui una barra fissata nello spazio viene tirata all'estremità opposta. Descriviamo il problema come segue:
rappresenta il modulo di compressione del materiale in trazione, l'esponente di una legge di potenza, la forza per unità di massa, il limite di proporzionalità della tensione, il limite di proporzionalità della deformazione, la funzione di tensione e la funzione di deformazione.
La barra considerata ha lunghezza unitaria. Questo caso d'uso ha una condizione al contorno per la tensione superficiale , ovvero la quantità di lavoro necessaria per allungare la barra.
Gli argomenti delle equazioni differenziali per MD si trovano su una griglia fissa, come segue:
- è compreso tra 0 e 1 con un passo di 0.04.
Input​
Per eseguire la Qiskit Function QUICK-PDE puoi regolare i seguenti parametri:
| Nome | Tipo | Descrizione | Specifico per caso d'uso | Esempio |
|---|---|---|---|---|
| use_case | Literal["MD", "CFD"] | Seleziona il sistema di equazioni differenziali da risolvere | No | "CFD" |
| parameters | dict[str, Any] | Parametri dell'equazione differenziale (vedi la tabella successiva per i dettagli) | No | {"a": 1.0, "b": 1.0} |
| nb_qubits | Optional[dict[str, dict[str, int]]] | Numero di qubit per funzione e per variabile. La funzione sceglie i valori ottimizzati, ma se vuoi provare una combinazione migliore puoi sovrascrivere i valori predefiniti | No | {"u": {"x": 1, "t":3}} |
| depth | Optional[dict[str, int]] | Profondità dell'ansatz per funzione. La funzione sceglie i valori ottimizzati, ma se vuoi provare una combinazione migliore puoi sovrascrivere i valori predefiniti | No | {"u": 4} |
| optimizer | Optional[list[str]] | Ottimizzatori da utilizzare: "CMAES" dalla libreria Python cma oppure uno degli ottimizzatori di scipy | MD | "SLSQP" |
| shots | Optional[list[int]] | Numero di shot usati per eseguire ogni circuito. Poiché sono necessari diversi passi di ottimizzazione, la lunghezza della lista deve essere uguale al numero di ottimizzatori utilizzati (4 per CFD). Il valore predefinito è [50_000] * nb_optimizers per MD e [5_00, 2_000, 5_000, 10_000] per CFD | No | [15_000, 30_000] |
| optimizer_options | Optional[dict[str, Any]] | Opzioni da passare all'ottimizzatore. I dettagli di questo input dipendono dall'ottimizzatore utilizzato; per i dettagli consulta la documentazione dell'ottimizzatore | MD | {"maxiter": 50 } |
| initialization | Optional[Literal["RANDOM", "PHYSICALLY_INFORMED"]] | Se iniziare con angoli casuali o scelti in modo intelligente. Tieni presente che gli angoli scelti in modo intelligente potrebbero non funzionare nel 100% dei casi. Il valore predefinito è "PHYSICALLY_INFORMED". | No | "RANDOM" |
| backend_name | Optional[str] | Il nome del backend da utilizzare. | No | "ibm_torino" |
| mode | Optional[Literal["job", "session", "batch"]] | La modalità di esecuzione da utilizzare. Il valore predefinito è "job". | No | "job" |
I parametri dell'equazione differenziale (parametri fisici e condizione al contorno) devono seguire il formato indicato:
| Caso d'uso | Chiave | Tipo valore | Descrizione | Esempio |
|---|---|---|---|---|
| CFD | a | float | Coefficiente dei valori iniziali di | 1.0 |
| CFD | b | float | Offset dei valori iniziali di | 1.0 |
| MD | t | float | tensione superficiale | 12.0 |
| MD | K | float | modulo di compressione | 100.0 |
| MD | n | int | legge di potenza | 4.0 |
| MD | b | float | forza per unità di massa | 10.0 |
| MD | epsilon_0 | float | limite di proporzionalità della tensione | 0.1 |
| MD | sigma_0 | float | limite di proporzionalità della deformazione | 5.0 |
Output​
L'output è un dizionario con la lista dei punti campione e i valori delle funzioni in ciascuno di questi punti:
# 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 di un array soluzione dipende dai campioni delle variabili:
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 corrispondenza tra i punti campione delle variabili della funzione e la dimensione dell'array soluzione avviene in ordine alfanumerico del nome della variabile. Ad esempio, se le variabili sono "t" e "x", una riga di solution["functions"]["u"] rappresenta i valori della soluzione per un "t" fisso, mentre una colonna di solution["functions"]["u"] rappresenta i valori della soluzione per un "x" fisso.
Il seguente è un esempio di come ottenere il valore della funzione per un insieme specifico di coordinate:
# 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
Benchmark​
La tabella seguente presenta statistiche su varie esecuzioni della nostra funzione.
| Esempio | Numero di qubit | Inizializzazione | Errore | Tempo totale (min) | Utilizzo runtime (min) |
|---|---|---|---|---|---|
| Equazione di Burgers non viscosa | 50 | PHYSICALLY_INFORMED | 66 | 25 | |
| Test di trazione ipoelastico 1D | 18 | RANDOM | 123 | 100 |
Per iniziare​
Compila il modulo per richiedere l'accesso alla funzione QUICK-PDE. Quindi, supponendo che tu abbia già salvato il tuo account nel tuo ambiente locale, seleziona la funzione come segue:
from qiskit_ibm_catalog import QiskitFunctionsCatalog
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
quick = catalog.load("colibritd/quick-pde")
Esempi​
Per iniziare, prova uno dei seguenti esempi:
Fluidodinamica Computazionale (CFD)​
Quando le condizioni iniziali sono impostate su , i risultati sono i seguenti:
# 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})
Controlla lo stato del workload della tua Qiskit Function o recupera i risultati come segue:
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()

Deformazione dei Materiali​
Il caso d'uso della deformazione dei materiali richiede i parametri fisici del tuo materiale e la forza applicata, come segue:
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()
Recupero dei messaggi di errore​
Se lo stato del workload è ERROR, usa job.error_message() per recuperare il messaggio di errore e facilitare il debug, come segue:
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'
Supporto​
Per assistenza, contatta qiskit-function-support@colibritd.com.
Passi successivi​
- Compila il modulo per richiedere l'accesso alla funzione QUICK-PDE.
- Prova a modellare un fluido non viscoso in moto con QUICK-PDE nel tutorial.
- Consulta Jaffali, H., et al. (2025). H-DES: a Quantum-Classical Hybrid Differential Equation Solver. arXiv preprint arXiv:2410.01130.