QUICK-PDE: Uma Função Qiskit da ColibriTD
As Funções Qiskit são um recurso experimental disponível para usuários dos planos IBM Quantum® Premium, Flex e On-Prem (via API da IBM Quantum Platform). Elas estão em status de versão prévia e sujeitas a alterações.
Visão geral
O solver de Equações Diferenciais Parciais (EDP) apresentado aqui faz parte da nossa plataforma Quantum Innovative Computing Kit (QUICK) (QUICK-PDE), e é disponibilizado como uma Função Qiskit. Com a função QUICK-PDE, você pode resolver equações diferenciais parciais específicas de domínio em QPUs da IBM Quantum. Esta função é baseada no algoritmo descrito no artigo de descrição do H-DES da ColibriTD. Esse algoritmo pode resolver problemas complexos de múltipla física, começando com Dinâmica de Fluidos Computacional (DFC) e Deformação de Materiais (DM), com outros casos de uso chegando em breve.
Para lidar com as equações diferenciais, as soluções tentativas são codificadas como combinações lineares de funções ortogonais (tipicamente polinômios de Chebyshev, e mais especificamente deles, onde é o número de qubits que codificam sua função), parametrizadas pelos ângulos de um Circuito Quântico Variacional (VQC). O ansatz gera um estado que codifica a função, avaliado por observáveis cujas combinações permitem calcular a função em todos os pontos. Você pode então avaliar a função de perda na qual as equações diferenciais são codificadas e ajustar os ângulos em um laço híbrido, como mostrado a seguir. As soluções tentativas se aproximam gradualmente das soluções reais até que você alcance um resultado satisfatório.
Além desse laço híbrido, você também pode encadear diferentes otimizadores. Isso é útil quando você quer que um otimizador global encontre um bom conjunto de ângulos e, em seguida, um otimizador mais refinado siga um gradiente até o melhor conjunto de ângulos vizinhos. No caso de dinâmica de fluidos computacional (DFC), a sequência de otimização padrão produz os melhores resultados — mas no caso de deformação de materiais (DM), embora o padrão forneça bons resultados, você pode configurá-lo para benefícios específicos do problema.
Observe que, para cada variável da função, especificamos o número de qubits (com o qual você pode experimentar). Ao empilhar 10 circuitos idênticos e avaliar os 10 observáveis idênticos em qubits diferentes ao longo de um único circuito grande, você pode mitigar ruído dentro do processo de otimização CMA, confiando no método de aprendizado de ruído, e reduzir significativamente o número de shots necessários.
Entrada/saída
Dinâmica de Fluidos Computacional
A equação de Burgers invíscida modela fluidos não viscosos em escoamento da seguinte forma:
representa o campo de velocidade do fluido. Esse caso de uso tem uma condição de contorno temporal: você pode selecionar a condição inicial e então permitir que o sistema relaxe. Atualmente, as únicas condições iniciais aceitas são funções lineares: .
Os argumentos para as equações diferenciais da DFC estão em uma grade fixa, como segue:
- está entre 0 e 0,95 com 30 pontos de amostra. está entre 0 e 0,95 com um tamanho de passo de 0,2375.
Deformação de Materiais
Este caso de uso foca na deformação hipoelástica com o teste de tração unidimensional, no qual uma barra fixada no espaço é puxada em sua outra extremidade. Descrevemos o problema da seguinte forma:
representa o módulo volumétrico do material sendo esticado, o expoente de uma lei de potência, a força por unidade de massa, o limite de tensão proporcional, o limite de deformação proporcional, a função de tensão e a função de deformação.
A barra considerada tem comprimento unitário. Este caso de uso tem uma condição de contorno para a tensão superficial , ou seja, a quantidade de trabalho necessária para esticar a barra.
Os argumentos para as equações diferenciais da DM estão em uma grade fixa, como segue:
- está entre 0 e 1 com um tamanho de passo de 0,04.
Entrada
Para executar a Função Qiskit QUICK-PDE, você pode ajustar os seguintes parâmetros:
| Nome | Tipo | Descrição | Específico do caso de uso | Exemplo |
|---|---|---|---|---|
| use_case | Literal["MD", "CFD"] | Opção para selecionar o sistema de equações diferenciais a resolver | Não | "CFD" |
| parameters | dict[str, Any] | Parâmetros da equação diferencial (veja a próxima tabela para mais detalhes) | Não | {"a": 1.0, "b": 1.0} |
| nb_qubits | Optional[dict[str, dict[str, int]]] | Número de qubits por função e por variável. Valores otimizados são escolhidos pela função, mas se você quiser tentar encontrar uma combinação melhor, pode substituir os valores padrão | Não | {"u": {"x": 1, "t":3}} |
| depth | Optional[dict[str, int]] | Profundidade do ansatz por função. Valores otimizados são escolhidos pela função, mas se você quiser tentar encontrar uma combinação melhor, pode substituir os valores padrão | Não | {"u": 4} |
| optimizer | Optional[list[str]] | Otimizadores a serem usados, sendo "CMAES" da biblioteca python cma ou um dos otimizadores do scipy | DM | "SLSQP" |
| shots | Optional[list[int]] | Número de shots usados para executar cada circuito. Como vários passos de otimização são necessários, o comprimento da lista deve ser igual ao número de otimizadores usados (4 no caso de DFC). O padrão é [50_000] * nb_optimizers para DM e [5_00, 2_000, 5_000, 10_000] para DFC | Não | [15_000, 30_000] |
| optimizer_options | Optional[dict[str, Any]] | Opções a passar para o otimizador. Os detalhes desta entrada dependem do otimizador usado; para especificidades, consulte a documentação do otimizador utilizado | DM | {"maxiter": 50 } |
| initialization | Optional[Literal["RANDOM", "PHYSICALLY_INFORMED"]] | Se deve começar com ângulos aleatórios ou ângulos escolhidos de forma inteligente. Atenção: ângulos escolhidos de forma inteligente podem não funcionar em 100% dos casos. O padrão é "PHYSICALLY_INFORMED". | Não | "RANDOM" |
| backend_name | Optional[str] | O nome do backend a usar. | Não | "ibm_torino" |
| mode | Optional[Literal["job", "session", "batch"]] | O modo de execução a usar. O padrão é "job". | Não | "job" |
Os parâmetros da equação diferencial (parâmetros físicos e condição de contorno) devem seguir o formato fornecido:
| Caso de uso | Chave | Tipo do valor | Descrição | Exemplo |
|---|---|---|---|---|
| DFC | a | float | Coeficiente dos valores iniciais de | 1.0 |
| DFC | b | float | Deslocamento dos valores iniciais de | 1.0 |
| DM | t | float | tensão superficial | 12.0 |
| DM | K | float | módulo volumétrico | 100.0 |
| DM | n | int | lei de potência | 4.0 |
| DM | b | float | força por unidade de massa | 10.0 |
| DM | epsilon_0 | float | limite de tensão proporcional | 0.1 |
| DM | sigma_0 | float | limite de deformação proporcional | 5.0 |
Saída
A saída é um dicionário com a lista de pontos de amostra, bem como os valores das funções em cada um desses pontos:
# 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]),
},
}
O formato de um array de solução depende das amostras das variáveis:
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)
O mapeamento entre os pontos de amostra das variáveis da função e as dimensões do array de solução é feito em ordem alfanumérica do nome da variável. Por exemplo, se as variáveis são "t" e "x", uma linha de solution["functions"]["u"] representa os valores da solução para um "t" fixo, e uma coluna de solution["functions"]["u"] representa os valores da solução para um "x" fixo.
A seguir há um exemplo de como obter o valor da função para um 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
A tabela a seguir apresenta estatísticas sobre várias execuções da nossa função.
| Exemplo | Número de qubits | Inicialização | Erro | Tempo total (min) | Uso do runtime (min) |
|---|---|---|---|---|---|
| Equação de Burgers invíscida | 50 | PHYSICALLY_INFORMED | 66 | 25 | |
| Teste de tração hipoelástico 1D | 18 | RANDOM | 123 | 100 |
Primeiros passos
Preencha o formulário para solicitar acesso à função QUICK-PDE. Em seguida, assumindo que você já salvou sua conta em seu ambiente local, selecione a função da seguinte forma:
from qiskit_ibm_catalog import QiskitFunctionsCatalog
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
quick = catalog.load("colibritd/quick-pde")
Exemplos
Para começar, experimente um dos seguintes exemplos:
Dinâmica de Fluidos Computacional (DFC)
Quando as condições iniciais são definidas como , os resultados são os seguintes:
# 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})
Verifique o status ou retorne os resultados da carga de trabalho da sua Função Qiskit da seguinte forma:
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()

Deformação de Materiais
O caso de uso de deformação de materiais requer os parâmetros físicos do seu material e a força aplicada, da seguinte forma:
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()
Recuperar mensagens de erro
Se o status da sua carga de trabalho for ERROR, use job.error_message() para recuperar a mensagem de erro e ajudar na depuração, da seguinte forma:
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'
Obter suporte
Para suporte, entre em contato com qiskit-function-support@colibritd.com.
Próximos passos
- Preencha o formulário para solicitar acesso à função QUICK-PDE.
- Experimente modelar um fluido não viscoso em escoamento usando QUICK-PDE no tutorial.
- Consulte Jaffali, H., et al. (2025). H-DES: a Quantum-Classical Hybrid Differential Equation Solver. arXiv preprint arXiv:2410.01130.