Use a UCC-like ansatz with a VQE#
When using a UCC
-style ansatz with a
VQE
one needs to pay particular attention to the
initial_point
attribute which indicates from
which set of initial parameters the optimization routine should start.
By default, VQE will start from a random initial point. In this how to we show how one
can set a custom initial point instead (for example to guarantee that one starts from the
Hartree-Fock state).
We obtain an
ElectronicStructureProblem
which we want to solve:
from qiskit_nature.second_q.drivers import PySCFDriver
driver = PySCFDriver(atom="H 0 0 0; H 0 0 0.735", basis="sto-3g")
problem = driver.run()
We setup our
QubitMapper
:
from qiskit_nature.second_q.mappers import JordanWignerMapper
mapper = JordanWignerMapper()
We setup our ansatz:
from qiskit_nature.second_q.circuit.library import UCCSD, HartreeFock
ansatz = UCCSD(
problem.num_spatial_orbitals,
problem.num_particles,
mapper,
initial_state=HartreeFock(
problem.num_spatial_orbitals,
problem.num_particles,
mapper,
),
)
We setup a
VQE
:
import numpy as np
from qiskit_algorithms import VQE
from qiskit_algorithms.optimizers import SLSQP
from qiskit.primitives import Estimator
vqe = VQE(Estimator(), ansatz, SLSQP())
Now comes the key step: choosing the initial point. Since we picked the
HartreeFock
initial state before, in order to ensure we start from that, we need to initialize ourinitial_point
with all-zero parameters. One way to do that is like so:
vqe.initial_point = np.zeros(ansatz.num_parameters)
Alternatively, one can also use
HFInitialPoint
like so:
from qiskit_nature.second_q.algorithms.initial_points import HFInitialPoint
initial_point = HFInitialPoint()
initial_point.ansatz = ansatz
initial_point.problem = problem
vqe.initial_point = initial_point.to_numpy_array()
This may seem like it is not adding a lot of benefit, but the key aspect here is that you can build
your code on top of the InitialPoint
interface based on which we also have the
MP2InitialPoint
which allows you to start
from an MP2 starting point like so:
from qiskit_nature.second_q.algorithms.initial_points import MP2InitialPoint
initial_point = MP2InitialPoint()
initial_point.ansatz = ansatz
initial_point.problem = problem
vqe.initial_point = initial_point.to_numpy_array()
Finally, we can now actually solve our problem:
from qiskit_nature.second_q.algorithms import GroundStateEigensolver
solver = GroundStateEigensolver(mapper, vqe)
result = solver.solve(problem)
print(f"Total ground state energy = {result.total_energies[0]:.4f}")
Total ground state energy = -1.1373