VQE

VQE workflow diagram

Schematic representation of a VQE workflow. \(\boldsymbol \theta\) represents the set of circuit parameters which are variationally optimized via an external classical routine. Expectation values of the molecular Hamiltonian \(H\) (cost function) are evaluated at circuit level.

The VQE algorithm can be invoked through the qc2.algorithms.qiskit.vqe.VQE and qc2.algorithms.pennylane.vqe.VQE classes. Despite requiring a few SDK-specific details, in general the algorithm and its instantiation entails the following input information:

  • Reference state & occupation numbers: a reference quantum circuit and initial qubit states; this is by default Hartree-Fock.

  • Molecule active space: this determines the total number of qubits and is input as an instance of ActiveSpace.

  • Ansatz: type of variational form used; by default, this is set to UCCSD.

  • Initial circuit parameters: Initial guesses for the ansatz variational parameters \(\theta_{i}\).

  • Fermionic-to-qubit mapper & qubit Hamiltonian: Strategy to transform the initial fermionic Hamiltonian (constructed from classical qchem data) to qubit space; by default, this set to Jordan-Wigner.

  • Classical optimizer: the optimization routine for the circuit variational parameters. Default routines are: SLSQP for Qiskit Nature and GradientDescentOptimizer for PennyLane .

Like in the case of qc2-ASE calculators, the algorithm VQE class is naturally abstracted within qc2Data. So, in actual runs, users only need to instantiate it as part of its algorithm method (to be discussed in Running quantum-classical algorithms via qc2Data class section). For illustrative purposes only, the following is a pseudo-code example demonstrating how VQE can be instantiated independently:

 1from ase.build import molecule
 2
 3from qiskit_algorithms.optimizers import COBYLA
 4from qiskit.primitives import Estimator
 5
 6from qc2.data import qc2Data
 7from qc2.algorithms.qiskit import VQE
 8from qc2.algorithms.utils import ActiveSpace
 9
10# set ASE Atoms object
11mol = molecule('H2')
12
13# instantiate qc2Data class
14qc2data = qc2Data(
15    molecule=mol,
16    ...
17)
18
19# set up VQE class
20vqe = VQE(
21    qc2data=qc2data,
22    active_space=ActiveSpace(
23        num_active_electrons=(1, 1),
24        num_active_spatial_orbitals=2
25    ),
26    mapper='bk',
27    optimizer=COBYLA(),
28    estimator=Estimator(),
29)

where the active_space argument is set to an instance of the ActiveSpace class. The 'bk' string in mapper invokes the Bravyi-Kitaev fermionic-to-qubit transformation (qiskit_nature.BravyiKitaevMapper) as implemented in FermionicToQubitMapper

A corresponding example using qc2.algorithms.pennylane.vqe.VQE is:

 1from ase.build import molecule
 2
 3import pennylane as qml
 4
 5from qc2.data import qc2Data
 6from qc2.algorithms.pennylane import VQE
 7from qc2.algorithms.utils import ActiveSpace
 8
 9# set ASE Atoms object
10mol = molecule('H2')
11
12# instantiate qc2Data class
13qc2data = qc2Data(
14    molecule=mol,
15    ...
16)
17
18# set up VQE class
19vqe = VQE(
20    qc2data=qc2data,
21    active_space=ActiveSpace(
22        num_active_electrons=(1, 1),
23        num_active_spatial_orbitals=2
24    ),
25    mapper='jw',
26    optimizer=qml.GradientDescentOptimizer(stepsize=0.5),
27    device='default.qubit'
28)