.. _vqe_class: VQE === .. _vqe_workflow: .. figure:: ../figures/vqe_workflow.png :align: center :alt: VQE workflow diagram Schematic representation of a VQE workflow. :math:`\boldsymbol \theta` represents the set of circuit parameters which are variationally optimized via an external classical routine. Expectation values of the molecular Hamiltonian :math:`H` (cost function) are evaluated at circuit level. The VQE algorithm can be invoked through the :class:`qc2.algorithms.qiskit.vqe.VQE` and :class:`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 :class:`~qc2.algorithms.utils.active_space.ActiveSpace`. * **Ansatz**: type of variational form used; by default, this is set to ``UCCSD``. * **Initial circuit parameters**: Initial guesses for the ansatz variational parameters :math:`\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 :class:`~qc2.data.data.qc2Data`. So, in actual runs, users only need to instantiate it as part of its :attr:`~qc2.data.data.qc2Data.algorithm` method (to be discussed in :ref:`run_algorithms_with_qc2Data` section). For illustrative purposes only, the following is a pseudo-code example demonstrating how ``VQE`` can be instantiated independently: .. code-block:: python :linenos: :emphasize-lines: 21-28 from ase.build import molecule from qiskit_algorithms.optimizers import COBYLA from qiskit.primitives import Estimator from qc2.data import qc2Data from qc2.algorithms.qiskit import VQE from qc2.algorithms.utils import ActiveSpace # set ASE Atoms object mol = molecule('H2') # instantiate qc2Data class qc2data = qc2Data( molecule=mol, ... ) # set up VQE class vqe = VQE( qc2data=qc2data, active_space=ActiveSpace( num_active_electrons=(1, 1), num_active_spatial_orbitals=2 ), mapper='bk', optimizer=COBYLA(), estimator=Estimator(), ) where the ``active_space`` argument is set to an instance of the :class:`~qc2.algorithms.utils.active_space.ActiveSpace` class. The ``'bk'`` string in ``mapper`` invokes the Bravyi-Kitaev fermionic-to-qubit transformation (qiskit_nature.BravyiKitaevMapper) as implemented in :class:`~qc2.algorithms.utils.mappers.FermionicToQubitMapper` A corresponding example using :class:`qc2.algorithms.pennylane.vqe.VQE` is: .. code-block:: python :linenos: :emphasize-lines: 20-27 from ase.build import molecule import pennylane as qml from qc2.data import qc2Data from qc2.algorithms.pennylane import VQE from qc2.algorithms.utils import ActiveSpace # set ASE Atoms object mol = molecule('H2') # instantiate qc2Data class qc2data = qc2Data( molecule=mol, ... ) # set up VQE class vqe = VQE( qc2data=qc2data, active_space=ActiveSpace( num_active_electrons=(1, 1), num_active_spatial_orbitals=2 ), mapper='jw', optimizer=qml.GradientDescentOptimizer(stepsize=0.5), device='default.qubit' )