"""Reciprocal-space exchange matrix J(q) and its eigenvalue spectrum."""
from __future__ import annotations
from typing import Dict
import numpy as np
[docs]
def build_jq_matrices(bond_data: Dict, q_points: np.ndarray) -> np.ndarray:
"""Compute :math:`J_{αβ}(q) = Σ_{\\text{bonds}(α,β)} JS²_n · e^{i\\,q · r_{αβ}}`.
Returns a complex array of shape ``(N_q, N_sub, N_sub)``.
"""
N_q = len(q_points)
n_sub = bond_data["n_sub"]
Jq = np.zeros((N_q, n_sub, n_sub), dtype=complex)
for (alpha, beta), bond_list in bond_data["bonds"].items():
vecs = np.array([b[0] for b in bond_list])
Jvals = np.array([b[1] for b in bond_list])
phases = np.exp(1j * (q_points @ vecs.T))
Jq[:, alpha, beta] += phases @ Jvals
return Jq
[docs]
def compute_eigenvalues_all_q(Jq: np.ndarray) -> np.ndarray:
"""Diagonalise the Hermitian J(q) at every q.
Returns a real array ``(N_q, N_sub)`` of eigenvalues sorted descending.
Used for T_c and q₀ search; the magnon dispersion uses the LSWT
dynamical matrix instead (see :mod:`mag4.magnon.dispersion`).
"""
N_q, n_sub, _ = Jq.shape
Jq_herm = 0.5 * (Jq + Jq.swapaxes(1, 2).conj())
evals = np.zeros((N_q, n_sub))
for iq in range(N_q):
ev = np.linalg.eigvalsh(Jq_herm[iq])
evals[iq] = ev[::-1]
return evals