Portuguese
Idiomas
English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

Nota

Esta página foi gerada a partir de tutorials/algorithms/01_algorithms_introduction.ipynb.

Uma introdução aos Algoritmos no Qiskit

Esta é uma introdução aos algoritmos no Qiskit e fornece uma visão geral de alto nível para ajudar a entender os vários aspectos da funcionalidade a ser iniciado. Outros tutoriais fornecerão material mais aprofundado, sobre os algoritmos, e formas de usá-los, etc.

Como a biblioteca de algoritmos está estruturada?

O Qiskit fornece vários Algoritmos e eles são agrupados por categoria de acordo com a tarefa que podem executar. Por exemplo Minimum Eigensolvers para encontrar o menor autovalor de um operador, por exemplo energia do estado fundamental de um hamiltoniano químico ou uma solução para um problema de otimização quando expresso como um hamiltoniano de Ising. Existem Time Evolvers para a evolução temporal de sistemas quânticos e Amplitude Estimators para estimativa de valor que podem ser usados, digamos, em aplicações financeiras. O conjunto completo de categorias pode ser visto no link de documentação de algoritmos acima.

Algoritmos são configuráveis e muitas vezes parte da configuração estará na forma de blocos de construção menores, de que instâncias diferentes do tipo bloco de construção podem ser fornecidas. Por exemplo, com VQE, o Variacional Quantum Eigensolver, precisa de uma função de onda experimental, na forma de um QuantumCircuit e um otimizador clássico entre outras coisas.

Vamos dar uma olhada em um exemplo para construir uma instância de VQE. Aqui «TwoLocal» é a forma variacional (versão de ondas de teste), um circuito parametrizado que pode ser variado e «SLSQP» um otimizador clássico. Estas são criadas como instâncias separadas e transmitidas para o VQE quando este é construído. Tentando, por exemplo, um otimizador clássico diferente, ou forma variacional é simplesmente um caso de criação de uma instância da que você deseja e a passagem para o VQE.

[1]:
from qiskit.algorithms.optimizers import SLSQP
from qiskit.circuit.library import TwoLocal

num_qubits = 2
ansatz = TwoLocal(num_qubits, "ry", "cz")
optimizer = SLSQP(maxiter=1000)

Vamos desenhar o ansatz para que possamos ver que é um QuantumCircuit onde θ[0] até θ[7] serão os parâmetros variados conforme o otimizador do VQE encontrar o autovalor mínimo. Voltaremos aos parâmetros mais tarde, em um exemplo abaixo.

[2]:
ansatz.decompose().draw("mpl", style="iqx")
[2]:
../../_images/tutorials_algorithms_01_algorithms_introduction_4_0.png

Mas é necessário um pouco mais antes que possamos executar o algoritmo, então vamos em frente.

Como executar um algoritmo?

Os algoritmos dependem das primitivas para avaliar valores esperados ou circuitos de amostra. As primitivas podem ser baseadas em um simulador ou dispositivo real e podem ser usadas de forma intercambiável nos algoritmos, pois todas implementam a mesma interface.

No VQE, temos que avaliar os valores esperados, então, por exemplo, podemos usar o qiskit.primitives.Estimator que é fornecido com a instalação padrão do Qiskit Terra.

[3]:
from qiskit.primitives import Estimator

estimator = Estimator()

Esse estimador usa uma simulação exata de vetor de estado para avaliar os valores esperados. Também podemos usar simuladores ruidosos e baseados em tiro ou back-ends reais. Para obter mais informações sobre os simuladores, você pode conferir Qiskit Aer e para o hardware real Qiskit IBM Runtime.

Com todos os ingredientes prontos, podemos agora instanciar o VQE:

[4]:
from qiskit.algorithms.minimum_eigensolvers import VQE

vqe = VQE(estimator, ansatz, optimizer)

Agora podemos chamar o método compute_mininum_eigenvalue(). Esta última é a interface escolhida para os módulos do aplicativo, como Natureza e Otimização, para que possam funcionar de forma intercambiável com qualquer algoritmo dentro da categoria específica.

Um exemplo de trabalho completo

Vamos juntar tudo o que aprendemos acima e criar um exemplo completo. O VQE irá encontrar o autovalor mínimo, ou seja, mínimo valor de energia de um operador hamiltoniano e, portanto, precisamos de um operador que o VQE possa utilizar. Um operador desse tipo é fornecido abaixo. Ele foi criado pelo módulo de aplicação Nature como o hamiltoniano de uma molécula de H2 à distância interatômica de 0,735A. É uma soma de termos Pauli como mostrado abaixo, mas, por enquanto, não vamos tratar disso, já que o objetivo é executar o algoritmo, mas é bom saber que informações adicionais sobre operadores podem ser encontradas em outros tutoriais.

[5]:
from qiskit.quantum_info import SparsePauliOp

H2_op = SparsePauliOp.from_list([
    ("II", -1.052373245772859),
    ("IZ", 0.39793742484318045),
    ("ZI", -0.39793742484318045),
    ("ZZ", -0.01128010425623538),
    ("XX", 0.18093119978423156)
])

