Portuguese, Brazilian
Idiomas
English
Japanese
German
Korean
Portuguese, Brazilian
French
Shortcuts

Nota

Esta página foi gerada a partir do tutorials/chemistry/1_programmatic_approach.ipynb.

Execute interativamente no IBM Quantum lab.

Solucionadores de estado fundamental

Introdução

7000be2fe96b4d7aa37117384ce8aab9

Neste tutorial vamos discutir a interface de cálculo de estado fundamental do Qiskit Chemistry. O objetivo é computar o estado fundamental de um Hamiltoniano molecular. Este Hamiltoniano pode ser eletrônico ou vibrônico. Para saber mais sobre a preparação do Hamiltoniano, confira os tutoriais de Estrutura Eletrônica e Estrutura Vibrônica.

O primeiro passo é definir o sistema molecular. A seguir, pedimos a parte eletrônica de uma molécula de hidrogênio.

[2]:
from qiskit.chemistry.drivers import PySCFDriver, UnitsType, Molecule
from qiskit.chemistry.transformations import FermionicTransformation, FermionicQubitMappingType

molecule = Molecule(geometry=[['H', [0., 0., 0.]],
                              ['H', [0., 0., 0.735]]],
                     charge=0, multiplicity=1)
driver = PySCFDriver(molecule = molecule, unit=UnitsType.ANGSTROM, basis='sto3g')
transformation = FermionicTransformation(qubit_mapping=FermionicQubitMappingType.JORDAN_WIGNER)

O Solucionador

Então precisamos definir um solucionador. O solucionador é o algoritmo através do qual o estado fundamental é computado.

Let’s first start with a purely classical example: the NumPy minimum eigensolver. This algorithm exactly diagonalizes the Hamiltonian. Although it scales badly, it can be used on small systems to check the results of the quantum algorithms.

[8]:
from qiskit.aqua.algorithms import NumPyMinimumEigensolver

numpy_solver = NumPyMinimumEigensolver()

Para encontrar o estado fundamental que poderiamos também usar o algoritmo Variational Quantum Eigensolver (VQE). Os algoritmos de VQE funcionam trocando informações entre um computador clássico e um quântico como retratado na figura a seguir.

a2968392907a4d7e99295a9c977507a7

Vamos inicializar um solucionador VQE.

[9]:
from qiskit import BasicAer
from qiskit.aqua import QuantumInstance
from qiskit.chemistry.algorithms.ground_state_solvers.minimum_eigensolver_factories import VQEUCCSDFactory

vqe_solver = VQEUCCSDFactory(QuantumInstance(BasicAer.get_backend('statevector_simulator')))

Para definir o solucionador VQE precisamos de dois elementos essenciais:

  1. Uma forma variacional: aqui usamos o ansatz de Cluster Acoplado Unitário (UCC) (ver, por exemplo, [Physical Review A 98.2 (2018): 022322]). Uma vez que é um padrão da química, já está disponível uma fábrica que permite uma inicialização rápida de um VQE com um UCC. O padrão é usar todas as excitações simples e duplas. No entanto, o tipo de excitação (S, D, SD), bem como outros parâmetros podem ser selecionados.

  2. Um estado inicial: o estado inicial dos qubits. Na fábrica usada acima, os qubits são inicializados no estado inicial de Hartree-Fock (veja o tutorial de estrutura eletrônica) (os qubits correspondentes aos MOs ocupados são \(|1\rangle\) e aqueles que correspondem aos MOs virtuais são \(|0\rangle\).

  3. O backend: esta é a máquina quântica na qual a parte à direita da figura acima será executada. Aqui pedimos pelo emulador quântico perfeito (statevector_simulator).

Também poderia-se usar qualquer forma variacional disponível / estado inicial ou até mesmo definir um próprio. Por exemplo,

[10]:
from qiskit.aqua.algorithms import VQE
from qiskit.circuit.library import TwoLocal

num_qubits = 4
tl_circuit = TwoLocal(num_qubits, ['h', 'rx'], 'cz',
                      entanglement='full', reps=3, parameter_prefix = 'y')

tl_circuit.draw(output = 'mpl')

another_solver = VQE(var_form = tl_circuit,
                     quantum_instance = QuantumInstance(BasicAer.get_backend('statevector_simulator')))

O cálculo e os resultados

Estamos agora prontos para executar o cálculo.

[11]:
from qiskit.chemistry.algorithms.ground_state_solvers import GroundStateEigensolver

calc = GroundStateEigensolver(transformation, vqe_solver)
res = calc.solve(driver)

print(res)
=== GROUND STATE ENERGY ===

* Electronic ground state energy (Hartree): -1.857275030145
  - computed part:      -1.857275030145
  - frozen energy part: 0.0
  - particle hole part: 0.0
~ Nuclear repulsion energy (Hartree): 0.719968994449
> Total ground state energy (Hartree): -1.137306035696

=== MEASURED OBSERVABLES ===

  0:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000

=== DIPOLE MOMENTS ===

~ Nuclear dipole moment (a.u.): [0.0  0.0  1.3889487]

  0:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.38894909]
    - computed part:      [0.0  0.0  1.38894909]
    - frozen energy part: [0.0  0.0  0.0]
    - particle hole part: [0.0  0.0  0.0]
  > Dipole moment (a.u.): [0.0  0.0  -0.00000039]  Total: 0.00000039
                 (debye): [0.0  0.0  -0.000001]  Total: 0.000001

