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¶
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.
Vamos começar com um exemplo puramente clássico: o NumPy minimum eigensolver. Esse algoritmo diagonaliza exatamente o Hamiltoniano. Embora escalone mal, ele pode ser usado em sistemas pequenos para verificar os resultados dos algoritmos quânticos.
[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.
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:
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.
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\).
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 Software | Version |
---|---|
Qiskit | 0.23.0 |
Terra | 0.16.0 |
Aer | 0.7.0 |
Ignis | 0.5.0 |
Aqua | 0.8.0 |
IBM Q Provider | 0.11.0 |
System information | |
Python | 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 13:42:17) [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] |
OS | Darwin |
CPUs | 2 |
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.
[ ]: