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)

from qiskit import Aer
from qiskit.aqua import QuantumInstance
from qiskit.chemistry.algorithms.ground_state_solvers.minimum_eigensolver_factories import VQEUCCSDFactory

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

from qiskit.chemistry.algorithms.ground_state_solvers import GroundStateEigensolver

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

print(res)

from qiskit.aqua.algorithms import NumPyMinimumEigensolver

numpy_solver = NumPyMinimumEigensolver()

calc = GroundStateEigensolver(transformation, numpy_solver)
res = calc.solve(driver)
print(res)

import numpy as np

distances = np.linspace(0.25, 3.0, 30)
exact_energies = []
vqe_energies = []
for dist in distances:
    molecule = Molecule(geometry=[['H', [0., 0., 0.]],
                              ['H', [0., 0., dist]]],
                     charge=0, multiplicity=1)
    driver = PySCFDriver(molecule = molecule, unit=UnitsType.ANGSTROM, basis='sto3g')
    # Exact solver
    calc = GroundStateEigensolver(transformation, numpy_solver)
    res = calc.solve(driver)
    exact_energies.append(res.total_energies)
    # VQE
    calc = GroundStateEigensolver(transformation, vqe_solver)
    res = calc.solve(driver)
    vqe_energies.append(res.total_energies)
    

import matplotlib.pyplot as plt

plt.plot(exact_energies, label = 'Exact solver')
plt.plot(vqe_energies, label = 'VQE')
plt.title('Dissociation profile')
plt.xlabel('Interatomic distance')
plt.legend()
plt.ylabel('Energy');

