Domain: Physics — Quantum Mechanics

Problem:
Consider a one-dimensional spin-\(\tfrac{1}{2}\) XXZ–Heisenberg chain of length \(L = 18\) with periodic boundary conditions, governed by the Hamiltonian
\(H = \sum_{j=1}^{L} \Big[ J_{xy}(1+\delta_j)\big(e^{i\phi/L} S_j^{+} S_{j+1}^{-} + e^{-i\phi/L} S_j^{-} S_{j+1}^{+}\big) + J_{zz}(1+\eta_j) S_j^{z} S_{j+1}^{z} \Big] + \sum_{j=1}^{L}\big(h_j S_j^{z} + D (S_j^{z})^{2}\big)\),

where  
- \(S_j^\alpha\) are spin-\(\tfrac{1}{2}\) Pauli operators at site \(j\),  
- \(S_j^\pm = S_j^x \pm i S_j^y\),  
- \(J_{xy} = 1.0\), \(J_{zz} = 1.3\), \(D = 0.15\), \(\phi = \pi/4\),  
- \((S_j^{z})^{2} = 1/4\) is a constant single-ion term.

**Deterministic disorder (no RNG):**  
Replace the Gaussian fields by the explicit fixed arrays
\(\delta = (0.113,\,-0.284,\,0.512,\,-0.091,\,0.337,\,-0.445,\,0.228,\,-0.019,\,0.404,\,-0.371,\,0.299,\,-0.154,\,0.221,\,-0.088,\,0.167,\,-0.311,\,0.052,\,-0.263)\),

\(\eta = (-0.192,\,0.341,\,-0.077,\,0.256,\,-0.418,\,0.109,\,-0.305,\,0.487,\,-0.044,\,0.233,\,-0.129,\,0.318,\,-0.271,\,0.064,\,-0.356,\,0.401,\,-0.185,\,0.092)\).

The quasiperiodic field is
\(h_j = 0.4\cos(2\pi\alpha j + \theta)\) for \(j = 1,\dots,18\), with \(\alpha = (\sqrt{5}-1)/2\) and \(\theta = 0.37\).

Impose the constraint \(S^z_{\mathrm{tot}} = 0\), i.e. exactly 9 spins up. Apply the Peierls phases \(e^{\pm i\phi/L}\) on every bond, including the periodic bond between sites \(18 \to 1\).

Construct the full Hamiltonian in the fixed-\(S^z\) sector of dimension \(\binom{18}{9}\), diagonalize it exactly, and compute the ground-state energy \(E_0\).

Return only \(E_0\) rounded to three decimal places.

Answer: -14.542

Solution code:
import math
import numpy as np
from scipy.sparse.linalg import LinearOperator, eigsh

