Guia de Migração de Algoritmos#
TL;DR#
O módulo qiskit.algorithms
foi completamente refatorado para que use o primitives
, na execução de circuitos, em vez da QuantumInstance
, a qual está agora depreciada.
Temos 3 tipos de refatoração:
Algoritmos refatorados em uma nova localização a fim de suportar
primitives
. Esses algoritmos têm o mesmos nomes de classe que aquelas baseadas emQuantumInstance
-, mas estão em um novo sub-pacote.Atenção
Cuidado com caminhos de importação!! Os algoritmos legados ainda podem ser importados diretamente de
qiskit.algorithms
. Até que as importações legadas sejam removidas, essa importação de conveniência não estará disponível para os algoritmos refatorados. Portanto, para importar os algoritmos refatorados, você deve sempre especificar o caminho de importação completo (por exemplo,from qiskit.algorithms.eigensolvers import VQD
)Algoritmos refatorados in-place (mesmo namespace) para suportar ambos
QuantumInstance
eprimitives
. No futuro, o uso daQuantumInstance
será removido.Algoritmos que estavam depreciados e que agora foram totalmente removidos do
qiskit.algorithms
. Estes são algoritmos que atualmente não servem como blocos de construção para aplicativos. Seu principal valor é educacional e, como tal, serão mantidos como tutoriais no manual do qiskit. Você pode consultar os tutoriais nos seguintes links:
O restante deste guia de migração se concentrará nos algoritmos com alternativas de migração dentro de qiskit.algorithms
, ou seja, aqueles sob os tipos de refatoração 1 e 2.
Background#
De volta a TL;DR
O módulo qiskit.algorithms
foi originalmente construído sobre a biblioteca qiskit.opflow
e o utilitário QuantumInstance
. O desenvolvimento do primitives
introduziu um paradigma de execução de alto nível, com o Estimator
para cálculo de valores esperados para observáveis e Sampler
para circuitos de execução e retorno de distribuições de probabilidade. Essas ferramentas permitiram refatorar o módulo qiskit.algorithms
e descontinuar ambos qiskit.opflow
e QuantumInstance
.
Atenção
A transição de qiskit.opflow
afeta as classes que os algoritmos tomam como parte da configuração do problema. Como regra geral, a maioria das dependências qiskit.opflow
tem uma substituição direta de qiskit.quantum_info
. Um exemplo comum é a classe qiskit.opflow.PauliSumOp
, usada para definir Hamiltonianos (por exemplo, para conectar ao VQE), que pode ser substituída por qiskit.quantum_info.SparsePauliOp
. Para obter informações sobre como migrar outros objetos opflow
, você pode consultar o Guia de migração Opflow.
Para obter mais informações e passos detalhados de migração, consulte:
Como escolher uma configuração primitiva para seu algoritmo#
De volta a TL;DR
As classes em qiskit.algorithms
são inicializadas com qualquer implementação de qiskit.primitive.BaseSampler
ou class:qiskit.primitive.BaseEstimator.
Uma vez conhecido o tipo de primitiva, você pode escolher entre as implementações primitivas que melhor se ajustam ao seu caso. Por exemplo:
Para prototipagem rápida, você pode usar as reference implementations of primitives inclusas no Qiskit:
qiskit.primitives.Sampler
eqiskit.primitives.Estimator
.Para um ajuste mais fino do algoritmo, um simulador local como a primitive implementation in Aer:
qiskit_aer.primitives.Sampler
eqiskit_aer.primitives.Estimator
.Para executar em um hardware quântico, você pode:
acessar serviços com implementações primitivas nativas, como IBM’s Qiskit Runtime service via
qiskit_ibm_runtime.Sampler
eqiskit_ibm_runtime.Estimator
Encapsule qualquer backend com Backend Primitives (
BackendSampler
eBackendEstimator
). Esses wrappers implementam uma interface primitiva em cima de um backend que suporta apenasBackend.run()
.
Para obter informações e exemplos mais detalhados, particularmente sobre o uso de Backend Primitives, consulte o Guia de Migração de Quantum Instance.
Neste guia, abordaremos 3 configurações comuns diferentes para algoritmos que determinam qual importação primitiva você deve selecionar:
Executando um algoritmo com um simulador de vetor de estado (ou seja, usando a
MatrixExpectation
legada deqiskit.opflow
), quando você desejar um resultado ideal sem ruído de execução:Primitivas Aer com simulador de vetores de estado (consulte o exemplo de QAOA):
from qiskit.primitives import Sampler, Estimator
Primitivas Aer com simulador de vetores de estado (consulte o exemplo de QAOA):
from qiskit_aer.primitives import Sampler, Estimator sampler = Sampler(backend_options={"method": "statevector"}) estimator = Estimator(backend_options={"method": "statevector"})
Executando um algoritmo usando um simulador/dispositivo com ruído de shot (ou seja, usando a classe legada
PauliExpectation
do móduloqiskit.opflow
):Primitivas de Referência com shots (consulte exemplos de VQE):
from qiskit.primitives import Sampler, Estimator sampler = Sampler(options={"shots": 100}) estimator = Estimator(options={"shots": 100}) # or... sampler = Sampler() job = sampler.run(circuits, shots=100) estimator = Estimator() job = estimator.run(circuits, observables, shots=100)
Primitivas Aer com configuração padrão (consulte exemplos de VQE):
from qiskit_aer.primitives import Sampler, Estimator
Primitivas IBM’s Qiskit Runtime com configuração padrão (consulte o exemplo de VQD):
from qiskit_ibm_runtime import Sampler, Estimator
3. Running an algorithm on an Aer simulator using a custom instruction (i.e., using qiskit.opflow
's legacy
AerPauliExpectation
):
Primitivas Aer com
shots=None
,approximation=True
(consulte o exemplo de TrotterQRTE):from qiskit_aer.primitives import Sampler, Estimator sampler = Sampler(run_options={"approximation": True, "shots": None}) estimator = Estimator(run_options={"approximation": True, "shots": None})
Eigensolvers mínimos#
De volta a TL;DR
Os algoritmos eigensolver mínimos pertencem ao primeiro tipo de refatoração listado acima (Algoritmos refatorados em um novo local para suportar primitives
). Em vez de uma QuantumInstance
, qiskit.algorithms.minimum_eigensolvers
agora são inicializados usando uma instância de Sampler
ou Estimator
primitivo, dependendo do algoritmo. As classes legadas ainda podem ser encontradas em qiskit.algorithms.minimum_eigen_solvers
.
Atenção
Para as classes qiskit.algorithms.minimum_eigensolvers
, dependendo do caminho de importação, você acessará a implementação baseada em primitiva ou baseada em instância quântica. Você tem que ter muito cuidado, porque o nome da classe não muda.
Antigas importações (baseadas em instancia Quantum):
from qiskit.algorithms import VQE, QAOA, NumPyMinimumEigensolver
Novas importações (baseadas em Primitives):
from qiskit.algorithms.minimum_eigensolvers import VQE, SamplingVQE, QAOA, NumPyMinimumEigensolver
VQE#
A classe legada qiskit.algorithms.minimum_eigen_solvers.VQE
foi dividida de acordo com os casos de uso:
Para Hamiltonianos de uso geral, você pode usar a classe
qiskit.algorithms.minimum_eigensolvers.VQE
baseada na Estimator.Se você tiver um Hamiltoniano diagonal e quiser que o algoritmo retorne uma amostra do estado, você pode usar o novo algoritmo
qiskit.algorithms.minimum_eigensolvers.SamplingVQE
baseado em Sampler. Anteriormente, isso poderia ser realizado usando a classe legadaVQE
com aCVaRExpectation
.
Nota
Além de receber uma instância Estimator
em vez de uma QuantumInstance
, a nova assinatura VQE
sofreu as seguintes alterações:
Os parâmetros
expectation
einclude_custom
foram removidos, já que esta funcionalidade agora é definida no nível deEstimator
.O parâmetro
gradient
agora usa uma instância de uma classe de gradiente baseada em primitiva deqiskit.algorithms.gradients
em vez da classeqiskit.opflow.gradients.Gradient
herdada.O parâmetro
max_evals_grouped
foi removido, pois pode ser definido diretamente na classe optimizer.O
estimator
,ansatz
eoptimizer
são os únicos parâmetros que podem ser definidos posicionalmente (e nesta ordem), todos os outros se tornaram argumentos keyword-only.
Nota
A nova classe VQEResult
não inclui mais o estado, pois esta saída só foi útil no caso de operadores diagonais. No entanto, se estiver disponível como parte da classe SamplingVQEResult
da nova classe SamplingVQE
’s .
Para obter exemplos de código completos, consulte os seguintes tutoriais atualizados:
QAOA#
A classe qiskit.algorithms.minimum_eigen_solvers.QAOA
legada usada para estender qiskit.algorithms.minimum_eigen_solvers.VQE
, mas agora, a qiskit.algorithms.minimum_eigensolvers.QAOA
estende :class: qiskit.algorithms.minimum_eigensolvers.SamplingVQE. Por esta razão, o novo QAOA suporta apenas operadores diagonais.
Nota
Além de receber uma instância de Sampler
em vez de uma QuantumInstance
, a nova assinatura da classe QAOA
sofreu as seguintes alterações:
Os parâmetros
expectation
einclude_custom
foram removidos. Em troca, o parâmetroaggregation
foi adicionado (costumava ser definido através de umaexpectation
adaptada).O parâmetro
gradient
agora usa uma instância de uma classe de gradiente baseada em primitiva deqiskit.algorithms.gradients
em vez da classeqiskit.opflow.gradients.Gradient
herdada.O parâmetro
max_evals_grouped
foi removido, pois pode ser definido diretamente na classe optimizer.O
sampler
eoptimizer
são os únicos parâmetros que podem ser definidos posicionalmente (e nesta ordem), todos os outros se tornaram parâmetros keyword-only.
Nota
Se você deseja executar QAOA em um operador não diagonal, pode usar a QAOAAnsatz
com qiskit.algorithms.minimum_eigensolvers.VQE
, mas tenha em mente que não haverá resultado de estado. Se seu aplicativo requer a distribuição de probabilidade final, você pode instanciar um Sampler
e executá-lo com o circuito ideal após a VQE
.
Para obter exemplos de código completos, consulte os seguintes tutoriais atualizados:
NumPyMinimumEigensolver#
Como este é um solucionador clássico, o fluxo de trabalho não mudou entre a implementação antiga e a nova. No entanto, a importação mudou de qiskit.algorithms.minimum_eigen_solvers.NumPyMinimumEigensolver
para qiskit.algorithms.minimum_eigensolvers.NumPyMinimumEigensolver
para se adequar às novas interfaces e classes de resultados.
Para obter exemplos de código completos, consulte os seguintes tutoriais atualizados:
Eigensolver#
De volta a TL;DR
Os algoritmos eigensolver também pertencem ao primeiro tipo de refatoração (Algoritmos refatorados em um novo local para suportar primitives
). Em vez de uma QuantumInstance
, qiskit.algorithms.eigensolvers
eles agora são inicializados usando uma instância de Sampler
ou Estimator
primitivo, ou uma sub-rotina baseada em primitivo, dependendo do algoritmo. As classes legadas ainda podem ser encontradas em qiskit.algorithms.eigen_solvers
.
Atenção
Para as classes de qiskit.algorithms.eigensolvers
, dependendo do caminho de importação, você acessará a implementação baseada em primitivas ou baseada em instância quântica. Você tem que ter muito cuidado, porque o nome da classe não muda.
Antigo caminho de importação (Instância Quantum):
from qiskit.algorithms import VQD, NumPyEigensolver
Novo caminho de importação (Primitivas):
from qiskit.algorithms.eigensolvers import VQD, NumPyEigensolver
VQD#
A nova classe qiskit.algorithms.eigensolvers.VQD
é inicializada com uma instância de Estimator
ao invés de uma QuantumInstance
. Além disso, ela usa uma instância de uma classe de fidelidade de estado de mod:qiskit.algorithms.state_fidelities, como a Sampler
baseada em ComputeUncompute
.
Nota
Além de receber uma instância de Estimator
em vez de uma QuantumInstance
, a nova assinatura da VQD
sofreu as seguintes alterações:
Os parâmetros
expectation
einclude_custom
foram removidos, já que esta funcionalidade agora é definida no nível deEstimator
.O parâmetro personalizado
fidelity
foi adicionado e o parâmetro personalizadogradient
foi removido, pois as classes atuais emqiskit.algorithms.gradients
não podem lidar com gradientes de fidelidade de estado.O parâmetro
max_evals_grouped
foi removido, pois pode ser definido diretamente na classe optimizer.O
estimator
,fidelity
,ansatz
eoptimizer
são os únicos parâmetros que podem ser definidos posicionalmente (e nesta ordem), todos os outros se tornaram parâmetros keyword-only.
Nota
Da mesma forma que o VQE, a nova classe VQDResult
não inclui mais o estado. Se sua aplicação exige a distribuição de probabilidade final, você pode instanciar um Sampler
e executá-lo com o circuito ideal para o estado excitado desejado após executar a classe VQD
.
Para obter exemplos de código completos, consulte o seguinte tutorial atualizado:
NumPyEigensolver#
Da mesma forma que a contraparte do minimum eigensolver, uma vez que este é um solucionador clássico, o fluxo de trabalho não mudou entre a implementação antiga e a nova. No entanto, a importação mudou de qiskit.algorithms.eigen_solvers.NumPyEigensolver
para qiskit.algorithms.eigensolvers.MinimumEigensolver
para se adequar às novas interfaces e classes de resultado.
Time Evolvers#
De volta a TL;DR
Os evoluidores de tempo são o último grupo de algoritmos a passar pelo primeiro tipo de refatoração (Algoritmos refatorados em um novo local para suportar primitives
). Em vez de QuantumInstance
, qiskit.algorithms.time_evolvers
agora são inicializados usando uma instância da primitiva Estimator
. As classes legadas ainda podem ser encontradas em qiskit.algorithms.evolvers
.
Além da migração, o módulo foi substancialmente expandido para incluir Variational Quantum Time Evolution (VarQTE
).
TrotterQRTE#
Atenção
Para a classe qiskit.algorithms.time_evolvers.TrotterQRTE
, dependendo do caminho de importação, você acessará a implementação baseada em primitiva ou baseada em instância quântica. Você tem que ter muito cuidado, porque o nome da classe não muda.
Antigo caminho de importação (Quantum Instance):
from qiskit.algorithms import TrotterQRTE
Novo caminho de importação (Primitives):
from qiskit.algorithms.time_evolvers import TrotterQRTE
Nota
Além de receber uma instância de Estimator
em vez de uma QuantumInstance
, a nova assinatura da VQD
sofreu as seguintes alterações:
O parâmetro
expectation
foi removido, já que esta funcionalidade agora é definida no nívelEstimator
.Os parâmetros
num_timesteps
foram adicionados, para permitir definir o número de etapas em que o tempo de evolução completo é dividido.
Amplificadores de Amplitude#
De volta a TL;DR
Os algoritmos amplificadores de amplitude pertencem ao segundo tipo de refatoração (Algoritmos refatorados no local). Em vez de uma classe QuantumInstance
, qiskit.algorithms.amplitude_amplifiers
agora são inicializados usando uma instância de qualquer primitiva «Sampler», por exemplo Sampler
.
Nota
O módulo completo qiskit.algorithms.amplitude_amplifiers
foi refatorado no lugar. Não há necessidade de alterar os caminhos de importação.
Para obter exemplos de código completos, consulte os seguintes tutoriais atualizados:
Estimadores de Amplitude#
De volta a TL;DR
Da mesma forma que os amplificadores de amplitude, os estimadores de amplitude também pertencem ao segundo tipo de refatoração (Algoritmos refatorados no local). Em vez de uma classe QuantumInstance
, qiskit.algorithms.amplitude_estimators
agora são inicializados usando uma instância de qualquer primitiva «Sampler», por exemplo Sampler
.
Nota
O módulo completo qiskit.algorithms.amplitude_estimators
foi refatorado no local. Não há necessidade de alterar os caminhos de importação.
Para obter exemplos de código completos, consulte os seguintes tutoriais atualizados:
Estimadores de fase#
De volta a TL;DR
Finalmente, os estimadores de fase são o último grupo de algoritmos a passar pelo primeiro tipo de refatoração (Algoritmos refatorados no local). Em vez de uma classe QuantumInstance
, qiskit.algorithms.phase_estimators
agora são inicializados usando uma instância de qualquer primitiva «Sampler», por exemplo Sampler
.
Nota
O módulo qiskit.algorithms.phase_estimators
completo foi refatorado. Não há necessidade de alterar os caminhos de importação.
Para obter exemplos de código completos, consulte os seguintes tutoriais atualizados: