configuration_recovery flag in SKQDOptions controls how the SQD post-processing loop in haiqu.postprocess_skqd handles measurement bitstrings that hardware noise pushed out of the target particle-number sector. This page walks through what the flag does on a small Single-Impurity Anderson Model (SIAM), so you can decide whether to enable it.
The system
We use the same SIAM that ships with the simple SKQD example: four spatial orbitals (one impurity, three bath sites), at half-filling.postprocess_skqd run on 2 * norb = 8 qubits.
Bitstring layout
Each shot returns 8 bits. We split them into two halves: the left four bits encode beta (spin-down) occupations, the right four encode alpha (spin-up). Within each half, position 0 is the rightmost bit (orbital 0), then orbital 1, orbital 2, orbital 3 going left:00110011 means:
- Beta: orbitals 0 and 1 occupied (rightmost two bits of the left half).
- Alpha: orbitals 0 and 1 occupied (rightmost two bits of the right half).
Valid configurations
Becausenelec = (2, 2), a valid bitstring has exactly two ones in each half. There are valid configurations out of total. A handful of examples:
What hardware noise does
Read-out noise flips bits independently with some probability per qubit. A perfect shot of00110011 can land as 00010011 (one beta bit flipped 1→0) or 10110011 (one beta bit flipped 0→1). Both bitstrings are out of the (2, 2) sector.
The fraction of out-of-sector shots grows with the number of qubits and the per-qubit error rate. For 8 qubits at 1% per-qubit read-out error, roughly 8% of shots fall outside the sector; for 40 qubits at the same rate, it’s roughly 33%.
Default behavior: postselection
Withconfiguration_recovery=False (the default), each iteration of the SQD loop discards every out-of-sector shot. The bigger your system, the more shots you waste:
What configuration recovery does
Withconfiguration_recovery=True, from the second iteration onward the loop repairs out-of-sector bitstrings instead of discarding them, using the orbital occupancies measured at the previous iteration.
For our SIAM at , the converged orbital occupancies (alpha and beta both) are:
Read this as: orbital 0 is “almost always occupied” in the ground state, orbital 3 is “almost always empty,” and orbitals 1 and 2 each carry half an electron on average across the ground-state distribution.
The recovery procedure handles the alpha and beta halves independently. For each half:
- Compute a per-bit flip probability for every position. A 0 at a high-occupancy orbital is very likely to be flipped to 1; a 1 at a low-occupancy orbital is very likely to be flipped to 0; bits at orbitals near the expected density (
nelec / norb = 0.5) get a small floor probability. - Count how many bits are wrong (e.g., one too few for
n_beta = 2). - Pick exactly that many bits to flip, weighted by the flip probabilities from step 1.
These are the building blocks for the worked examples below.
Worked example 1: 00010011 → 00110011
Starting bitstring: 00010011. Beta half is 0001, so only beta orbital 0 is occupied — n_beta = 1, target is 2, so one beta 0 needs to flip to 1.
The 0-bits in beta are at orbitals 1, 2, 3. Their 0→1 flip probabilities (normalized within the 0-bit set) are:
Recovery picks orbital 1 or orbital 2 with about equal probability (~49.5% each), and orbital 3 only about 1% of the time. Both
00110011 and 01010011 are equally-weighted dominant ground-state determinants, so either outcome lands in the high-weight part of the subspace; we essentially never recover into the much higher-energy configuration with orbital 3 occupied.
Worked example 2: 10110011 → 00110011
Starting bitstring: 10110011. Beta half is 1011 — three orbitals occupied (0, 1, 3) — so n_beta = 3, one beta 1 needs to flip to 0.
The 1-bits in beta are at orbitals 0, 1, 3. Their 1→0 flip probabilities (normalized within the 1-bit set) are:
Recovery picks orbital 3 about 99% of the time. The recovered beta is
0011, putting the bitstring back to 00110011 — one of the dominant ground-state determinants.
In words: orbital 3 was “supposed to be empty” (occupancy 0.01) but the noisy bitstring had it occupied; recovery confidently turns it off.
Why iteration 1 has no recovery
The procedure needs orbital occupancies, which only become available after the first diagonalization. Iteration 1 always falls back to plain Hamming-weight postselection; recovery kicks in from iteration 2 onward and continues until the loop converges ormax_iterations is reached.
This is a self-consistent loop: each iteration’s diagonalization produces occupancies that feed the next iteration’s recovery, which produces a different subspace, which produces refined occupancies, and so on.
When to enable it
The benefit grows with the fraction of out-of-sector samples. For a 40-qubit hardware run, recovery is typically the difference between converging cleanly and failing to. For a 4-qubit toy model on a simulator, it usually does nothing.
References
- Yu, J. et al. Quantum-Centric Algorithm for Sample-Based Krylov Diagonalization. arXiv:2501.09702 (2025).
- Robledo-Moreno, J. et al. Chemistry Beyond Exact Solutions on a Quantum-Centric Supercomputer. arXiv:2405.05068 (2024) — the original SQD configuration-recovery procedure.
- IBM Quantum tutorial: Sample-based Krylov quantum diagonalization of a fermionic lattice model.
- Implementation:
qiskit_addon_sqd.configuration_recovery.recover_configurations.