Create an Estimator

Goal

Construct an estimator for use in Adaptive/Iterative VQE (e.g., FAST-VQE), choosing between a high-performance excitation-gate estimator or a backend-powered estimator, and optionally enabling estimator-level error mitigation.

Quick Start (default estimator)

For a simple working estimator, stick with the defaults:

import qrunch as qc

estimator = (
      qc.estimator_creator()
      .create()
)

The estimator builder follows the pattern explained in Understanding and Using Kvantify Qrunch’s Fluent Builder Pattern. In practice, one usually narrows down to a specific estimator type. The options are:

  • .backend(): third-party simulators, noisy simulators, and real hardware (see Choose a Backend)

  • .excitation_gate(): Kvantify’s proprietary chemistry tailored excitation-gate simulator

  • .memory_restricted(): Kvantify’s proprietary chemistry tailored memory-restricted simulator

  • .qiskit_statevector(): Qiskit state-vector simulator

Excitation Gate Estimator

The excitation gate estimator is a fast, chemistry-tailored simulator and a great default for running VQEs for molecular systems.

import qrunch as qc

estimator = (
      qc.estimator_creator()
      .excitation_gate()
      .create()
)

The excitation gate estimator can be configured with the following options:

import qrunch as qc

estimator = (
      qc.estimator_creator()
      .excitation_gate()
      .with_float_type("f64")             # Precision of internal floats: "f64" (default) or "f32"
      .with_parallel_setting("parallel")  # Parallelization behavior: "serial" or "parallel"
      .with_spin_particle_conservation()  # Use spin particle conservation policy (see note below):
      .with_seed(1234)                    # Reproducibility: set a seed (or None to disable)
      .with_eps(1e-12)                    # Sampling epsilon lower bound (absolute amplitude threshold), or None
      .create()
)

Note on particle conservation policies

  • with_spin_particle_conservation() specifies that the number of spin up and spin down particles are conserved separately (fermionic encoding). Excitation gates are expected to conserve the number of particles in the two parts of the circuits corresponding to the spin up and spin down orbitals. This is the situation with the fermionic encoding in FAST-VQE.

  • with_total_particle_conservation() Specify that the total number of particles are conserved (bosonic encoding). Excitation gates are expected to conserve the total number of particles. This is the case of the hard-core bosonic encoding (BEAST-VQE) where the qubits represent spatial orbitals occupied by electron pairs. Thus, the total number of (electron-pair) particles is conserved.

Note that the particle conservation policy is only relevant when using the excitation gate simulator and the reason for this is related to memory usage.

Choose Grouper

It is possible to choose different groupers for grouping Pauli strings.

import qrunch as qc

estimator = (
      qc.estimator_creator()
      .excitation_gate()
      .choose_grouper()
      # .<pick-one-grouper>(...)
      .create()
)

The options are:

  • identity() creates an identity (trivial) measurement grouper

  • qubit_wise() creates a qubit-wise commuting measurement grouper

  • beast() creates a BEAST measurement grouper

Memory Restricted Estimator

The memory restricted estimator is the recommended simulator for large scale calculations. It is designed to handle large Hilbert spaces by capping memory usage. Thus it is not an exact simulator, but rather a high-performance approximate simulator.

import qrunch as qc

estimator = (
      qc.estimator_creator()
      .memory_restricted()
      .create()
)

Note that the memory restricted estimator only resorts to approximating the state when certain criteria are met, when enough gates have been added to the circuit. A warning will be issued when the simulator starts truncating the number of amplitudes of the state vector.

It has an easy way to define precise (but still approximate) defaults:

import qrunch as qc

estimator_precise = (
      qc.estimator_creator()
      .memory_restricted()
      .with_precise_defaults()
      .create()
)

Or fast (and less precise) defaults:

import qrunch as qc

estimator_fast = (
      qc.estimator_creator()
      .memory_restricted()
      .with_quick_defaults()
      .create()
)

The memory restricted estimator can also be manually configured with the options shown in the following example:

import qrunch as qc

options = qc.options.MemoryRestrictedSimulatorOptions(
      suppress_warnings=False,
      max_number_of_amplitudes=1_000_000,
      max_memory_usage_in_kb=None,
)

estimator_custom = (
      qc.estimator_creator()
      .memory_restricted()
      .with_options(options)
      .create()
)

Alternatively, one can set the maximum memory usage instead of the maximum number of amplitudes:

import qrunch as qc

estimator_custom = (
      qc.estimator_creator()
      .memory_restricted()
      .with_max_memory(max_memory_usage_in_kb=512_000)
      .create()
)

In this example, the estimator will use at most 512 MB of RAM (512.000 kilobytes).

Backend Estimator

This estimator is designed for use with third-party simulators, noisy simulators, or real quantum computers.

import qrunch as qc

estimator = (
      qc.estimator_creator()
      .backend()
      .create()
)

See Choose a Backend for how to choose and configure a non-default backend.

Qiskit State Vector

The Qiskit State Vector estimator.

import qrunch as qc

estimator = (
      qc.estimator_creator()
      .qiskit_statevector()
      .create()
)

CuQuantum State Vector Estimator

The CuQuantum state vector estimator is a GPU-accelerated exact simulator powered by NVIDIA cuQuantum’s cuStateVec library.

Prerequisites

This estimator requires an NVIDIA GPU with CUDA support. If CUDA is not available on your system, attempting to create the estimator will raise a RuntimeError.

Basic Usage

import qrunch as qc

estimator = (
      qc.estimator_creator()
      .cuquantum_statevector()
      .create()
)

Shots

Like all state vector estimators, this estimator computes exact expectation values and does not support shot-based sampling. The shots argument must always be None; any other value will raise an EstimatorError.

Cleanup

The estimator holds a cuStateVec library handle and associated GPU memory. Once you are done with it, call cleanup() to release GPU resources explicitly:

estimator = (
      qc.estimator_creator()
      .cuquantum_statevector()
      .create()
)

# ... use the estimator ...

estimator.cleanup()

Failing to call cleanup() after use may result in GPU memory not being freed until the Python process exits.

Verify the Result

  • You now have a configured estimator instance ready to be plugged into a VQE

Next Step

See Also