An Index is currently a single name::Symbol, so lattice Hamiltonians like $H = -J \sum_i (\sigma_i^+ \sigma_{i+1}^- + \mathrm{h.c.})$ can't be written natively — i+1 has no representation.
MVP: add a shift::Int field to Index so Index(name=:i, shift=1) means $i+1$. Touches:
- index_types.jl — struct,
==, hash, isless extended over (name, shift).
- index.jl —
change_index, get_indices, and especially _diagonal_split!: with shifts, decide when (i,1) colliding with free j on the same subspace should emit j → i+1.
- Per-operator
_site_compare — sort key becomes (space_index, name, shift).
- Numeric
Σ enumeration — respect boundary conditions (open i+1 ≤ N vs periodic (i mod N)+1) via a boundary=:open|:periodic kwarg on Σ.
Out of scope for the MVP: sparse-pattern DoubleIndexedVariable like J(i,j), generic j = f(i) for higher-shell shifts, and explicit boundary-condition objects.
Motivation: unblocks an indexed Heisenberg/XXZ chain example (spin-wave dispersion $\varepsilon(k) = J(1-\cos k)$ via Holstein-Primakoff).
An$H = -J \sum_i (\sigma_i^+ \sigma_{i+1}^- + \mathrm{h.c.})$ can't be written natively —
Indexis currently a singlename::Symbol, so lattice Hamiltonians likei+1has no representation.MVP: add a$i+1$ . Touches:
shift::Intfield toIndexsoIndex(name=:i, shift=1)means==,hash,islessextended over(name, shift).change_index,get_indices, and especially_diagonal_split!: with shifts, decide when(i,1)colliding with freejon the same subspace should emitj → i+1._site_compare— sort key becomes(space_index, name, shift).Σenumeration — respect boundary conditions (openi+1 ≤ Nvs periodic(i mod N)+1) via aboundary=:open|:periodickwarg onΣ.Out of scope for the MVP: sparse-pattern
DoubleIndexedVariablelikeJ(i,j), genericj = f(i)for higher-shell shifts, and explicit boundary-condition objects.Motivation: unblocks an indexed Heisenberg/XXZ chain example (spin-wave dispersion$\varepsilon(k) = J(1-\cos k)$ via Holstein-Primakoff).