Skip to content

VQE Method for Molecule Energy Solver

This notebook demonstrates how to use the construct_chemistry_model function, which constructs a VQE model for Molecule eigensolver. For more comprehensive explanation on the algorithm see Molecule Eigensolver notebook.

import numpy as np

from classiq import QuantumProgram, construct_chemistry_model, execute, show, synthesize
from classiq.applications.chemistry import (
    ChemistryExecutionParameters,
    Molecule,
    MoleculeProblem,
    UCCParameters,
)
from classiq.execution import (
    ClassiqBackendPreferences,
    ClassiqSimulatorBackendNames,
    ExecutionPreferences,
    OptimizerType,
)
from classiq.synthesis import set_execution_preferences

1. Defining a Molecule and a Molecule Problem

First, declare the class Molecule and insert a list of atoms and their spacial positions (distances are in Å (\(10^{-10} m\))). Below we treat the \(H_2\) example.

molecule_H2 = Molecule(atoms=[("H", (0.0, 0.0, 0)), ("H", (0.0, 0.0, 0.735))])

Next, we define the parameters of the Hamiltonian generation program. The user has a choice over the following options: - mapping (str): the mapping between the fermionic Hamiltonian and the qubits Hamiltonian. Supported types: - "jordan_wigner" - "parity" - "bravyi_kitaev" - "fast_bravyi_kitaev" - freeze_core (bool): remove the "core" orbitals of the atoms defining the molecule. - z2_symmetries (bool): whether to perform z2 symmetries reduction. If symmetries in the molecules exist, this option will decrease the number of qubits defining the Hamiltonian and thus make the calculations more efficient.

chemistry_problem = MoleculeProblem(
    molecule=molecule_H2,
    mapping="jordan_wigner",
    z2_symmetries=False,
    freeze_core=True,
)

2. Constructing and Synthesizing a Ground State Solver

The quantum part of the model consists of a parameterized quantum function ("the ansatz"). The constructor function allows to choose whether to start with an initial Hartree Fock function, and the choice of three built-in variational functions: Hardware Efficient Ansatz (HEA), Unitary Coupled Cluster ansatz (UCC), and Hamiltonian Variational ansatz (HVA).

The classical part of the algorithm runs a classical optimizer for finding the optimal parameters, as well as post-processes the result and returns the total energy (combining the ground state energy of the Hamiltonian, the nuclear repulsion and the static nuclear energy).

In the example below we use Hartree Fock initial condition and a UCC ansatz with single and double excitations. For the classical solver we take the COBYLA optimizer with up to 30 iterations.

chemistry_model = construct_chemistry_model(
    chemistry_problem=chemistry_problem,
    use_hartree_fock=True,
    ansatz_parameters=UCCParameters(excitations=[1, 2]),
    execution_parameters=ChemistryExecutionParameters(
        optimizer=OptimizerType.COBYLA,
        max_iteration=30,
        initial_point=None,
    ),
)

backend_preferences = ClassiqBackendPreferences(
    backend_name=ClassiqSimulatorBackendNames.SIMULATOR
)

chemistry_model = set_execution_preferences(
    chemistry_model,
    execution_preferences=ExecutionPreferences(
        num_shots=1000, backend_preferences=backend_preferences
    ),
)

qprog = synthesize(chemistry_model)
show(qprog)
Opening: https://platform.classiq.io/circuit/fcd44b9e-35b2-4ee9-97e5-c91f32589d1a?version=0.41.0.dev39%2B79c8fd0855
from classiq import write_qmod

write_qmod(chemistry_model, "chemistry")

Classiq's UCC function provides a highly efficient solution in aspects of circuit depth and number of CX gates. Those ultimately reduce the gate's time and amount of resources needed for its operation.

3. Executing to Find the Ground State

Once we've synthesized the model we can execute it.

result = execute(qprog).result()
chemistry_result_dict = result[1].value

Execution of the quantum program returns the full VQE solution (e.g., the values of the optimal_parameters), as well as the post-processed results (e.g., the value of the total_energy, which is the ground state energy of the Hamiltonian).

chemistry_result_dict["total_energy"]  # energy is returned in units of Hartree
-1.1367743111939652
chemistry_result_dict["vqe_result"]["optimal_parameters"]
{'param_0': -4.6539276399379945,
 'param_1': -1.5597296169566757,
 'param_2': -4.819846630440713}