Calculate the Ground State Energy Using the FAST-VQE

Goal

Run a FAST-VQE calculation for a prepared ground-state problem and obtain the ground-state energy.

Prerequisites

Steps

  1. Quick start: Build the default FAST-VQE calculator

    The calculator_creator() is a fluent builder (see Understanding and Using Kvantify Qrunch’s Fluent Builder Pattern) that configures and returns a GroundStateProblemCalculator. By default, .vqe().iterative().standard() builds a FAST-VQE calculator with conservative defaults to avoid lengthy runs on real hardware.

        fast_vqe_calculator = qc.calculator_creator().vqe().iterative().standard().create()
    
  2. Use the default FAST-VQE calculator to calculate the ground state energy

    You can now calculate the result from an existing .ground_state_problem:

        result = fast_vqe_calculator.calculate(ground_state_problem)
    
    

    The result is an AdaptiveVqeGroundStateProblemCalculatorResult object, which contains:

    • Electronic energy of the active electrons

    • Electronic energy of all electrons

    • Total molecular energy

    • Total electronic energy per macro iteration (list of values for each VQE iteration)

    The total_energy field is an ExpectationValue:

    print(f"Total energy = {result.total_energy:.6f}")
    
  3. Customize the VQE settings

    The most common setting to adjust is max_iterations in IterativeVqeOptions. The default is intentionally low to avoid long, costly runs on hardware — but often insufficient for convergence. It is also often useful to require that the vqe runs all iterations up to the maximum specified value.

        adaptive_vqe_options = qc.options.IterativeVqeOptions(
            max_iterations=100,  # Increase the maximum number of iterations
            gates_per_iteration=1,  # Add one gate per iteration (Recommended)
            force_all_iterations=True,  # Force all iterations to run, independent of convergence.
        )
    
        # Build the user-configured VQE calculator instance
        fast_vqe_calculator = (
            qc.calculator_creator()  # Start creating a calculator
            .vqe()  # Narrow: pick Variational quantum eigensolver (VQE)
            .iterative()  # Narrow: pick the iterative VQE
            .standard()  # Narrow: pick the standard iterative VQE (FAST-VQE)
            .with_options(adaptive_vqe_options)  # Use the user-defined iterative VQE options
            .choose_minimizer()  # Start sub-choice: Choose the gate parameter minimizer
            .quick_default()  # Perform the sub-choice selection - Here we pick the greedy and quick minimizer
            .create()  # Create the calculator instance
        )
    

    See the API reference for IterativeVqeOptions for the full list of options. You can configure additional options before calling .create():

  • Set the estimator:

    .with_estimator(my_estimator)
    

    Setting an estimator to be used for energy estimation and parameter optimization.

  • Set number of measurement shots:

    .with_estimator_shots(1000)
    

    Setting the number of shots to use in the estimator when doing parameter optimization. Setting to None uses an exact simulator evaluation.

  • Choose classical minimizer:

    .choose_minimizer()
    # .<pick-a-minimizer>(...)
    

    You can choose which classical minimizer you want to use to optimize the parameters. See Choose a Minimizer for available options.

  • Choose reminimizer:

    .choose_reminimizer()
    # .<pick-a-minimizer>(...)
    

    You can choose a classical minimizer if you want to re-optimize the parameters at the end of a VQE run. See Choose a Minimizer for available options.

  • Set stopping criteria:

    .choose_stopping_criterion()
    # .<pick-a-stopping-criterion>(...)
    

    You can choose the stopping criterion for the iterative VQE. See Choose a Stopping Criterion for available options.

  • Select a custom gate selector:

    .with_gate_selector(my_gate_selector)
    

    You can provide a custom gate selector to control which excitation gate is added at each iteration. See Create a FAST Gate Selector for how to build a gate_selector.

  • Configure data persistence:

    .choose_data_persister_manager()
    # .<pick-a-persister>(...)
    

    You can choose how and where to save/load intermediate data during the VQE run. See Choose a Data Persister Manager for available options.

  • Control inclusion of single excitations:

    .with_single_excitations(include=False)
    

    You can exclude the use of single excitation gates in the FAST-VQE ansatz.

  • Control inclusion of double excitations:

    .with_double_excitations(include=False)
    

    You can exclude the use of double excitation gates in the FAST-VQE ansatz.

OO-FAST-VQE (Orbital-Optimized FAST-VQE)

OO-FAST-VQE augments FAST-VQE with orbital optimization at each iteration. This may reduce the number of iterations needed for convergence, but at a significant increase in computational cost per iteration.

import qrunch as qc

adaptive_vqe_options = qc.options.IterativeVqeOptions(
    max_iterations=100,
)

fast_vqe_calculator = (
    qc.calculator_creator()
    .vqe()
    .iterative_with_orbital_optimization()
    .standard()
    .with_options(adaptive_vqe_options)
    .create()
)

The OO-FAST-VQE has all the same configuration options as FAST-VQE, and in addition you can also:

  • Define an orbital optimizer:

.with_orbital_optimizer(orbital_optimizer)

See Create an Orbital Optimizer for how to construct the orbital_optimizer.

  • Set stopping criterion for the orbital optimizer:

.choose_orbital_optimizer_stopping_criterion()
# .<pick-a-stopping-criterion>(...)

See Choose a Stopping Criterion for available options.

ADAPT-VQE

To use ADAPT-VQE instead of FAST-VQE, replace the gate_selector with an ADAPT gate selector. See Create a ADAPT Gate Selector for how to build an ADAPT gate_selector.

Verify the Result

  • Check that the result.total_energy is correct.

  • For simulator runs, repeated calculations should produce the same .value with .error close to zero, unless the simulator uses a finite number of shots.

  • On hardware, .error will reflect shot noise from a finite number of measurements.

See Also