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. 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 (see Running FAST-VQE on Quantum Computers for details on how to perform a cost analysis before running on 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 of an existing ground_state_problem:

        result = fast_vqe_calculator.calculate(ground_state_problem)
    

    The result is an GroundStateProblemCalculatorResult object that 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 5 iterations, which is is often insufficient for convergence but it is intentionally low to avoid long, costly runs on quantum hardware. 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. See Create an Estimator for more details.

    • 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 an 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