Skip to main contentIBM Quantum Documentation Preview
This is a preview build of IBM Quantum® documentation. Refer to quantum.cloud.ibm.com/docs for the official documentation.

Get started with HI-VQE Chemistry

See the API reference

Note

Qiskit Functions are an experimental feature available only to IBM Quantum® Premium Plan, Flex Plan, and On-Prem (via IBM Quantum Platform API) Plan users. They are in preview release status and subject to change.

For an overview of this function, see the HI-VQE Chemistry documentation home.

  • The code on this page was developed using the following requirements. We recommend using these versions or newer.

    qiskit-ibm-runtime~=0.45.0
    

Set up

First, request access to the function. Then, authenticate using your IBM Quantum® API key and, assuming you've already saved your account to your local environment, select the Qiskit Function as follows:

import reprlib
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# Verify that you have access to the function
catalog.list()

Output:

[QiskitFunction(qunova/hivqe-chemistry),
 QiskitFunction(global-data-quantum/quantum-portfolio-optimizer),
 QiskitFunction(algorithmiq/tem),
 QiskitFunction(qedma/qesem),
 QiskitFunction(multiverse/singularity),
 QiskitFunction(ibm/circuit-function),
 QiskitFunction(q-ctrl/optimization-solver),
 QiskitFunction(colibritd/quick-pde),
 QiskitFunction(q-ctrl/performance-management),
 QiskitFunction(kipu-quantum/iskay-quantum-optimizer)]
# Load the function
function = catalog.load("qunova/hivqe-chemistry")

Example

The first example shows how to compute the ground state energy for an NH3 molecule using the HI-VQE algorithm.

Define the molecular geometry and options

The molecular geometry of NH3 is provided with Cartesian coordinates separated with ";" for each atom.

# Define the molecule geometry
geometry = """
N         -0.85188       -0.02741        0.03141;
H          0.16545        0.00593       -0.01648;
H         -1.16348       -0.39357       -0.86702;
H         -1.16348        0.94228        0.06281;
"""

Additional options can be defined and provided for molecular system in the following dictionary format.

# Configure some options for the job.
molecule_options = {"basis": "sto3g"}
hivqe_options = {"shots": 100, "max_iter": 20}

Execute the function with geometry and option inputs.

# Run HI-VQE
job = function.run(
    geometry=geometry,
    # `backend_name` is the name of a backend with at least 16 qubits,
    # for example, "ibm_marrakesh".
    backend_name=backend_name,
    max_states=2000,
    max_expansion_states=10,
    molecule_options=molecule_options,
    hivqe_options=hivqe_options,
)

It is a good idea to print the Function job ID so that it can be provided in support requests if something goes wrong.

print("Job ID:", job.job_id)

Output:

Job ID: e5ced6f2-fd1d-4244-a6aa-bd27cfb0cdee

This example then utilizes 16 qubits with 8 orbitals of sto3g basis for an NH3 molecule.

Check your Qiskit Function workload's status or return results as follows:

print(job.status())

Output:

QUEUED

After the job is completed, the results can be obtained with result() instance.

result = job.result()

# Output can be long, so we display a shortened representation
shortened_result = reprlib.repr(result)
print(shortened_result)

Output:

{'eigenvector': [0.9824448589364075, 0.009527106392132133, 6.854074372058527e-08, 3.591500190038039e-07, 0.0012975231577544268, 2.310159709002111e-05, ...], 'energy': -55.52108557170985, 'energy_history': [-55.51901898989887, -55.52056881448526, -55.52065046778772, -55.520690696813716, -55.520691108428, -55.520708448092634, ...], 'energy_variance': 3.066239097617371e-10, ...}

To access the ground state energy, use the "energy" key. The "eigenvector" key provides the CI coefficients with corresponding bitstring notation of electron configuration stored with "states" of the results.

fci_energy = -55.521148034704126  # the exact energy using FCI method
hivqe_energy = result["energy"]
print(
    f"|Exact Energy - HI-VQE Energy|: "
    f"{abs(fci_energy - hivqe_energy) * 1000} mHa"
)
print(f"Sampled Number of States: {len(result['states'])}")

Output:

|Exact Energy - HI-VQE Energy|: 0.06246299427914437 mHa
Sampled Number of States: 1936

Licensing

Note that use of this Qiskit Function is limited to problems requiring at most 20 qubits, unless a license is obtained granting a higher limit.

Email qiskit.support@qunovacomputing.com with license inquiries.

Example of licensed function use

Licensed users are issued a license token, and then must use a wrapper library to submit their license token to the function. The wrapper library can be installed from PyPI with pip install hivqe-qiskit-function-utils. The below example shows how this library should be used to submit your license token when calling the function.

import math
from qiskit_ibm_catalog import QiskitFunctionsCatalog
from hivqe_qiskit_function_utils import FunctionWrapper

catalog = QiskitFunctionsCatalog(
    token="your_qiskit_functions_catalog_token",
    channel="ibm_quantum_platform",
    instance="your_ibm_instance",
)

molecule_geometry = f"""
O 0 0 0;
H {-0.957*math.sin(math.radians(104.5)/2.0)} {0.957*math.cos(math.radians(104.5)/2.0)} 0;
H {0.957*math.sin(math.radians(104.5)/2.0)} {0.957*math.cos(math.radians(104.5)/2.0)} 0
"""

hivqe = FunctionWrapper(
    token="your_hivqe_license_token",
    function=catalog.load("qunova/hivqe-chemistry"),
)
job = hivqe.run(
    geometry=molecule_geometry,
    backend_name="ibm_torino",
    max_states=10000,
    max_expansion_states=1000,
    hivqe_options={"ansatz": "epa", "max_iter": 10},
)
result = job.result()

Performance

This section shows the demonstrated benchmark calculations of HI-VQE with a 24-qubit case for Li2S, a 40-qubit case for an N2 molecule, and a 44-qubit case for an FeP-NO system.

Dissociation potential energy surface curve for an Li2S molecule with 24 qubits

The PES curve is shown with the FCI reference and initial guess from RHF, together with the energy error from the FCI reference.

Image showing that HI-VQE produces solutions within chemical accuracy of a classical reference PES curve for the Li2S system.

The calculations have been conducted with the following geometries and options.

# Define Li2S geometries
Li2S_geoms = {
    "Li2S_1.51": "S        -1.239044    0.671232   -0.030374;Li       -1.506327    0.432403   -1.498949;Li       -0.899996    0.973348    1.826768;",
    "Li2S_2.40": "S        -1.741432    0.680397    0.346702;Li       -0.529307    0.488006   -1.729343;Li       -1.284307    0.989409    2.177209;",
    "Li2S_3.80": "S        -2.707255    0.674298    0.909161;Li        0.079218    0.552012   -1.671656;Li       -0.927010    0.931502    1.557063;",
}

# Configure some options for the job.
molecule_options = {
    "basis": "sto3g",
}
hivqe_options = {
    "shots": 100,
    "max_iter": 20,
}

results = []
for geom in ["Li2S_1.51", "Li2S_2.40", "Li2S_3.80"]:
    # Run HI-VQE
    job = function.run(
        geometry=Li2S_geoms[geom],
        backend_name=backend_name,  # can use any device with at least 38 qubits
        max_states=2000,
        max_expansion_states=10,
        molecule_options=molecule_options,
        hivqe_options=hivqe_options,
    )
    results.append(job.result())

The red dots represent the HI-VQE calculation results for six different geometries, and three geometries corresponding to 1.51, 2.40, and 3.80 Angstrom are provided as input in the above cell.

Dissociation PES curve for an N2 molecule with 40 qubits

The nitrogen molecule has been identified as a multireference system with large correlation energy contributions beyond the Hartree-Fock state. We conducted a benchmark calculation for the N2 molecule with cc-pvdz basis, (20o,14e) using the homo-lumo active orbital selection. The complete active space (CAS) number to represent this problem is 6,009,350,400. It is not possible to obtain the eigenvalue problem solution (for energy and electronic structure) with this number of states using a powerful desktop (16cpu/64GB). With HI-VQE, users can efficiently search the subspace of CAS states to find chemically accurate results while saving computation resources significantly. The following plots show the PES curve of 40 qubits HI-VQE calculation of the N2 molecule dissociation.

Image showing that HI-VQE produces solutions within chemical accuracy of a classical reference PES curve for the N2 system

Dissociation PES curve for five-coordinated iron(II)-porphyrin with an NO system with 44 qubits

Another interesting chemical system is an iron(II)-porphyrin (FeP) complex with a coordinated nitric oxide (NO) ligand, which represents a biologically relevant metalloporphyrin system that plays crucial roles in various physiological processes. In this example, HI-VQE has been utilized to estimate the accurate potential energy surface curve of the intermolecular interaction between FeP and NO (ground state energy for differently separated geometries). The combined system has 450 orbitals and 202 electrons (450o,202e) with 6-31g(d) basis in total. The homo-lumo active orbital selection was utilized to calculate the smaller case from the real case with (22o,22e). From the following benchmark results, we were able to achieve the chemical accuracy (> 1.6 mHa) with a state-of-the-art classical computer chemistry calculation of CASCI(DMRG) (22o,22e) reference.

Image showing that HI-VQE produces solutions within chemical accuracy of a classical reference PES curve for the FeP-NO system

Fetch error messages

If your workload fails, the status will be ERROR and calling job.result() will raise an exception:

job = function.run(
    geometry="invalid-geometry",  # This will cause an error
    backend_name=backend_name,
    max_states=2000,
    max_expansion_states=15,
    molecule_options=molecule_options,
    hivqe_options=hivqe_options,
)

job.result()

Output:

---------------------------------------------------------------------------
QiskitServerlessException                 Traceback (most recent call last)
Cell In[12], line 10
      1 job = function.run(
      2     geometry="invalid-geometry",  # This will cause an error
      3     backend_name=backend_name,
   (...)
      7     hivqe_options=hivqe_options,
      8 )
---> 10 job.result()

File ~/work/documentation/documentation/.tox/py311/lib/python3.11/site-packages/qiskit_serverless/core/job.py:253, in Job.result(self, wait, cadence, verbose, maxwait)
    251 if self.status() == "ERROR":
    252     if results:
--> 253         raise QiskitServerlessException(results)
    255     raise QiskitServerlessException(self.filtered_logs(include=r"(?i)error|exception"))
    257 if isinstance(results, str):

QiskitServerlessException: ["runner.UnknownRuntimeError: 'An unexpected error occurred during job execution. Please make sure that your inputs are valid. If you are still experiencing problems, you can contact the Qunova Computing support service at qiskit.support@qunovacomputing.com and provide the Function job ID of this job for more assistance. -- https://docs.quantum.ibm.com/errors#1500'\n"]
job.status()

Output:

'ERROR'