H2 energy with various RY and RYRZ variational forms

This notebook demonstrates using Qiskit Aqua Chemistry to plot graphs of the ground state energy of the Hydrogen (H2) molecule using VQE with different variation form configurations. The results are compared to the same energy as computed by the ExactEigensolver

This notebook populates a dictionary, that is a progammatic representation of an input file, in order to drive the Qiskit Aqua Chemistry stack. Such a dictionary can be manipulated programmatically and this is indeed the case here.

This notebook has been written to use the PYSCF chemistry driver. See the PYSCF chemistry driver readme if you need to install the external PySCF library that this driver requires.


In [1]:
import numpy as np
import pylab
from qiskit_aqua_chemistry import AquaChemistry

# Input dictionary to configure Qiskit Aqua Chemistry for the chemistry problem.
aqua_chemistry_dict = {
    'problem': {'random_seed': 50},
    'driver': {'name': 'PYSCF'},
    'PYSCF': {'atom': 'H .0 .0 -0.3625; H .0 .0 0.3625', 'basis': 'sto3g'},
    'operator': {'name': 'hamiltonian', 'qubit_mapping': 'jordan_wigner',
                 'two_qubit_reduction': False},
    'algorithm': {'name': 'ExactEigensolver'},
    'optimizer': {'name': 'COBYLA', 'maxiter': 10000 },
    'variational_form': {'name': 'RYRZ', 'depth': 3, 'entanglement': 'full'},
    'initial_state': {'name': 'ZERO'}
}
var_forms = ['RYRZ', 'RY']
entanglements = ['full', 'linear']
depths = [x for x in range(3, 11)]

energies = np.empty([len(var_forms), len(entanglements), len(depths)])
hf_energy = None
energy = None
eval_counts = np.empty([len(var_forms), len(entanglements), len(depths)])

solver = AquaChemistry()
result = solver.run(aqua_chemistry_dict)
hf_energy = result['hf_energy']
energy = result['energy']
print('Hartree-Fock energy:', hf_energy)
print('FCI energy:', energy)


Hartree-Fock energy: -1.1173432691225829
FCI energy: -1.1372213770723043

With a reference FCI energy computed from ExactEigensolver we now compute the ground state energy with VQE and different variational form setups


In [2]:
aqua_chemistry_dict['algorithm']['name'] = 'VQE' 
print('Processing step __', end='')
for i, d in enumerate(depths):
    print('\b\b{:2d}'.format(i), end='', flush=True)
    aqua_chemistry_dict['variational_form']['depth'] = d
    for j in range(len(entanglements)):
        aqua_chemistry_dict['variational_form']['entanglement'] = entanglements[j] 
        for k in range(len(var_forms)):
            aqua_chemistry_dict['variational_form']['name'] = var_forms[k] 
            solver = AquaChemistry()
            result = solver.run(aqua_chemistry_dict)
            energies[k][j][i] = result['energy']
            eval_counts[k][j][i] = result['algorithm_retvals']['eval_count']
print(' --- complete')

print('Depths: ', depths)
print('Energies:', energies)
print('Num evaluations:', eval_counts)


Processing step  7 --- complete
Depths:  [3, 4, 5, 6, 7, 8, 9, 10]
Energies: [[[-1.11734327 -1.13697842 -1.13720129 -1.13719983 -1.13722136
   -1.13722136 -1.13722135 -1.13722137]
  [-1.1372213  -1.13721845 -1.13722128 -1.13714447 -1.13715117
   -1.13710957 -1.13721905 -1.13717202]]

 [[-1.13722043 -1.13722129 -1.13722093 -1.1372209  -1.13722136
   -1.13722136 -1.13722137 -1.13722137]
  [-1.13722134 -1.13722138 -1.13722136 -1.13722137 -1.13722137
   -1.13722137 -1.13722137 -1.13722137]]]
Num evaluations: [[[  770. 10000. 10000. 10000.  4018.  2982.  3503.  3571.]
  [ 5668. 10000.  4820. 10000. 10000. 10000. 10000. 10000.]]

 [[ 7196.  2785.  4062.  5296.  1744.  2008.  1127.  1219.]
  [ 1125.   380.  1105.   794.   952.   914.   706.   829.]]]

In [3]:
for k in range(len(var_forms)):
    for j in range(len(entanglements)):
        pylab.plot(depths, energies[k][j]-energy, label=var_forms[k]+' + '+entanglements[j])
pylab.xlabel('Variational form depth')
pylab.ylabel('Energy difference')
pylab.yscale('log')
pylab.title('H2 Ground State Energy Difference from Reference')
pylab.legend(loc='upper right')


Out[3]:
<matplotlib.legend.Legend at 0x10bfb1b38>

In [4]:
for k in range(len(var_forms)):
    for j in range(len(entanglements)):
        pylab.plot(depths, eval_counts[k][j], '-o', label=var_forms[k]+' + '+entanglements[j])
pylab.xlabel('Variational form depth')
pylab.ylabel('Evaluations')
pylab.title('VQE number of evaluations')
pylab.legend(loc='upper right')


Out[4]:
<matplotlib.legend.Legend at 0x10bd6ca58>

In [ ]: