Skip to content

fix(uhfk): handle spin-block Transfer entries consistently in hermiticity check and sublattice fold - #164

Open
aoymt wants to merge 2 commits into
developfrom
fix/spin-block-transfer
Open

fix(uhfk): handle spin-block Transfer entries consistently in hermiticity check and sublattice fold#164
aoymt wants to merge 2 commits into
developfrom
fix/spin-block-transfer

Conversation

@aoymt

@aoymt aoymt commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Two related fixes for how UHFk handles spin-block Transfer entries — orbital
indices in [norb, 2*norb) from Wannier90 spin-orbital-format files read in
normal mode (enable_spin_orbital = false). The documented behavior for such
entries is "ignored with a warning" (_make_ham_trans), but two other
consumers of the Transfer table did not implement it:

  1. _check_hermite crashed with an unhandled IndexError (fix in
    src/hwave/solver/uhfk.py). The check scattered every entry into an array
    of shape (nx, ny, nz, norb, norb), so any spin-block index was out of
    bounds. Since _check_interaction runs in __init__ before
    _make_ham_trans, the documented ignored-with-warning path was unreachable
    for such files. With a sublattice fold the inflated self.norb happened to
    absorb the indices instead, but the dropped entries landed in
    sublattice-orbital slots they do not belong to and could spuriously fail
    the strict_hermite check.

  2. fold.reshape_interaction silently corrupted H(k) (fix in
    src/hwave/solver/fold.py). The normal-mode fold
    a + norb_phys_orig * cellidx relabels a spin-block index onto the folded
    index of a genuine sublattice orbital. The relabeled entries then pass
    _make_ham_trans's index guard and enter H(k) as spurious inter-orbital
    hoppings instead of being dropped. Verified repro: a 1-orbital chain with
    CellShape = [6,1,1], SubShape = [3,1,1], onsite −1 and spin-block hops
    0.7 at R = ±1 produced 0.7 off-diagonals in H(k) where −1 × identity is
    correct. RPA/FLEX share this fold and had the same latent defect.

Fix

Both sites now skip entries with an orbital index >= norb_orig, matching the
semantics of _make_ham_trans dropping them from H(k):

  • _check_hermite sizes its array with the pre-reshape norb (the check runs
    before the sublattice reshape, so Transfer still carries original-geometry
    indices) and excludes spin-block entries from the hermiticity comparison —
    the check covers exactly the terms that end up in H(k).
  • reshape_interaction skips spin-block entries before folding and emits the
    ignore-warning itself, since the dropped entries can no longer reach the
    solvers' own spin-block warning. No duplicate logs: without a sublattice the
    warning still comes from _make_ham_trans, with one it comes from the fold.

Per-consumer guards were chosen deliberately as the minimal fix; consolidating
the drop into a single normalization point right after _check_orbital_index
is planned as a follow-up refactor once the current feature work stabilizes.

Tests

New regression file tests/test_uhfk_spin_block_transfer.py (3 tests, all
verified to fail before their respective fix):

  • construction with a spin-block entry and SubShape = [1,1,1] must not raise
    (the original IndexError), and H(k) must equal the orbital block ⊗ spin
    identity — the entry is deliberately non-hermitian to pin down that dropped
    entries are excluded from the check rather than checked in a larger array;
  • with the default SubShape (= CellShape), an unpaired spin-block hop must
    not abort the strict hermiticity check via mis-folded slots;
  • for the fold repro above, the folded Transfer must carry no spin-block
    indices and ham_trans must equal −1 × identity.

Full sweep passing: tests/test_uhfk_*.py, test_uhf.py,
test_wraparound_hopping.py, test_block_matrix.py, test_qlms_run_result.py,
plus the RPA fold-related tests (test_rpa_fold_collision.py,
test_rpa_trans_mod.py, test_rpa_so_trans_mod.py, test_rpa_geom_norb.py)
and test_rpa_1orb/2orb/spin/output/ext — 146 + 33 tests.

🤖 Generated with Claude Code

aoymt and others added 2 commits August 24, 2026 18:41
…sfer entries

In normal mode (enable_spin_orbital=False) a spin-orbital-format Transfer
file may carry orbital indices up to 2*norb; _check_orbital_index accepts
them for compatibility and _make_ham_trans drops them with a warning. But
_check_hermite scattered every entry into a (nx,ny,nz,norb,norb) array, so
a spin-block index raised an unhandled IndexError during __init__ and the
documented ignored-with-warning path was unreachable. With a sublattice
fold the inflated self.norb happened to absorb the indices instead, and
the dropped entries landed in sublattice-orbital slots they do not belong
to, spuriously failing the strict hermiticity check.

Size the check array with the pre-reshape norb (the check runs before the
sublattice reshape) and skip the spin-block entries, matching what
_make_ham_trans keeps in H(k).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nto H(k)

The normal-mode branch of fold.reshape_interaction folds orbital indices
with the physical stride a + norb_phys_orig * cellidx, which relabels a
spin-block index (a >= norb_phys_orig, legal in the compatibility path for
spin-orbital-format files read with enable_spin_orbital=False) onto the
folded index of a genuine sublattice orbital. The relabeled entries then
pass _make_ham_trans's index guard and enter H(k) as spurious
inter-orbital hoppings, silently corrupting the Hamiltonian instead of
being dropped: on a 1-orbital chain with CellShape=[6,1,1],
SubShape=[3,1,1], onsite -1 and spin-block hops 0.7 at R=+-1, H(k) gained
0.7 off-diagonals where -1 * identity is correct. RPA/FLEX share this
fold and had the same latent defect.

Skip such entries before folding, consistent with the solvers dropping
them from H(k), and emit the ignore-warning from the fold: the dropped
entries no longer reach the solvers' own spin-block warning.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant