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 \(\varphi \in [0, 1)\) that encodes an eigenvalue \(E\) of the target Hamiltonian. The relationship between the measured phase and energy depends on the type of unitary being phase-estimated.
QDK/Chemistry uses a unified factory method from_phase_fraction() that accepts a callable eigenvalue_from_phase
mapping the measured phase to the Hamiltonian eigenvalue. Each unitary container provides this mapping as an instance method.
Time evolution
When QPE acts on \(U = e^{-iHt}\), the eigenvalues are \(e^{-iEt}\) and the energy is recovered via
eigenvalue_from_phase():
where \(\varphi' \in (-1/2, 1/2]\) is the measured phase fraction wrapped from \([0, 1)\) into \((-1/2, 1/2]\).
Qubitization
When QPE acts on the qubitization walk operator \(W\), the eigenvalues are \(e^{\pm i \arccos(E/\lambda)}\) and the energy is recovered via
eigenvalue_from_phase():
where \(\lambda = \sum_j |\alpha_j|\) is the 1-norm of the Hamiltonian coefficients.
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 |
Raw measured phase \(\varphi \in [0, 1)\). |
|
float |
Raw phase angle in radians: \(2\pi\varphi\). |
|
float |
Alias-resolved phase fraction. Equals |
|
float |
Alias-resolved phase angle in radians. |
|
float |
Energy computed from the measured phase via the container’s |
|
tuple[float, …] |
Energy candidates. For the unified |
|
float | None |
Reserved for alias resolution (currently |
|
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
Alias resolution is relevant for time-evolution-based QPE (Trotter) where the phase is periodic. It is not needed for qubitization because the cosine mapping is injective over the measurable range.
Phase estimation measures a phase \(\varphi \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.
Note
The current from_phase_fraction factory does not perform alias resolution automatically.
Alias resolution is the responsibility of the calling algorithm when needed.
Construction
QpeResult objects are typically created by the PhaseEstimation algorithm.
They can also be constructed manually using from_phase_fraction(), passing container.eigenvalue_from_phase as the phase-to-energy mapping.
Time evolution example
from qdk_chemistry.algorithms import create
from qdk_chemistry.data import QpeResult, QubitOperator
# Time-evolution QPE: U = e^{-iHt}, eigenvalue_from_phase wraps the angle.
hamiltonian = QubitOperator(
pauli_strings=["ZI", "IZ", "XX"], coefficients=[0.5, -0.3, 0.2]
)
evolution_time = 0.1
builder = create("hamiltonian_unitary_builder", "trotter", time=evolution_time)
unitary = builder.run(hamiltonian)
container = unitary.get_container()
result = QpeResult.from_phase_fraction(
method="iterative",
phase_fraction=0.423828125,
eigenvalue_from_phase=container.eigenvalue_from_phase,
bits_msb_first=(0, 1, 1, 0, 1, 1, 0, 0, 1, 0),
bitstring_msb_first="0110110010",
)
Qubitization example
from qdk_chemistry.algorithms import create
from qdk_chemistry.data import QpeResult, QubitOperator
# Qubitization QPE: W = walk operator, E = lambda * cos(2*pi*phi).
hamiltonian = QubitOperator(
pauli_strings=["ZI", "IZ", "XX"], coefficients=[0.5, -0.3, 0.2]
)
builder = create("hamiltonian_unitary_builder", "lcu", quantum_walk=True)
unitary = builder.run(hamiltonian)
walk_container = unitary.get_container()
result_qubitization = QpeResult.from_phase_fraction(
method="qubitization_qpe",
phase_fraction=0.25,
eigenvalue_from_phase=walk_container.eigenvalue_from_phase,
bits_msb_first=(0, 1, 0, 0),
bitstring_msb_first="0100",
)
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"Measured bits: {result.bits_msb_first}")
# Full summary
print(result.get_summary())
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
HamiltonianUnitaryBuilder: Hamiltonian simulation or block encoding methods
Serialization: Data persistence formats
See the
examples/qpe_stretched_n2.ipynbnotebook for an end-to-end QPE workflow