Energy estimation
The EnergyEstimator algorithm in QDK/Chemistry estimates the energy of a quantum state by measuring expectation values of Pauli operators.
Following QDK/Chemistry’s algorithm design principles, it takes an OpenQASM circuit (from StatePreparation) and a QubitHamiltonian (from QubitMapper) as input and returns energy expectation values with statistical uncertainty.
Overview
The EnergyEstimator evaluates the expectation value of a QubitHamiltonian with respect to a given quantum circuit that loads a wavefunction onto qubits.
It takes a Circuit object and a target qubit Hamiltonian and automatically generates the corresponding measurement circuits.
These circuits are executed on a selected backend simulator with the user-specified number of shots, and the resulting bitstring statistics are used to calculate per-term expectation values and the total energy.
The algorithm supports:
- Multiple simulator backends
QDK’s native Q# simulator or Qiskit’s Aer simulator
- Noise modeling
Depolarizing noise, bit flip noise, Pauli noise, phase flip noise, and qubit loss simulation
- Grouped measurements
Efficient measurement of commuting Pauli terms in a single circuit execution
A typical workflow connects StatePreparation (which loads the wavefunction onto qubits) with EnergyEstimator (which measures the energy):
Prepare a
Wavefunctionfrom a multi-configuration calculationGenerate an OpenQASM circuit using StatePreparation
Map the Hamiltonian to qubit operators using QubitMapper
Estimate the energy using EnergyEstimator
Using the EnergyEstimator
Note
This algorithm is currently available only in the Python API.
This section demonstrates how to create, configure, and run an energy estimation.
The run method returns an energy expectation value with variance and the raw measurement data.
Input requirements
The EnergyEstimator requires the following inputs:
- Circuit
A quantum circuit that prepares the target quantum state. This is typically generated by the StatePreparation algorithm from a
Wavefunction.- QubitHamiltonian
A
QubitHamiltonianinstance containing the Pauli-string representation of the electronic Hamiltonian. This is obtained from the QubitMapper algorithm.- Circuit execution
A backend to execute the measurement circuits. Supported backends include QDK’s native Q# simulator and Qiskit’s Aer simulator.
- Number of shots
The number of measurement repetitions to perform for statistical sampling. More shots reduce statistical uncertainty but increase computational cost.
Note
The circuit and Hamiltonian must be compatible—they should use the same qubit encoding and be derived from the same underlying molecular system. The estimator automatically generates measurement circuits for each Pauli term in the Hamiltonian and performs the circuit sampling internally.
Creating an estimator
import numpy as np
from qdk_chemistry.algorithms import create
from qdk_chemistry.data import Circuit, QuantumErrorProfile, QubitHamiltonian
# Create energy estimator using Qsharp simulator as backend
qdk_estimator = create("energy_estimator", "qdk")
Configuring settings and running
Settings vary by implementation. The QDK backend supports noise models and qubit loss, while the Qiskit backend supports custom Aer noise models.
# Define a simple quantum circuit in QASM and a qubit Hamiltonian
circuit = Circuit(
qasm="""
include "stdgates.inc";
qubit[2] q;
rz(pi) q[0];
x q[0];
cx q[0], q[1];
"""
)
qubit_hamiltonian = QubitHamiltonian(["ZZ"], np.array([1.0]))
# Run energy estimation using Qsharp simulator without noise
circuit_executor = create("circuit_executor", "qdk_sparse_state_simulator")
energy_expectation_results, measurement_data = qdk_estimator.run(
circuit, qubit_hamiltonian, circuit_executor, total_shots=1000
)
print(
"Energy expectation value from noiseless QDK Simulator: "
f"{energy_expectation_results.energy_expectation_value}"
)
# Create energy estimator using Qsharp simulator with depolarizing noise
noise_model = QuantumErrorProfile(
name="noise model",
description="Noise model for QDK full state simulator",
errors={
"rz": {
"type": "depolarizing_error",
"rate": 0.005,
"num_qubits": 1,
},
"h": {
"type": "depolarizing_error",
"rate": 0.005,
"num_qubits": 1,
},
"s": {
"type": "depolarizing_error",
"rate": 0.005,
"num_qubits": 1,
},
"cx": {
"type": "depolarizing_error",
"rate": 0.007,
"num_qubits": 2,
},
},
)
circuit_executor = create("circuit_executor", "qdk_full_state_simulator", type="cpu")
qdk_estimator = create("energy_estimator", "qdk")
energy_expectation_results, measurement_data = qdk_estimator.run(
circuit,
qubit_hamiltonian,
circuit_executor,
total_shots=1000,
noise_model=noise_model,
)
print(
"Energy expectation value from QDK Simulator with depolarizing noise: "
f"{energy_expectation_results.energy_expectation_value}"
)
# Run energy estimation using Qiskit Aer simulator without noise
qiskit_aer_simulator = create("circuit_executor", "qiskit_aer_simulator")
energy_expectation_results, measurement_data = qdk_estimator.run(
circuit, qubit_hamiltonian, qiskit_aer_simulator, total_shots=1000
)
print(
f"Energy expectation value from Qiskit Aer Simulator: {energy_expectation_results.energy_expectation_value}"
)
# Create energy estimator using Qiskit Aer simulator with noise model
noise_model = QuantumErrorProfile(
name="noise model",
description="Noise model for Qiskit Aer simulator",
errors={
"rz": {
"type": "depolarizing_error",
"rate": 0.005,
"num_qubits": 1,
},
"sx": {
"type": "depolarizing_error",
"rate": 0.005,
"num_qubits": 1,
},
"cx": {
"type": "depolarizing_error",
"rate": 0.007,
"num_qubits": 2,
},
},
)
energy_expectation_results, measurement_data = qdk_estimator.run(
circuit,
qubit_hamiltonian,
qiskit_aer_simulator,
total_shots=1000,
noise_model=noise_model,
)
print(
"Energy expectation value from Qiskit Aer Simulator with noise: "
f"{energy_expectation_results.energy_expectation_value}"
)
Available implementations
QDK/Chemistry’s EnergyEstimator provides a unified interface for quantum circuit simulation and energy measurement.
You can discover available implementations programmatically:
from qdk_chemistry.algorithms import registry
print(registry.available("energy_estimator"))
# ['qdk']
print(registry.available("circuit_executor"))
# ['qdk_full_state_simulator', 'qdk_sparse_state_simulator', 'qiskit_aer_simulator']
QDK energy estimator
Factory name: "qdk"
Native QDK/Chemistry implementation of energy estimator. Supports various simulator backends and noise models for realistic quantum hardware simulation.
Run parameters
Parameter |
Type |
Description |
|---|---|---|
|
Circuit |
Quantum circuit that prepares the target quantum state |
|
QubitHamiltonian |
Qubit Hamiltonian to measure |
|
CircuitExecutor |
Backend to execute the measurement circuits |
|
int |
Total number of measurement shots |
|
QuantumErrorProfile | None |
Noise model to apply during circuit execution |
Further reading
The above examples can be downloaded as a complete Python script.
StatePreparation: Load wavefunctions onto qubits as quantum circuits
QubitMapper: Map fermionic Hamiltonians to qubit operators
See the
examples/state_prep_energy.ipynbnotebook for an end-to-end workflow demonstrationSettings: Configuration settings for algorithms
Factory Pattern: Understanding algorithm creation