Então, vamos executar o VQE e imprimir o resultado que ele retorna.

[6]:
result = vqe.compute_minimum_eigenvalue(H2_op)
print(result)
{   'aux_operators_evaluated': None,
    'cost_function_evals': 102,
    'eigenvalue': -1.857275020719397,
    'optimal_circuit': <qiskit.circuit.library.n_local.two_local.TwoLocal object at 0x7f96da26a470>,
    'optimal_parameters': {   ParameterVectorElement(θ[0]): -2.403507257619715,
                              ParameterVectorElement(θ[5]): 1.7060524493254914,
                              ParameterVectorElement(θ[1]): 3.085467047665086,
                              ParameterVectorElement(θ[2]): -2.1949965223522487,
                              ParameterVectorElement(θ[3]): 4.276089268519914,
                              ParameterVectorElement(θ[4]): -3.098644972035885,
                              ParameterVectorElement(θ[6]): 0.032773583818940334,
                              ParameterVectorElement(θ[7]): 2.8861019033185396},
    'optimal_point': array([-2.40350726,  3.08546705, -2.19499652,  4.27608927, -3.09864497,
        1.70605245,  0.03277358,  2.8861019 ]),
    'optimal_value': -1.857275020719397,
    'optimizer_evals': None,
    'optimizer_result': <qiskit.algorithms.optimizers.optimizer.OptimizerResult object at 0x7f96da2a4d60>,
    'optimizer_time': 0.29071593284606934}

A partir do resultado acima, podemos ver o número de avaliações da função de custo (=energia) que o otimizador levou até encontrar o autovalor mínimo de \(\approx -1.85727\), que é a energia eletrônica do estado fundamental da molécula de H2 dada. Os parâmetros ótimos do ansatz também podem ser vistos quais são os valores que estavam no ansatz no valor mínimo.

Atualizando a primitiva dentro do VQE

Para fechar, vamos também alterar a primitiva do estimador dentro de um VQE. Talvez você esteja satisfeito com os resultados da simulação e agora queira usar um simulador baseado em lançamentos ou rodar em um hardware!

Neste exemplo, estamos mudando para um estimador baseado em «shots», ainda usando a primitiva de referência do Qiskit Terra. No entanto, você pode substituir a primitiva pelo estimador Qiskit Aer (qiskit_aer.primitives.Estimator), por exemplo,  ou até mesmo por um backend real (qiskit_ibm_runtime.Estimator).

Para funções de perda ruidosa, o otimizador SPSA normalmente funciona bem, então também atualizamos o otimizador. Veja também o noisy VQE tutorial para obter mais detalhes sobre simulações ruidosas e baseadas em shots.

[7]:
from qiskit.algorithms.optimizers import SPSA

estimator = Estimator(options={"shots": 1000})

vqe.estimator = estimator
vqe.optimizer = SPSA(maxiter=100)
result = vqe.compute_minimum_eigenvalue(operator=H2_op)
print(result)
{   'aux_operators_evaluated': None,
    'cost_function_evals': 200,
    'eigenvalue': -1.8574503552440247,
    'optimal_circuit': <qiskit.circuit.library.n_local.two_local.TwoLocal object at 0x7f96da2f4250>,
    'optimal_parameters': {   ParameterVectorElement(θ[0]): -7.7940259581467375,
                              ParameterVectorElement(θ[5]): 0.28827257835035214,
                              ParameterVectorElement(θ[1]): -1.8091021117029589,
                              ParameterVectorElement(θ[2]): -2.460381278734678,
                              ParameterVectorElement(θ[3]): -7.725013961075425,
                              ParameterVectorElement(θ[4]): -1.3793338621798832,
                              ParameterVectorElement(θ[6]): -2.4148423942537587,
                              ParameterVectorElement(θ[7]): -1.8555574263247812},
    'optimal_point': array([-7.79402596, -1.80910211, -2.46038128, -7.72501396, -1.37933386,
        0.28827258, -2.41484239, -1.85555743]),
    'optimal_value': -1.8574503552440247,
    'optimizer_evals': None,
    'optimizer_result': <qiskit.algorithms.optimizers.optimizer.OptimizerResult object at 0x7f96da26a5f0>,
    'optimizer_time': 0.8142139911651611}

Observação: não corrigimos a semente aleatória nos simuladores aqui, portanto, a reexecução fornece resultados ligeiramente variáveis.

Isso conclui essa introdução aos algoritmos no Qiskit. Confira os outros tutoriais de algoritmos nesta série para uma cobertura mais ampla e mais profunda dos algoritmos.

[8]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
qiskit-terra0.23.0.dev0+f52bb33
qiskit-aer0.11.1
qiskit-ignis0.7.1
qiskit-ibmq-provider0.19.2
qiskit-nature0.5.0
qiskit-optimization0.5.0
qiskit-machine-learning0.6.0
System information
Python version3.10.4
Python compilerClang 12.0.0
Python buildmain, Mar 31 2022 03:38:35
OSDarwin
CPUs4
Memory (Gb)32.0
Wed Dec 07 11:02:26 2022 CET

This code is a part of Qiskit

© Copyright IBM 2017, 2022.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

[ ]: