QpeResult
The QpeResult class in QDK/Chemistry represents the outcome of a quantum phase estimation calculation.
It encapsulates the measured phase, reconstructed energy, alias candidates, and measurement metadata, providing a complete record of a QPE experiment.
Overview
Quantum phase estimation measures a phase fraction \(\phi \in [0, 1)\) that encodes an eigenvalue \(E\) of the target Hamiltonian. The relationship between phase and energy depends on the evolution time \(t\):
However, because the phase is periodic, the measured \(\phi\) is only unique modulo \(2\pi / t\).
This means multiple energy values — called aliases — can produce the same measured phase.
The QpeResult class handles this ambiguity automatically by computing all alias candidates and optionally resolving to the physically correct energy using a reference value.
QpeResult is the output of the PhaseEstimation algorithm and supports full serialization to JSON and HDF5 formats.
For details on how different QPE implementations (IQPE, standard QFT-based) populate this result, see the PhaseEstimation algorithm documentation.
Properties
The QpeResult stores the following information:
Property |
Type |
Description |
|---|---|---|
|
str |
Algorithm identifier (e.g., |
|
float |
Time parameter \(t\) used in the evolution \(U = e^{-iHt}\). |
|
float |
Raw measured phase \(\phi \in [0, 1)\). |
|
float |
Raw phase angle in radians: \(2\pi\phi\). |
|
float |
Alias-resolved phase fraction. Equals |
|
float |
Alias-resolved phase angle in radians. |
|
float |
Energy computed directly from the raw phase: \(E = 2\pi\phi / t\). |
|
tuple[float, …] |
All alias energy candidates \(E + k \cdot 2\pi/t\) for a range of integer shifts \(k\). |
|
float | None |
The alias candidate closest to the reference energy, or |
|
tuple[int, …] | None |
Measured phase bits ordered from most significant to least significant. Available for IQPE; may be |
|
str | None |
Binary string representation of the measured phase (e.g., |
|
dict | None |
Caller-defined metadata for provenance tracking (e.g., molecule name, basis set, reference energy). |
Alias resolution
Phase estimation measures a phase \(\phi \in [0, 1)\), but the underlying energy eigenvalue can be negative, positive, or arbitrarily large. Different energy values that differ by integer multiples of \(2\pi / t\) all map to the same phase.
The alias resolution algorithm works as follows:
Compute the raw energy: \(E_{\text{raw}} = 2\pi\phi / t\) where the angle is mapped to \((-\pi, \pi]\)
Enumerate alias candidates: \(E_k = E_{\text{raw}} + k \cdot 2\pi/t\) for each \(k\) in the branch shift range (default: \(k \in \{-2, -1, 0, 1, 2\}\))
Include negative reflections: \(-E_k\) for symmetry
If a reference energy is provided, select the candidate closest to the reference as
resolved_energy
The branch shift range can be customized via the branch_shifts parameter in from_phase_fraction().
Tip
A good choice for reference_energy is the energy from a classical multi-configuration calculation (e.g., CASCI), which is typically close to the true eigenvalue.
Construction
QpeResult objects are typically created by the PhaseEstimation algorithm.
They can also be constructed manually from a measured phase fraction using the from_phase_fraction() class method:
from qdk_chemistry.data import QpeResult
# Construct a QpeResult from a measured phase fraction
result = QpeResult.from_phase_fraction(
method="iterative",
phase_fraction=0.423828125,
evolution_time=0.1,
bits_msb_first=(0, 1, 1, 0, 1, 1, 0, 0, 1, 0),
bitstring_msb_first="0110110010",
reference_energy=-1.137,
)
Inspecting results
# Inspect the result
print(f"Method: {result.method}")
print(f"Phase fraction: {result.phase_fraction:.6f}")
print(f"Phase angle: {result.phase_angle:.6f} rad")
print(f"Raw energy: {result.raw_energy:.8f} Ha")
print(f"Alias candidates: {result.branching}")
print(f"Resolved energy: {result.resolved_energy:.8f} Ha")
print(f"Measured bits: {result.bits_msb_first}")
# Full summary
print(result.get_summary())
Working with aliases
# Construct without a reference energy — no alias resolution
result_no_ref = QpeResult.from_phase_fraction(
method="iterative",
phase_fraction=0.423828125,
evolution_time=0.1,
)
# All alias candidates are available in the branching tuple
for i, energy in enumerate(result_no_ref.branching):
print(f" Candidate {i}: {energy:.6f} Ha")
# Resolve later using a reference energy
from qdk_chemistry.utils.phase import resolve_energy_aliases
resolved = resolve_energy_aliases(
result_no_ref.raw_energy,
evolution_time=0.1,
reference_energy=-1.137,
)
print(f"Resolved energy: {resolved:.8f} Ha")
Serialization
QpeResult supports the same serialization formats as other QDK/Chemistry data classes:
import os
import tempfile
tmpdir = tempfile.mkdtemp()
# Save to JSON
result.to_json_file(os.path.join(tmpdir, "result.qpe_result.json"))
# Load from JSON
loaded = QpeResult.from_json_file(os.path.join(tmpdir, "result.qpe_result.json"))
# Save to HDF5
result.to_hdf5_file(os.path.join(tmpdir, "result.qpe_result.h5"))
# Load from HDF5
loaded_h5 = QpeResult.from_hdf5_file(os.path.join(tmpdir, "result.qpe_result.h5"))
Further reading
The above examples can be downloaded as a complete Python script.
PhaseEstimation: Phase estimation algorithms
TimeEvolutionBuilder: Hamiltonian simulation methods
Serialization: Data persistence formats
See the
examples/qpe_stretched_n2.ipynbnotebook for an end-to-end QPE workflow