def main():
    # -----------------------------
    # Model parameters
    # -----------------------------
    L    = 18
    Jxy  = 1.0
    Jzz  = 1.3
    phi  = math.pi / 4.0
    D    = 0.15

    alpha = (math.sqrt(5.0) - 1.0) / 2.0
    theta = 0.37

    # Deterministic "disorder" fields (fixed, seed-free)
    delta = np.array([
        0.113, -0.284,  0.512, -0.091,  0.337, -0.445,  0.228, -0.019,
        0.404, -0.371,  0.299, -0.154,  0.221, -0.088,  0.167, -0.311,
        0.052, -0.263
    ], dtype=np.float64)

    eta = np.array([
        -0.192,  0.341, -0.077,  0.256, -0.418,  0.109, -0.305,  0.487,
        -0.044,  0.233, -0.129,  0.318, -0.271,  0.064, -0.356,  0.401,
        -0.185,  0.092
    ], dtype=np.float64)

    # Quasi-periodic field h_j = 0.4 cos(2π α j + θ), j = 0,...,L-1
    j_sites = np.arange(1, L + 1, dtype=np.float64)
    h_arr = 0.4 * np.cos(2.0 * math.pi * alpha * j_sites + theta)

    # -----------------------------
    # Basis: S^z_tot = 0 → exactly 9 up spins out of 18
    # Represent each basis state by an integer bitmask of length L
    # bit j = 1 → spin up at site j, bit j = 0 → spin down.
    # -----------------------------
    def gen_basis_popcount(n, k):
        """
        Generate all n-bit integers with exactly k bits set.
        Uses Gosper's hack, no itertools.
        """
        if k < 0 or k > n:
            return []
        if k == 0:
            return [0]

        total = math.comb(n, k)
        masks = []
        x = (1 << k) - 1          # smallest int with k bits set
        limit = 1 << n

        while x < limit and len(masks) < total:
            masks.append(int(x))
            # Gosper's hack: next integer with same popcount
            c = x & -x
            r = x + c
            x = (((r ^ x) >> 2) // c) | r
        return masks

    Nup = L // 2  # 9
    basis = np.array(gen_basis_popcount(L, Nup), dtype=np.int64)
    dim = len(basis)

    # Inverse map: mask -> index in basis
    idx_dict = {int(m): i for i, m in enumerate(basis)}

    # -----------------------------
    # Precompute diagonal energies
    # H_diag(mask) = sum_j h_j S_j^z
    #              + sum_j Jzz (1+η_j) S_j^z S_{j+1}^z
    #              + D (S_j^z)^2  (constant shift)
    # with S_j^z = ±1/2 → (S_j^z)^2 = 1/4.
    # -----------------------------
    const_shift = D * 0.25 * L  # sum_j D (1/4)

    diag = np.zeros(dim, dtype=np.float64)

    for i, m in enumerate(basis):
        m_int = int(m)
        e = 0.0

        # local fields h_j S_j^z
        for j in range(L):
            sz_j = 0.5 if ((m_int >> j) & 1) else -0.5
            e += h_arr[j] * sz_j

        # ZZ-couplings Jzz (1+η_j) S_j^z S_{j+1}^z
        for j in range(L):
            jp = (j + 1) % L
            s_j  = 1 if ((m_int >> j)  & 1) else -1
            s_jp = 1 if ((m_int >> jp) & 1) else -1
            e += Jzz * (1.0 + eta[j]) * 0.25 * s_j * s_jp

        diag[i] = e + const_shift

    # -----------------------------
    # Precompute XY off-diagonal "hops"
    #
    # Term: Jxy (1+δ_j) [ e^{+i φ/L} S_j^+ S_{j+1}^- + e^{-i φ/L} S_j^- S_{j+1}^+ ].
    #
    # In the S^z basis:
    # S_j^+ S_{j+1}^- acts only on |↓_j ↑_{j+1}⟩ and yields |↑_j ↓_{j+1}⟩,
    # S_j^- S_{j+1}^+ acts only on |↑_j ↓_{j+1}⟩ and yields |↓_j ↑_{j+1}⟩.
    # -----------------------------
    twist_fwd = complex(np.exp(1j * phi / L))
    twist_bwd = complex(np.conj(twist_fwd))

    # adjacency list: for each basis index i, list of (i2, coeff)
    adj = [[] for _ in range(dim)]

    for i, m in enumerate(basis):
        m_int = int(m)
        for j in range(L):
            jp = (j + 1) % L
            bit_j  = (m_int >> j)  & 1
            bit_jp = (m_int >> jp) & 1
            Jxy_j = Jxy * (1.0 + delta[j])

            # S_j^+ S_{j+1}^-: (↓,↑) → (↑,↓)
            if (bit_j == 0) and (bit_jp == 1):
                new_mask = m_int | (1 << j)
                new_mask &= ~(1 << jp)
                i2 = idx_dict[new_mask]
                adj[i].append((i2, Jxy_j * twist_fwd))

            # S_j^- S_{j+1}^+: (↑,↓) → (↓,↑)
            if (bit_j == 1) and (bit_jp == 0):
                new_mask = (m_int & ~(1 << j)) | (1 << jp)
                i2 = idx_dict[new_mask]
                adj[i].append((i2, Jxy_j * twist_bwd))

    # -----------------------------
    # Matrix-free H·v using precomputed diag and adj
    # -----------------------------
    def H_matvec(x):
        # start from diagonal contribution
        y = diag * x
        # add off-diagonal XY terms
        for i, row in enumerate(adj):
            amp = x[i]
            if abs(amp) < 1e-14:
                continue
            for i2, coeff in row:
                y[i2] += coeff * amp
        return y

    H = LinearOperator((dim, dim), matvec=H_matvec, dtype=np.complex128)

    # -----------------------------
    # Ground state via Lanczos / ARPACK (smallest algebraic eigenvalue)
    # -----------------------------
    # NOTE: For dim = 48620 this is heavy but feasible in a compiled SciPy stack.
    evals, _ = eigsh(H, k=1, which='SA', tol=1e-9, maxiter=50000, ncv=60)
    E0 = float(np.real(evals[0]))
    return E0

if __name__ == "__main__":
    E0 = main()
    # Final output: ground-state energy to 3 decimal places
    print(f"{E0:.3f}")