Podemos comparar os resultados do VQE com o solucionador exato NumPy e ver que eles correspondem.

[12]:
calc = GroundStateEigensolver(transformation, numpy_solver)
res = calc.solve(driver)
print(res)
=== GROUND STATE ENERGY ===

* Electronic ground state energy (Hartree): -1.857275030202
  - computed part:      -1.857275030202
  - frozen energy part: 0.0
  - particle hole part: 0.0
~ Nuclear repulsion energy (Hartree): 0.719968994449
> Total ground state energy (Hartree): -1.137306035753

=== MEASURED OBSERVABLES ===

  0:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000

=== DIPOLE MOMENTS ===

~ Nuclear dipole moment (a.u.): [0.0  0.0  1.3889487]

  0:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.3889487]
    - computed part:      [0.0  0.0  1.3889487]
    - frozen energy part: [0.0  0.0  0.0]
    - particle hole part: [0.0  0.0  0.0]
  > Dipole moment (a.u.): [0.0  0.0  0.0]  Total: 0.
                 (debye): [0.0  0.0  0.0]  Total: 0.

Usando uma função de filtro

Às vezes, o verdadeiro estado fundamental do Hamiltoniano não é de interesse, porque reside num sector de simetria diferente do espaço de Hilbert. Neste caso o NumPy eigensolver pode pegar uma função de filtro para retornar apenas os autoestados com, por exemplo, o número correto de partículas. Isto é particularmente importante no caso de cálculos de estruturas vibrônicas em que o verdadeiro estado fundamental do Hamiltonismo é o estado de vácuo. Uma função de filtro padrão para verificar o número de partículas é implementada nas diferentes transformações e pode ser usada como

[13]:
from qiskit.chemistry.drivers import GaussianForcesDriver
from qiskit.chemistry.algorithms.ground_state_solvers import NumPyMinimumEigensolverFactory
from qiskit.chemistry.transformations import (BosonicTransformation,
                                              BosonicTransformationType,
                                              BosonicQubitMappingType)

driver = GaussianForcesDriver(logfile='aux_files/CO2_freq_B3LYP_ccpVDZ.log')
bosonic_transformation = BosonicTransformation(qubit_mapping=BosonicQubitMappingType.DIRECT,
                                               transformation_type=BosonicTransformationType.HARMONIC,
                                               basis_size=2,
                                               truncation=2)

solver_without_filter = NumPyMinimumEigensolverFactory(use_default_filter_criterion=False)
solver_with_filter = NumPyMinimumEigensolverFactory(use_default_filter_criterion=True)

gsc_wo = GroundStateEigensolver(bosonic_transformation, solver_without_filter)
result_wo = gsc_wo.solve(driver)

gsc_w = GroundStateEigensolver(bosonic_transformation, solver_with_filter)
result_w = gsc_w.solve(driver)

print(result_wo)
print('\n\n')
print(result_w)
=== GROUND STATE ENERGY ===

* Vibronic ground state energy (cm^-1): (1e-12+0j)
The number of occupied modals is
- Mode 0: [0.0, 0.0, 0.0, 0.0]



=== GROUND STATE ENERGY ===

* Vibronic ground state energy (cm^-1): (2536.487976362422+0j)
The number of occupied modals is
- Mode 0: [1.0000000000000002, 1.0000000000000002, 1.0000000000000002, 1.0000000000000002]
/Users/aul/anaconda3/envs/QiskitPip/lib/python3.6/site-packages/qiskit/chemistry/results/vibronic_structure_result.py:73: DeprecationWarning: The Python built-in `round` is deprecated for complex scalars, and will raise a `TypeError` in a future release. Use `np.round` or `scalar.round` instead.
  format(round(self.computed_vibronic_energies[0], 12)))
/Users/aul/anaconda3/envs/QiskitPip/lib/python3.6/site-packages/qiskit/chemistry/results/vibronic_structure_result.py:73: DeprecationWarning: The Python built-in `round` is deprecated for complex scalars, and will raise a `TypeError` in a future release. Use `np.round` or `scalar.round` instead.
  format(round(self.computed_vibronic_energies[0], 12)))
[1]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
Qiskit0.23.0
Terra0.16.0
Aer0.7.0
Ignis0.5.0
Aqua0.8.0
IBM Q Provider0.11.0
System information
Python3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 13:42:17) [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
OSDarwin
CPUs2
Memory (Gb)16.0
Tue Oct 20 18:05:31 2020 CEST

This code is a part of Qiskit

© Copyright IBM 2017, 2020.

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.

[ ]: