Skip to content
Home/Blog/State Tomography with Qiskit Experiments: Reconstructing What You Built
QiskitAlgorithmsBest Practices

State Tomography with Qiskit Experiments: Reconstructing What You Built

How to use StateTomography in Qiskit Experiments 0.14 to reconstruct a qubit's density matrix from measurements and compute its fidelity against the state you intended to prepare.

FreeQuantumComputing
·· 6 min read

Benchmarks like Quantum Volume and randomized benchmarking tell you how good a device's gates are in general. State tomography answers a narrower, circuit-specific question: for this particular circuit, what state did you prepare, and how close is it to what you intended. Qiskit Experiments (version 0.14) implements this through the StateTomography class.

pip install qiskit-experiments

Why you can't measure the state directly

A single measurement collapses a qubit to a classical outcome and destroys the superposition you were trying to characterize. Measurement in the computational basis tells you populations, not phase, the same limitation that makes distinguishing T1 from T2 nontrivial. Tomography works around this by preparing the same state repeatedly and measuring it in different bases (X, Y, and Z), then reconstructing the full density matrix from the combined statistics rather than from any single measurement.

Running StateTomography on a GHZ state

import qiskit
from qiskit_experiments.library import StateTomography
from qiskit_aer import AerSimulator
from qiskit_ibm_runtime.fake_provider import FakePerth

backend = AerSimulator.from_backend(FakePerth())

nq = 2
qc_ghz = qiskit.QuantumCircuit(nq)
qc_ghz.h(0)
qc_ghz.s(0)
for i in range(1, nq):
    qc_ghz.cx(0, i)

exp = StateTomography(qc_ghz)
exp_data = exp.run(backend, seed_simulation=100).block_for_results()

You pass the circuit you want characterized directly to StateTomography. The experiment handles generating the basis-rotation circuits and running all of them for you, so this one call runs several circuit variants under the hood, not only the one you passed in.

Reading the fitted density matrix

state_result = exp_data.analysis_results("state", dataframe=True).iloc[0]
print(state_result.value)

state_result.value is the fitted density matrix, a DensityMatrix object representing the best statistical reconstruction of what the circuit produced, noise and all, not the ideal target state.

Reading the fidelity number

The result you usually care about most is a single comparable number, not the full matrix:

fid_result = exp_data.analysis_results("state_fidelity", dataframe=True).iloc[0]
print(f"State fidelity = {fid_result.value:.5f}")

state_fidelity compares the fitted density matrix against the ideal state the input circuit targets, and it's this number, not the matrix itself, that answers "how close did the circuit come." A fidelity of 1.0 means the reconstructed state matches the ideal target exactly. Real hardware GHZ states typically land well below that once qubit count grows past two or three, since every additional entangling gate adds its own error contribution.

Why the reconstructed state isn't automatically physical

Statistical noise in the measurement data means a naive reconstruction sometimes produces a matrix that isn't a valid quantum state (negative eigenvalues, for instance), an artifact of finite sampling rather than a claim about the actual physics. Qiskit Experiments' default fitter constrains the reconstruction to be a physically valid density matrix (positive semidefinite, trace one), which is why state_result.value is always a legitimate quantum state even when the raw measurement counts, taken naively, wouldn't be.

When tomography is and isn't the right tool

State tomography's cost grows fast: the number of measurement bases needed scales exponentially with qubit count, which is why it's practical for verifying a two- or three-qubit state and impractical for checking a fifty-qubit one. Reach for it when you need to confirm a specific small circuit is doing what you designed it to do, debugging a state-prep routine, verifying an entangled-state generator, checking a variational circuit's output at a fixed parameter setting. For characterizing a device's general gate quality rather than one circuit's output, randomized benchmarking or Quantum Volume scale better and answer a more useful question for that purpose.

Try this next

  • Run StateTomography on a Bell state and a GHZ state on the same fake-backend simulator, and compare fidelities as you add qubits, watching the fidelity drop as more two-qubit gates enter the circuit.
  • Swap in ProcessTomography from the same library to characterize a gate itself rather than a prepared state, useful for checking a custom or calibrated gate rather than a state-prep circuit.
  • Read the Qiskit Experiments manuals for the full verification-experiment library this and the RB post both draw from.