nDot.io physics
08-ilang-propagation / 08-tilt
08tiltverified

Determines whether a push on one cell orients rotation-symmetric exchange cells far away, how small deviations match the anchored oscillator field, and which sources have a long-range mutual cost.

Code of version 4

ed_push.py6 KB · raw
"""Check (item 1): exact diagonalization of exchange cells with a push.

C = J sum_<xy> S_x.S_y - h_p S^3_h  (J = 1, n = e_3), spin S = 1/2 and S = 1.
Clusters: rings of even size L (S=1/2: 8,12,16,20; S=1: 6,8,10,12) and the
16-object periodic cubic cluster Z^3 / Lambda, Lambda spanned by (2,2,0),(2,0,2),(0,2,2).
C commutes with M = sum_x S^3_x.  The two lowest eigenvalues are computed in EVERY sector
M = -NS, ..., NS, at h_p = 0 and at the sampled push strengths HPS.  In each sector the lowest
eigenvalue is simple (Perron-Frobenius after the Marshall sign change; the push is diagonal),
so the lowest eigenvector of C is unique iff the lowest sector value lies strictly below the
lowest values of all other sectors and below the second value of its own sector.
Output: output/ed_push.txt
"""
from pathlib import Path
from collections import deque
import itertools
import numpy as np
import scipy.sparse as sp
from scipy.sparse.linalg import eigsh

OUT = Path(__file__).parent / "output"
OUT.mkdir(exist_ok=True)
HPS = [0.01, 0.1, 0.3, 1.0, 3.0, 10.0]


def ring(L):
    links = [(i, (i + 1) % L) for i in range(L)]
    eps = np.array([(-1) ** i for i in range(L)])
    return links, eps


def cubic16():
    A = np.array([[2, 2, 0], [2, 0, 2], [0, 2, 2]]).T  # columns are the periods
    Ainv = np.linalg.inv(A)

    def same(u, v):
        c = Ainv @ (np.array(u) - np.array(v))
        return np.allclose(c, np.round(c))

    reps = []
    for p in itertools.product(range(4), repeat=3):
        if not any(same(p, q) for q in reps):
            reps.append(p)
    assert len(reps) == 16

    def idx(p):
        return [k for k, q in enumerate(reps) if same(p, q)][0]

    links = set()
    for k, p in enumerate(reps):
        nb = set()
        for d in np.eye(3, dtype=int):
            for s in (1, -1):
                j = idx(tuple(np.array(p) + s * d))
                nb.add(j)
                links.add(tuple(sorted((k, j))))
        assert len(nb) == 6
    links = sorted(links)
    assert len(links) == 48
    eps = np.array([(-1) ** (sum(p) % 2) for p in reps])
    for a, b in links:
        assert eps[a] != eps[b]
    return links, eps, reps


def distances(links, n, h=0):
    adj = [[] for _ in range(n)]
    for a, b in links:
        adj[a].append(b)
        adj[b].append(a)
    d = [-1] * n
    d[h] = 0
    q = deque([h])
    while q:
        u = q.popleft()
        for v in adj[u]:
            if d[v] < 0:
                d[v] = d[u] + 1
                q.append(v)
    return np.array(d)


def sector(n, S2, M2):
    """Basis states (digit arrays, digit = m + S) with 2*sum(m) = M2; S2 = 2S."""
    d = S2 + 1
    codes = np.arange(d ** n, dtype=np.int64)
    digits = np.zeros((codes.size, n), dtype=np.int8)
    c = codes.copy()
    for i in range(n):
        digits[:, i] = c % d
        c //= d
    tot = 2 * digits.sum(axis=1).astype(np.int64) - n * S2
    keep = tot == M2
    return codes[keep], digits[keep]


def build(n, S2, M2, links, J=1.0):
    S = S2 / 2.0
    d = S2 + 1
    codes, digits = sector(n, S2, M2)
    m = digits.astype(float) - S
    diag = np.zeros(codes.size)
    rows, cols, vals = [], [], []
    for a, b in links:
        diag += J * m[:, a] * m[:, b]
        for i, j in ((a, b), (b, a)):  # S^+_i S^-_j
            ok = (digits[:, i] < S2) & (digits[:, j] > 0)
            src = np.nonzero(ok)[0]
            new = codes[src] + d ** i - d ** j
            dst = np.searchsorted(codes, new)
            amp = 0.5 * J * np.sqrt(S * (S + 1) - m[src, i] * (m[src, i] + 1)) \
                * np.sqrt(S * (S + 1) - m[src, j] * (m[src, j] - 1))
            rows.append(dst); cols.append(src); vals.append(amp)
    if rows:
        off = sp.csr_matrix((np.concatenate(vals), (np.concatenate(rows), np.concatenate(cols))),
                            shape=(codes.size, codes.size))
    else:
        off = sp.csr_matrix((codes.size, codes.size))
    return off, diag, m


def lowest(H, k=1):
    if H.shape[0] <= 1500:
        w, v = np.linalg.eigh(H.toarray())
        return w[:k], v[:, :k]
    w, v = eigsh(H, k=k, which="SA", tol=1e-12)
    o = np.argsort(w)
    return w[o], v[:, o]


def run(name, n, S2, links, eps, out):
    dist = distances(links, n)
    far = np.nonzero(dist == dist.max())[0]
    out.append(f"\n## {name}: N={n}, S={S2}/2, links={len(links)}, far sites {[int(f) for f in far]}"
               f" at distance {dist.max()}; sectors searched: all M = {-n * S2 / 2:g}, ..., {n * S2 / 2:g}")
    hps = [0.0] + HPS
    res = {hp: [] for hp in hps}
    for M2 in range(-n * S2, n * S2 + 1, 2):
        off, diag, m = build(n, S2, M2, links)
        for hp in hps:
            H = off + sp.diags(diag - hp * m[:, 0])
            k = 2 if H.shape[0] > 1 else 1
            w, v = lowest(H, k=k)
            e2 = w[1] if k == 2 else np.inf
            p = np.abs(v[:, 0]) ** 2
            sz = p @ m
            res[hp].append((w[0], e2, M2, float(np.mean(eps[far] * sz[far])), float(sz[0])))
    out.append("h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)")
    for hp in hps:
        best = min(res[hp], key=lambda t: t[0])
        nxt = min([best[1]] + [t[0] for t in res[hp] if t[2] != best[2]])
        uniq = best[0] < nxt - 1e-9
        out.append(f"{hp:6.2f}  {best[2] / 2:5.1f}  {best[0]:.10f}   {nxt:.10f}        {nxt - best[0]:.3e}  {uniq!s:6s}"
                   f"   {best[3]: .6f}            {best[4]: .6f}")
    b0 = min(res[0.0], key=lambda t: t[0])
    n0 = min([b0[1]] + [t[0] for t in res[0.0] if t[2] != b0[2]])
    out.append(f"no push: lowest eigenvector in M=0 and unique (a total-spin singlet): {b0[2] == 0 and b0[0] < n0 - 1e-9}")


def main():
    out = ["# ED check, item 1: exchange cells, J=1, push -h_p S^3_h at h=0 (class +); all sectors of M searched"]
    for L in (8, 12, 16, 20):
        links, eps = ring(L)
        run(f"ring L={L}", L, 1, links, eps, out)
    links, eps, reps = cubic16()
    out.append("\n16-object cubic cluster sites (representatives mod Lambda): " + str(reps))
    out.append("links: each site x to x+e_i, i=1,2,3 (mod Lambda); 48 links, 6 distinct neighbours each")
    run("cubic cluster 16", 16, 1, links, eps, out)
    for L in (6, 8, 10, 12):
        links, eps = ring(L)
        run(f"ring L={L}", L, 2, links, eps, out)
    (OUT / "ed_push.txt").write_text("\n".join(out) + "\n")
    print("\n".join(out))


if __name__ == "__main__":
    main()
spinwave_mutual.py17 KB · raw
"""Check (item 3, leading order in 1/S): mutual cost of two held sources on the cubic torus.

Units J S = 1.  C_2 = 1/2 P^T T P + 1/2 Q^T V Q, T_k = z(1+gamma_k), V_k = z(1-gamma_k); q1 = Q, q2 = E P.
(1) Transverse direction sources (linear in q): separation part from ghat; single objects, two-object cells,
    and a single object against a cell along the separation (midpoint against end-point separation).
(2) Static quadratic sources dH_i = 1/2 Q^T A_i Q + 1/2 P^T B_i P (along-n sources on objects and cells; changed
    links R2 in four orientation pairs): E_12 = -2 int_0^inf dtau <dH_1(tau) dH_2(0)>_c, Wick with G_QQ, G_PP and
    G_QP = (i/2) F (tau > 0); far from the push: the two zero modes (k = 0, k = Q) are left out.  R2 is compared
    with the continuum formula at the separation of the link midpoints.
(3) Held spin R1 with the retarded vertex of Step 12, K(nu) = a(nu) 1 + b(nu) eps (per unit |g'| s_b):
    a = nu^2/(nu^2+D^2), b = sgn(sigma) eps_x D nu/(nu^2+D^2), D = |g'|/J;
    E_12 = -1/2 int dnu/2pi Tr[K1 G12 K2 G21], lattice G(nu) at (r,0,0) by summing over (k2,k3) for each k1,
    tori L = 32, 64, 128, 256; against the continuum crossover function
    J S E/(|g'1 g'2| s1 s2) = -kappa_par F(beta)/r^3, beta = 2 r D / sqrt(2z) (A), and against the same with the
    off-diagonal part G12 = G0 (1 + gam eps), gam = -(eps1+eps2) nu/T_0, of the continuum covariance (B).
Output: output/spinwave_mutual.txt
"""
from pathlib import Path
import numpy as np
from scipy.integrate import quad
from scipy.special import ive
from scipy import fft as sfft

OUT = Path(__file__).parent / "output"
OUT.mkdir(exist_ok=True)
Z = 6
CS = np.sqrt(2 * Z)                       # speed of the copies, units J S = 1
KAP = np.sqrt(2 * Z) / (32 * np.pi ** 3)  # kappa_par
PRE = np.sqrt(3) / (8 * np.pi ** 3)       # prefactor of (8.17)


def kgrid(L):
    k = 2 * np.pi * np.arange(L) / L
    c = np.cos(k)
    g = (c[:, None, None] + c[None, :, None] + c[None, None, :]) / 3.0
    return g


def ghat(L):
    k = 2 * np.pi * np.arange(L) / L
    lap = 2 * ((1 - np.cos(k))[:, None, None] + (1 - np.cos(k))[None, :, None] + (1 - np.cos(k))[None, None, :])
    inv = np.zeros_like(lap)
    inv[lap > 1e-12] = 1.0 / lap[lap > 1e-12]
    return np.real(np.fft.ifftn(inv))


def ghat_inf(x):
    """Infinite cubic lattice: (Lap^{-1})(x) = int_0^inf prod_i e^{-2t} I_{x_i}(2t) dt."""
    f = lambda t: np.prod([ive(abs(int(c)), 2 * t) for c in x])
    return quad(f, 0, np.inf, limit=400, epsabs=1e-13, epsrel=1e-11)[0]


def eps(x):
    return (-1) ** (int(sum(x)) % 2)


def check_58(L=6, eta=0.7):
    n = L ** 3
    co = np.array(np.unravel_index(np.arange(n), (L,) * 3)).T
    adj = np.zeros((n, n))
    for d in range(3):
        sh = co.copy(); sh[:, d] = (sh[:, d] + 1) % L
        j = np.ravel_multi_index(sh.T, (L,) * 3)
        adj[np.arange(n), j] += 1; adj[j, np.arange(n)] += 1
    V = Z * np.eye(n) - adj
    V[0, 0] += eta
    Ga = np.linalg.inv(V)
    g = ghat(L).ravel()
    dif = lambda a, b: np.ravel_multi_index(tuple((co[a] - co[b]) % L), (L,) * 3)
    err = 0.0
    for a, b in [(5, 17), (40, 101), (3, 3), (0, 77)]:
        f = 1 / eta + g[dif(a, b)] - g[dif(a, 0)] - g[dif(b, 0)] + g[0]
        err = max(err, abs(f - Ga[a, b]))
    return err


def pert(kind, x, e=None):
    """Return (A, B) as lists of (site, site, value), per unit strength."""
    x = tuple(x)
    if kind == "along":
        A = [(x, x, -eps(x))]
        return A, A
    if kind == "along_cell":
        x2 = (x[0], x[1] + 1, x[2])
        A = [(x, x, -eps(x)), (x2, x2, -eps(x))]
        return A, A
    if kind == "link":
        y = tuple(np.array(x) - np.array(e))
        A = [(x, x, 1), (y, y, 1), (x, y, -1), (y, x, -1)]
        B = [(x, x, 1), (y, y, 1), (x, y, 1), (y, x, 1)]
        return A, B
    raise ValueError(kind)


def contraction(M1, M2, L):
    w, i1, i2 = [], [], []
    for a, b, u in M1:
        for c, d, v in M2:
            w.append(u * v)
            i1.append(np.ravel_multi_index(tuple(np.mod(np.array(a) - np.array(c), L)), (L,) * 3))
            i2.append(np.ravel_multi_index(tuple(np.mod(np.array(b) - np.array(d), L)), (L,) * 3))
    return np.array(w), np.array(i1), np.array(i2)


def mutual_quadratic(L, configs, nodes=300):
    g = kgrid(L)
    om = Z * np.sqrt(np.clip(1 - g ** 2, 0, None))
    mask = om > 1e-9
    Tk = np.where(mask, Z * (1 + g), 0.0)
    Vk = np.where(mask, Z * (1 - g), 0.0)
    omm = np.where(mask, om, 1.0)
    pre = []
    for (A1, B1), (A2, B2) in configs:
        pre.append((contraction(A1, A2, L), contraction(B1, B2, L),
                    contraction(A1, B2, L), contraction(B1, A2, L)))
    s, ws = np.polynomial.legendre.leggauss(nodes)
    lo, hi = np.log(1e-7), np.log(200.0)
    sv = 0.5 * (hi - lo) * s + 0.5 * (hi + lo)
    wv = 0.5 * (hi - lo) * ws
    acc = np.zeros(len(configs))
    for sj, wj in zip(sv, wv):
        tau = np.exp(sj)
        ex = np.where(mask, np.exp(-omm * tau), 0.0)
        GQ = sfft.ifftn(Tk / (2 * omm) * ex, workers=-1).real.ravel()
        GP = sfft.ifftn(Vk / (2 * omm) * ex, workers=-1).real.ravel()
        F = sfft.ifftn(ex, workers=-1).real.ravel()
        for n, (qq, pp, qp, pq) in enumerate(pre):
            val = 0.5 * np.sum(qq[0] * GQ[qq[1]] * GQ[qq[2]]) + 0.5 * np.sum(pp[0] * GP[pp[1]] * GP[pp[2]]) \
                - 0.125 * (np.sum(qp[0] * F[qp[1]] * F[qp[2]]) + np.sum(pq[0] * F[pq[1]] * F[pq[2]]))
            acc[n] += wj * tau * val
    return -2 * acc


def cont_link(e1, e2, e12, R):
    """Continuum (8.17) integral: J E/(delta1 delta2 S) for two changed links (unit vectors e1, e2 from y to x,
    e12 = eps_x1 eps_x2) whose midpoints are separated by the vector R."""
    R = np.asarray(R, float); Rn = np.linalg.norm(R); Rh = R / Rn
    E1 = np.r_[0, e1]; E2 = np.r_[0, e2]; t0 = np.r_[1.0, 0, 0, 0]
    M1 = np.outer(E1, E1) - (2 / Z) * np.outer(t0, t0)
    M2 = np.outer(E2, E2) - (2 / Z) * np.outer(t0, t0)

    def C(t):
        X = np.r_[t, Rh]; rho = np.linalg.norm(X); n = X / rho
        I = np.eye(4) - 4 * np.outer(n, n)
        cross = I[0, 0] * (E1 @ I @ E2) - (I @ E1)[0] * (I @ E2)[0]
        return (4 * np.trace(M1 @ I @ M2 @ I) - (16 / Z) * e12 * cross) / rho ** 8
    val = quad(C, -np.inf, np.inf, epsabs=1e-14, epsrel=1e-12)[0]
    return -np.sqrt(2 * Z) / (16 * np.pi ** 4) * val / Rn ** 7


def F_hat(beta, vs):
    """Continuum crossover function of (8.18) for equal held spins (beta1 = beta2 = beta), vs = sgn(s1 s2) e1 e2."""
    f = lambda u: np.exp(-u) * u ** 2 * (u ** 2 - vs * beta ** 2) / (u ** 2 + beta ** 2) ** 2
    if beta == 0:
        return 1.0
    return quad(f, 0, beta, limit=400, epsabs=1e-15, epsrel=1e-12)[0] + \
        quad(f, beta, np.inf, limit=400, epsabs=1e-15, epsrel=1e-12)[0]


def F_full(beta, r, e1, e2, s=1):
    """(8.18) including the off-diagonal part of the continuum covariance, G12 = G0 (1 + gam eps),
    gam = -(e1+e2) nu/T_0 with nu = c u/(2r); held spins with sgn(sigma1) = sgn(sigma2) = s."""
    T0 = 2 * Z

    def f(u):
        a = u ** 2 / (u ** 2 + beta ** 2)
        b1 = s * e1 * beta * u / (u ** 2 + beta ** 2)
        b2 = s * e2 * beta * u / (u ** 2 + beta ** 2)
        gam = (e1 + e2) * CS * u / (2 * r * T0)
        return np.exp(-u) * ((a * a - b1 * b2) * (1 - gam ** 2) + 2 * gam * a * (b1 + b2))
    if beta == 0:
        return quad(f, 0, np.inf, limit=400, epsabs=1e-15, epsrel=1e-12)[0]
    return quad(f, 0, beta, limit=400, epsabs=1e-15, epsrel=1e-12)[0] + \
        quad(f, beta, np.inf, limit=400, epsabs=1e-15, epsrel=1e-12)[0]


def r1_lattice(L, rs, deltas, nodes=240):
    """Lattice value of J S E_12/(|g'1 g'2| s1 s2) for held spins with sgn(sigma1) = sgn(sigma2) = +1 at 0 and
    (r,0,0).  G^QQ, G^PP, G^QP at (r,0,0) for all frequency nodes by summing over (k2,k3) for each k1
    (zero modes k = 0, Q left out)."""
    s, ws = np.polynomial.legendre.leggauss(nodes)
    lo, hi = np.log(1e-5), np.log(300.0)
    nus = np.exp(0.5 * (hi - lo) * s + 0.5 * (hi + lo))
    wv = 0.5 * (hi - lo) * ws
    k = 2 * np.pi * np.arange(L) / L
    c = np.cos(k)
    C23 = (c[:, None] + c[None, :]).ravel()
    nu2 = nus ** 2
    SQ = np.zeros((L, nodes)); SP = np.zeros((L, nodes)); SX = np.zeros((L, nodes))
    for i1 in range(L):
        g = (c[i1] + C23) / 3.0
        om2 = Z ** 2 * (1 - g ** 2)
        m = om2 > 1e-12
        g, om2 = g[m], om2[m]
        den = 1.0 / (nu2[:, None] + om2[None, :])
        SQ[i1] = den @ (Z * (1 + g))
        SP[i1] = den @ (Z * (1 - g))
        SX[i1] = -nus * den.sum(axis=1)
    cosm = np.cos(np.outer(rs, k)) / L ** 3
    GQ, GP, GX = cosm @ SQ, cosm @ SP, cosm @ SX          # (len(rs), nodes)
    acc = np.zeros((len(deltas), len(rs)))
    for ir, r in enumerate(rs):
        e1, e2 = 1, (-1) ** r
        g0, g1 = GQ[ir], e2 * GX[ir]                       # G12 = [[GQ, e2 GX], [-e1 GX, e1 e2 GP]]
        gp = e1 * e2 * GP[ir]
        for idl, D in enumerate(deltas):
            a = nu2 / (nu2 + D ** 2)
            b = D * nus / (nu2 + D ** 2)
            # Tr[K1 G12 K2 G21], K_i = a 1 + e_i b eps, G21 = G12(-nu)^T, written out for 2x2 matrices
            G12 = np.array([[g0, g1], [-e1 * GX[ir], gp]])
            G21 = np.array([[g0, e1 * GX[ir]], [-g1, gp]])
            K1 = np.array([[a, e1 * b], [-e1 * b, a]])
            K2 = np.array([[a, e2 * b], [-e2 * b, a]])
            M = np.einsum("ijn,jkn,kln,lin->n", K1, G12, K2, G21)
            acc[idl, ir] = np.sum(wv * nus * M)
    return -acc / (2 * np.pi)


def main():
    out = ["# Mutual cost of two held sources, leading order in 1/S, cubic torus (units as stated per block)"]
    out.append(f"\n(5.8) with kappa_h = J S, kappa_a = h_p against direct inverse (L=6): max error {check_58():.2e}")

    out.append("\n## (1) Transverse sources: separation part J E_r/(g1 g2 (m1perp.m2perp))")
    out.append("single objects: -eps1 eps2 ghat(r); cells (x, x+e2), + on the first object: -eps1 eps2 sum ghat")
    out.append(f"ghat_inf(0) = {ghat_inf((0, 0, 0)):.7f} (gamma_3 = 0.2527310)")
    out.append("r   eps1eps2   single: J E_r/(g1g2)  4 pi r ghat_inf(r)   cells: J E_r/(g1g2)  pi r sum ghat_inf"
               "   torus check: ghat_L(r)-ghat_L(8) for L=16, 32, 64 vs ghat_inf(r)-ghat_inf(8)")
    gl = {L: ghat(L) for L in (16, 32, 64)}
    g8 = ghat_inf((8, 0, 0))
    gi = {r: ghat_inf((r, 0, 0)) for r in range(2, 10)}
    for r in range(2, 9):
        e12 = (-1) ** r
        gs = gi[r]
        gc = 2 * gs + ghat_inf((r, 1, 0)) + ghat_inf((r, -1, 0))
        tor = "  ".join(f"{gl[L][r, 0, 0] - gl[L][8, 0, 0]:.6f}" for L in (16, 32, 64))
        out.append(f"{r:2d}   {e12:+d}        {-e12 * gs: .6f}            {4 * np.pi * r * gs:.4f}"
                   f"             {-e12 * gc: .6f}         {np.pi * r * gc:.4f}            {tor}   {gs - g8:.6f}")
    out.append("single object at 0, cell (r e1, (r+1) e1) along the separation: 4 pi R [ghat(r)+ghat(r+1)]/2 with"
               " R = midpoint separation r+1/2, and with R = end-point separation r")
    for r in range(2, 9):
        s2 = gi[r] + gi[r + 1]
        out.append(f"{r:2d}   midpoint: {2 * np.pi * (r + 0.5) * s2:.5f}   end point: {2 * np.pi * r * s2:.5f}")

    out.append("\n## Continuum coefficients")
    out.append(f"along n, single:  J S E/(g1 g2) = -eps1 eps2 kappa_par / r^3, kappa_par = sqrt(2z)/(32 pi^3) = {KAP:.7f}")
    out.append(f"held spin, r >> l_b: S E/(J sig1 sig2) = +eps1 eps2 lambda / r^5, lambda = 3 sqrt3/(8 pi^3) = "
               f"{3 * np.sqrt(3) / (8 * np.pi ** 3):.7f}")
    ex, ey, ez = [1, 0, 0], [0, 1, 0], [0, 0, 1]
    geo = {"par (e1,e1)": (ex, ex, lambda e: 43 / 6 + 2.5 * e),
           "perp same (e2,e2)": (ey, ey, lambda e: 4 / 3 - 5 / 12 * e),
           "perp cross (e2,e3)": (ey, ez, lambda e: 1 / 12),
           "mixed (e1,e2)": (ex, ey, lambda e: -0.5)}
    out.append("changed links, separation r e1: J E/(d1 d2 S) * r^7 = -sqrt3/(8 pi^3) a; numerical integral against a:")
    for nm, (u, v, af) in geo.items():
        for e in (1, -1):
            num = cont_link(u, v, e, [1, 0, 0])
            out.append(f"  {nm:20s} eps1eps2={e:+d}: integral {num:.8f}   closed form a={af(e):.6f}: {-PRE * af(e):.8f}")

    out.append("\n## (2) Static quadratic sources, lattice (zero modes left out); ratio = lattice / continuum")
    out.append("columns: r, eps1eps2, along single [J S E/(g1g2), ratio], along cell [.., ratio vs 4x], then J E/(d1d2S)"
               " and ratio for links: par (e1 at 0, e1 at r e1), perp same (e2, e2), perp cross (e2, e3), mixed (e1, e2);"
               " link continuum at the midpoint separation R")
    rs = list(range(2, 13))
    Rvec = {"par": lambda r: [r, 0, 0], "perp": lambda r: [r, 0, 0],
            "cross": lambda r: [r, 0.5, -0.5], "mixed": lambda r: [r + 0.5, -0.5, 0]}
    cref = {}
    for r in rs:
        e = (-1) ** r
        cref[r] = [-e * KAP / r ** 3, -4 * e * KAP / r ** 3,
                   cont_link(ex, ex, e, Rvec["par"](r)), cont_link(ey, ey, e, Rvec["perp"](r)),
                   cont_link(ey, ez, e, Rvec["cross"](r)), cont_link(ex, ey, e, Rvec["mixed"](r))]
    ratios = {}
    for L in (32, 64, 128):
        configs = []
        for r in rs:
            x2 = (r, 0, 0)
            configs += [(pert("along", (0, 0, 0)), pert("along", x2)),
                        (pert("along_cell", (0, 0, 0)), pert("along_cell", x2)),
                        (pert("link", (0, 0, 0), ex), pert("link", x2, ex)),
                        (pert("link", (0, 0, 0), ey), pert("link", x2, ey)),
                        (pert("link", (0, 0, 0), ey), pert("link", x2, ez)),
                        (pert("link", (0, 0, 0), ex), pert("link", x2, ey))]
        res = mutual_quadratic(L, configs).reshape(len(rs), 6)
        out.append(f"L = {L}")
        ratios[L] = np.zeros_like(res)
        for i, r in enumerate(rs):
            p = np.array(cref[r])
            ratios[L][i] = res[i] / p
            row = "  ".join(f"{res[i, j]: .3e} {res[i, j] / p[j]:6.3f}" for j in range(6))
            out.append(f"{r:2d} {(-1) ** r:+d}  {row}")
        if L == 32:
            along32 = res[:, 0].copy()
    out.append("ratio extrapolated to L -> infinity: Aitken from L = 32, 64, 128 (geometric finite-size error);"
               " the L = 128 value where the change from 64 to 128 is below 1e-3 or not geometric")
    for i, r in enumerate(rs):
        x1, x2, x3 = ratios[32][i], ratios[64][i], ratios[128][i]
        d1, d2 = x2 - x1, x3 - x2
        geo_ = (np.abs(d2) > 1e-3) & (d1 * d2 > 0) & (np.abs(d2) < np.abs(d1))
        exv = np.where(geo_, x3 + d2 / np.where(geo_, d1 / np.where(geo_, d2, 1.0) - 1, 1.0), x3)
        out.append(f"{r:2d}  " + "  ".join(f"{v:6.3f}" for v in exv))

    out.append("\n## (3) Held spin R1, retarded vertex (Step 12); J S E/(|g'1 g'2| s1 s2), sgn sigma1 = sgn sigma2,"
               " so vs = eps1 eps2 = (-1)^r")
    out.append("continuum crossover function F(beta) (equal held spins), with its small-beta form 1 - pi (3+vs) beta/4"
               " and large-beta form -2 vs/beta^2 + 24 (1+2 vs)/beta^4")
    for vs in (1, -1):
        for beta in (0.01, 0.03, 0.1, 0.3, 1.0, 3.0, 10.0, 30.0, 100.0):
            Fv = F_hat(beta, vs)
            out.append(f"  vs={vs:+d} beta={beta:7.2f}: F = {Fv: .6e}   small-beta form {1 - np.pi * (3 + vs) * beta / 4: .6e}"
                       f"   large-beta form {-2 * vs / beta ** 2 + 24 * (1 + 2 * vs) / beta ** 4: .6e}")
    lo_, hi_ = 0.1, 10.0
    for _ in range(80):
        mid = 0.5 * (lo_ + hi_)
        if F_hat(mid, 1) > 0:
            lo_ = mid
        else:
            hi_ = mid
    out.append(f"  vs=+1: F changes sign at beta_0 = {0.5 * (lo_ + hi_):.5f} (r_0 = beta_0 l_b / 2); vs=-1: F > 0 at every beta")
    deltas = [0.0, 0.2, 0.5, 2.0]
    out.append("lattice against continuum: D = |g'|/J = " + ", ".join(f"{d:g}" for d in deltas)
               + f"; l_b = sqrt(2z)/D = " + ", ".join("inf" if d == 0 else f"{CS / d:.2f}" for d in deltas))
    out.append("continuum A = (8.18): -kappa_par F(beta)/r^3; continuum B = (8.18) with the off-diagonal part of the"
               " covariance (nonzero for eps1 = eps2 only)")
    out.append("columns per D: lattice value, ratio lattice/A, ratio lattice/B")
    contA = np.array([[-KAP * F_hat(2 * r * D / CS, (-1) ** r) / r ** 3 for r in rs] for D in deltas])
    contB = np.array([[-KAP * F_full(2 * r * D / CS, r, 1, (-1) ** r) / r ** 3 for r in rs] for D in deltas])
    r1 = {}
    for L in (32, 64, 128, 256):
        r1[L] = r1_lattice(L, rs, deltas)
        out.append(f"L = {L}")
        for ir, r in enumerate(rs):
            row = [f"{r1[L][idl, ir]: .4e} {r1[L][idl, ir] / contA[idl, ir]:6.3f} {r1[L][idl, ir] / contB[idl, ir]:6.3f}"
                   for idl in range(len(deltas))]
            out.append(f"{r:2d} {(-1) ** r:+d}  " + "  ".join(row))
        if L == 32:
            dev = np.max(np.abs(r1[L][0] - np.array([(-1) ** r for r in rs]) * along32) / np.abs(along32))
            out.append(f"cross-check D = 0 (frequency domain) against the along-n single column (time domain), L = 32:"
                       f" max relative difference {dev:.2e}")
    out.append("ratio lattice/B extrapolated to L -> infinity: Aitken from L = 64, 128, 256 (as in block (2))")
    for ir, r in enumerate(rs):
        x1, x2, x3 = (r1[L][:, ir] / contB[:, ir] for L in (64, 128, 256))
        d1, d2 = x2 - x1, x3 - x2
        geo_ = (np.abs(d2) > 1e-3) & (d1 * d2 > 0) & (np.abs(d2) < np.abs(d1))
        exv = np.where(geo_, x3 + d2 / np.where(geo_, d1 / np.where(geo_, d2, 1.0) - 1, 1.0), x3)
        out.append(f"{r:2d} {(-1) ** r:+d}  " + "  ".join(f"{v:7.3f}" for v in exv)
                   + "   (continuum B: " + "  ".join(f"{contB[idl, ir]: .3e}" for idl in range(len(deltas))) + ")")
    (OUT / "spinwave_mutual.txt").write_text("\n".join(out) + "\n")
    print("\n".join(out))


if __name__ == "__main__":
    main()
spinwave_tilt.py3 KB · raw
"""Check (item 1(b), leading order in 1/S): first correction to m(x) far from the push.

Quadratic form (units J S = 1): C_2 = 1/2 P^T T P + 1/2 Q^T V Q with
V = Lap + eta P_h, T = E V E = Lap^+ + eta P_h, eta = h_p/(J S), E = diag(eps).
Ground-state covariances: <QQ^T> = 1/2 T^(1/2) (T^(1/2) V T^(1/2))^(-1/2) T^(1/2), same for P with T<->V.
First correction: m(x) = eps_h (S - dS(x)), dS(x) = (<Q_x^2> + <P_x^2> - 1)/2.
Output: output/spinwave_tilt.txt
"""
from pathlib import Path
import numpy as np

OUT = Path(__file__).parent / "output"
OUT.mkdir(exist_ok=True)


def lattice(L, D):
    n = L ** D
    coords = np.array(np.unravel_index(np.arange(n), (L,) * D)).T
    adj = np.zeros((n, n))
    for d in range(D):
        sh = coords.copy()
        sh[:, d] = (sh[:, d] + 1) % L
        j = np.ravel_multi_index(sh.T, (L,) * D)
        adj[np.arange(n), j] += 1
        adj[j, np.arange(n)] += 1
    eps = (-1.0) ** coords.sum(axis=1)
    return coords, adj, eps


def sqrtm_sym(A, power):
    w, U = np.linalg.eigh(A)
    return (U * w ** power) @ U.T


def dS_push(L, D, eta):
    coords, adj, eps = lattice(L, D)
    z = 2 * D
    n = L ** D
    V = z * np.eye(n) - adj
    V[0, 0] += eta
    T = (eps[:, None] * V) * eps[None, :]
    Vh = sqrtm_sym(V, 0.5)
    Th = (eps[:, None] * Vh) * eps[None, :]
    covQ = 0.5 * Th @ sqrtm_sym(Th @ V @ Th, -0.5) @ Th
    covP = 0.5 * Vh @ sqrtm_sym(Vh @ T @ Vh, -0.5) @ Vh
    far = np.ravel_multi_index(tuple(np.full(D, L // 2)), (L,) * D)
    dS = 0.5 * (np.diag(covQ) + np.diag(covP) - 1)
    return dS[far], dS[0], np.max(np.abs(np.diag(covQ) - np.diag(covP)))


def dS3_bulk(L):
    k = 2 * np.pi * (np.arange(L) + 0.5) / L
    c = np.cos(k)
    tot = 0.0
    for c1 in c:
        g = (c1 + c[:, None] + c[None, :]) / 3.0
        tot += np.sum(1.0 / np.sqrt(1.0 - g ** 2))
    W = tot / L ** 3
    return 0.5 * (W - 1.0)


def main():
    out = ["# Leading order in 1/S: first correction dS, m = eps_h (S - dS) + O(1/S)"]
    out.append("\n## Cubic torus, L -> infinity, no push (midpoint sums): dS_3 = (W - 1)/2")
    vals = {}
    for L in (64, 128, 256):
        vals[L] = dS3_bulk(L)
        out.append(f"L={L:4d}: dS_3 = {vals[L]:.6f}")
    rich = (4 * vals[256] - vals[128]) / 3
    out.append(f"Richardson (error ~ L^-2): dS_3 = {rich:.5f}")
    out.append("\n## Cubic torus with push (exact Gaussian), far site (L/2,L/2,L/2)")
    out.append("L    eta=h_p/(JS)   dS(far)    dS(h)     zero-mode estimate sqrt(2z/(N eta))/2   max|<Q^2>-<P^2>|")
    for L in (8, 12, 16):
        for eta in (0.1, 1.0, 10.0):
            f, h, sym = dS_push(L, 3, eta)
            est = 0.5 * np.sqrt(12.0 / (L ** 3 * eta))
            out.append(f"{L:3d}  {eta:6.2f}        {f:.5f}   {h:.5f}   {est:.5f}                                {sym:.1e}")
    out.append("\n## Ring with push (exact Gaussian), eta = 1, far site L/2")
    out.append("L      dS(L/2)    dS(L/2) - (1/pi) ln(L/2)")
    ring = []
    for L in (64, 128, 256, 512, 1024):
        f, h, _ = dS_push(L, 1, 1.0)
        ring.append((L, f))
        out.append(f"{L:5d}  {f:.5f}    {f - np.log(L / 2) / np.pi:.5f}")
    sl = np.polyfit(np.log([r[0] for r in ring[-3:]]), [r[1] for r in ring[-3:]], 1)[0]
    out.append(f"slope d dS / d ln L (last three sizes) = {sl:.5f};  1/pi = {1 / np.pi:.5f} (Dirichlet image at the push)")
    (OUT / "spinwave_tilt.txt").write_text("\n".join(out) + "\n")
    print("\n".join(out))


if __name__ == "__main__":
    main()
output/ed_push.txt9 KB · raw
# ED check, item 1: exchange cells, J=1, push -h_p S^3_h at h=0 (class +); all sectors of M searched

## ring L=8: N=8, S=1/2, links=8, far sites [4] at distance 4; sectors searched: all M = -4, ..., 4
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -3.6510934089   -3.1284190638        5.227e-01  True      0.000000            -0.000000
  0.01    0.0  -3.6511215930   -3.1296915912        5.214e-01  True      0.002915             0.005637
  0.10    0.0  -3.6539014094   -3.1431227850        5.108e-01  True      0.028913             0.055951
  0.30    0.0  -3.6756584654   -3.1846251065        4.910e-01  True      0.081547             0.158772
  1.00    0.0  -3.8706747638   -3.4156351786        4.550e-01  True      0.178327             0.361393
  3.00    0.0  -4.7406497893   -4.3144845120        4.262e-01  True      0.217820             0.469512
 10.00    0.0  -8.1656749710   -7.7600032466        4.057e-01  True      0.223623             0.496231
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True

## ring L=12: N=12, S=1/2, links=12, far sites [6] at distance 6; sectors searched: all M = -6, ..., 6
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -5.3873909174   -5.0315434037        3.558e-01  True      0.000000            -0.000000
  0.01    0.0  -5.3874232606   -5.0324032116        3.550e-01  True      0.003078             0.006468
  0.10    0.0  -5.3906079037   -5.0424751866        3.481e-01  True      0.030399             0.063994
  0.30    0.0  -5.4152047132   -5.0786464182        3.366e-01  True      0.083233             0.177593
  1.00    0.0  -5.6229268437   -5.3035888107        3.193e-01  True      0.162829             0.374293
  3.00    0.0  -6.5029771989   -6.1995713695        3.034e-01  True      0.187370             0.471246
 10.00    0.0  -9.9314563940   -9.6416540673        2.898e-01  True      0.190367             0.496371
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True

## ring L=16: N=16, S=1/2, links=16, far sites [8] at distance 8; sectors searched: all M = -8, ..., 8
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -7.1422963606   -6.8721066784        2.702e-01  True     -0.000000            -0.000000
  0.01    0.0  -7.1423316575   -6.8727610785        2.696e-01  True      0.003176             0.007059
  0.10    0.0  -7.1458016524   -6.8812455850        2.646e-01  True      0.031226             0.069621
  0.30    0.0  -7.1722882312   -6.9153754572        2.569e-01  True      0.083171             0.189514
  1.00    0.0  -7.3866985161   -7.1395893046        2.471e-01  True      0.150071             0.379989
  3.00    0.0  -8.2707749474   -8.0347711943        2.360e-01  True      0.167171             0.471891
 10.00    0.0  -11.7005556368   -11.4746815979        2.259e-01  True      0.169000             0.496425
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True

## ring L=20: N=20, S=1/2, links=20, far sites [10] at distance 10; sectors searched: all M = -10, ..., 10
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -8.9043865299   -8.6864409862        2.179e-01  True     -0.000000            -0.000000
  0.01    0.0  -8.9044241355   -8.6869727301        2.175e-01  True      0.003245             0.007520
  0.10    0.0  -8.9081154951   -8.6945612781        2.136e-01  True      0.031764             0.073953
  0.30    0.0  -8.9359905145   -8.7278252110        2.082e-01  True      0.082444             0.197877
  1.00    0.0  -9.1544799698   -8.9525608798        2.019e-01  True      0.139769             0.383032
  3.00    0.0  -10.0405891867   -9.8472945657        1.933e-01  True      0.152531             0.472206
 10.00    0.0  -13.4710121778   -13.2857257643        1.853e-01  True      0.153753             0.496452
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True

16-object cubic cluster sites (representatives mod Lambda): [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 1, 3), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 0, 3), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3)]
links: each site x to x+e_i, i=1,2,3 (mod Lambda); 48 links, 6 distinct neighbours each

## cubic cluster 16: N=16, S=1/2, links=48, far sites [13, 15] at distance 3; sectors searched: all M = -8, ..., 8
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -15.5783288133   -14.7965997285        7.817e-01  True     -0.000000            -0.000000
  0.01    0.0  -15.5783455887   -14.7972341444        7.811e-01  True      0.002435             0.003355
  0.10    0.0  -15.5800039442   -14.8037863318        7.762e-01  True      0.024280             0.033454
  0.30    0.0  -15.5932340835   -14.8236634632        7.696e-01  True      0.071115             0.098118
  1.00    0.0  -15.7272156212   -14.9455491085        7.817e-01  True      0.192088             0.268207
  3.00    0.0  -16.4641224768   -15.5885629797        8.756e-01  True      0.294607             0.424892
 10.00    0.0  -19.7476521880   -18.7648142770        9.828e-01  True      0.330312             0.487059
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True

## ring L=6: N=6, S=2/2, links=6, far sites [3] at distance 3; sectors searched: all M = -6, ..., 6
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -8.6174231818   -7.8967958192        7.206e-01  True     -0.000000            -0.000000
  0.01    0.0  -8.6174901294   -7.8984940829        7.190e-01  True      0.010352             0.013389
  0.10    0.0  -8.6240752905   -7.9165725682        7.075e-01  True      0.102132             0.132193
  0.30    0.0  -8.6745349327   -7.9736946079        7.008e-01  True      0.278218             0.362050
  1.00    0.0  -9.0869706859   -8.3170486312        7.699e-01  True      0.546592             0.732523
  3.00    0.0  -10.7994879963   -9.8711217775        9.284e-01  True      0.660086             0.919464
 10.00    0.0  -17.5670872881   -16.5260310626        1.041e+00  True      0.694926             0.986112
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True

## ring L=8: N=8, S=2/2, links=8, far sites [4] at distance 4; sectors searched: all M = -8, ..., 8
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -11.3369560779   -10.7434008235        5.936e-01  True      0.000000             0.000000
  0.01    0.0  -11.3370291952   -10.7446882357        5.923e-01  True      0.010221             0.014622
  0.10    0.0  -11.3442097178   -10.7595852021        5.846e-01  True      0.100476             0.143920
  0.30    0.0  -11.3985873076   -10.8127173263        5.859e-01  True      0.267565             0.386678
  1.00    0.0  -11.8253272598   -11.1625840354        6.627e-01  True      0.494463             0.745935
  3.00    0.0  -13.5497976377   -12.7541078915        7.957e-01  True      0.582260             0.922190
 10.00    0.0  -20.3241940732   -19.4463816695        8.778e-01  True      0.609254             0.986461
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True

## ring L=10: N=10, S=2/2, links=10, far sites [5] at distance 5; sectors searched: all M = -10, ..., 10
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -14.0941299549   -13.5693220045        5.248e-01  True      0.000000             0.000000
  0.01    0.0  -14.0942062020   -13.5703639701        5.238e-01  True      0.009913             0.015248
  0.10    0.0  -14.1016869890   -13.5834553445        5.182e-01  True      0.097223             0.149801
  0.30    0.0  -14.1579598525   -13.6349424056        5.230e-01  True      0.255412             0.398181
  1.00    0.0  -14.5907289613   -13.9930452621        5.977e-01  True      0.456752             0.751132
  3.00    0.0  -16.3197109015   -15.6120227946        7.077e-01  True      0.529673             0.923214
 10.00    0.0  -23.0967344366   -22.3278084780        7.689e-01  True      0.550821             0.986603
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True

## ring L=12: N=12, S=2/2, links=12, far sites [6] at distance 6; sectors searched: all M = -12, ..., 12
h_p/J   M_low   E_low            E_next (all sectors)   gap        unique   m(far)=eps*<S3_far>   m(h)
  0.00    0.0  -16.8695561395   -16.3853596696        4.842e-01  True     -0.000000            -0.000000
  0.01    0.0  -16.8696337457   -16.3862386819        4.834e-01  True      0.009055             0.015520
  0.10    0.0  -16.8772443685   -16.3981919225        4.791e-01  True      0.088705             0.152333
  0.30    0.0  -16.9343124777   -16.4490478042        4.853e-01  True      0.231425             0.402886
  1.00    0.0  -17.3693927041   -16.8150715758        5.543e-01  True      0.407686             0.753039
  3.00    0.0  -19.1000782201   -18.4546315463        6.454e-01  True      0.470341             0.923626
 10.00    0.0  -25.8782395163   -25.1861031627        6.921e-01  True      0.488416             0.986670
no push: lowest eigenvector in M=0 and unique (a total-spin singlet): True
output/spinwave_mutual.txt17 KB · raw
# Mutual cost of two held sources, leading order in 1/S, cubic torus (units as stated per block)

(5.8) with kappa_h = J S, kappa_a = h_p against direct inverse (L=6): max error 4.88e-14

## (1) Transverse sources: separation part J E_r/(g1 g2 (m1perp.m2perp))
single objects: -eps1 eps2 ghat(r); cells (x, x+e2), + on the first object: -eps1 eps2 sum ghat
ghat_inf(0) = 0.2527310 (gamma_3 = 0.2527310)
r   eps1eps2   single: J E_r/(g1g2)  4 pi r ghat_inf(r)   cells: J E_r/(g1g2)  pi r sum ghat_inf   torus check: ghat_L(r)-ghat_L(8) for L=16, 32, 64 vs ghat_inf(r)-ghat_inf(8)
 2   +1        -0.042889            1.0779             -0.157642         0.9905            0.029359  0.032566  0.032862   0.032901
 3   -1         0.027545            1.0384              0.106137         1.0003            0.014233  0.017247  0.017521   0.017557
 4   +1        -0.020289            1.0198             -0.079621         1.0005            0.007303  0.010028  0.010269   0.010301
 5   -1         0.016101            1.0117              0.063679         1.0003            0.003573  0.005889  0.006087   0.006113
 6   +1        -0.013365            1.0077             -0.053058         1.0001            0.001456  0.003213  0.003358   0.003377
 7   -1         0.011430            1.0055              0.045475         1.0001            0.000347  0.001353  0.001432   0.001442
 8   +1        -0.009988            1.0041             -0.039790         1.0000            0.000000  0.000000  0.000000   0.000000
single object at 0, cell (r e1, (r+1) e1) along the separation: 4 pi R [ghat(r)+ghat(r+1)]/2 with R = midpoint separation r+1/2, and with R = end-point separation r
 2   midpoint: 1.10638   end point: 0.88511
 3   midpoint: 1.05192   end point: 0.90165
 4   midpoint: 1.02890   end point: 0.91458
 5   midpoint: 1.01826   end point: 0.92569
 6   midpoint: 1.01265   end point: 0.93475
 7   midpoint: 1.00932   end point: 0.94203
 8   midpoint: 1.00717   end point: 0.94792

## Continuum coefficients
along n, single:  J S E/(g1 g2) = -eps1 eps2 kappa_par / r^3, kappa_par = sqrt(2z)/(32 pi^3) = 0.0034913
held spin, r >> l_b: S E/(J sig1 sig2) = +eps1 eps2 lambda / r^5, lambda = 3 sqrt3/(8 pi^3) = 0.0209480
changed links, separation r e1: J E/(d1 d2 S) * r^7 = -sqrt3/(8 pi^3) a; numerical integral against a:
  par (e1,e1)          eps1eps2=+1: integral -0.06749907   closed form a=9.666667: -0.06749907
  par (e1,e1)          eps1eps2=-1: integral -0.03258576   closed form a=4.666667: -0.03258576
  perp same (e2,e2)    eps1eps2=+1: integral -0.00640077   closed form a=0.916667: -0.00640077
  perp same (e2,e2)    eps1eps2=-1: integral -0.01221966   closed form a=1.750000: -0.01221966
  perp cross (e2,e3)   eps1eps2=+1: integral -0.00058189   closed form a=0.083333: -0.00058189
  perp cross (e2,e3)   eps1eps2=-1: integral -0.00058189   closed form a=0.083333: -0.00058189
  mixed (e1,e2)        eps1eps2=+1: integral 0.00349133   closed form a=-0.500000: 0.00349133
  mixed (e1,e2)        eps1eps2=-1: integral 0.00349133   closed form a=-0.500000: 0.00349133

## (2) Static quadratic sources, lattice (zero modes left out); ratio = lattice / continuum
columns: r, eps1eps2, along single [J S E/(g1g2), ratio], along cell [.., ratio vs 4x], then J E/(d1d2S) and ratio for links: par (e1 at 0, e1 at r e1), perp same (e2, e2), perp cross (e2, e3), mixed (e1, e2); link continuum at the midpoint separation R
L = 32
 2 +1  -4.624e-04  1.060  -1.491e-03  0.854  -1.274e-03  2.417  -1.174e-04  2.347   5.574e-06  1.626   1.632e-06  0.342
 3 -1   1.198e-04  0.927   4.142e-04  0.801  -2.430e-05  1.631  -1.119e-05  2.002  -7.837e-07  2.114  -1.343e-06  6.120
 4 +1  -3.922e-05  0.719  -1.480e-04  0.678  -6.880e-06  1.670  -6.874e-07  1.759   1.380e-08 -1.438   1.286e-07  1.139
 5 -1   1.640e-05  0.587   6.200e-05  0.555  -5.446e-07  1.306  -2.119e-07  1.355  -1.049e-08  1.233  -3.651e-09 -0.752
 6 +1  -7.170e-06  0.444  -2.790e-05  0.432  -3.006e-07  1.247  -2.761e-08  1.207  -1.060e-09  0.795   9.699e-09  1.102
 7 -1   3.351e-06  0.329   1.293e-05  0.318  -4.524e-08  1.143  -1.714e-08  1.155  -8.316e-10  1.098   8.711e-10  0.714
 8 +1  -1.510e-06  0.221  -5.918e-06  0.217  -3.768e-08  1.171  -3.017e-09  0.988  -2.295e-10  1.045   1.383e-09  1.042
 9 -1   6.659e-07  0.139   2.578e-06  0.135  -7.892e-09  1.158  -2.875e-09  1.125  -1.522e-10  1.199   2.089e-10  0.695
10 +1  -2.585e-07  0.074  -1.014e-06  0.073  -8.418e-09  1.247  -5.211e-10  0.814  -6.725e-11  1.338   2.734e-10  0.921
11 -1   8.809e-08  0.034   3.369e-07  0.032  -2.283e-09  1.366  -7.612e-10  1.214  -4.936e-11  1.606   3.147e-11  0.351
12 +1  -2.467e-08  0.012  -9.778e-08  0.012  -2.906e-09  1.543  -1.184e-10  0.663  -3.074e-11  2.092   5.073e-11  0.589
L = 64
 2 +1  -4.970e-04  1.139  -1.616e-03  0.926  -1.274e-03  2.416  -1.174e-04  2.348   5.569e-06  1.624   1.623e-06  0.340
 3 -1   1.393e-04  1.077   4.876e-04  0.943  -2.430e-05  1.631  -1.119e-05  2.002  -7.827e-07  2.111  -1.341e-06  6.110
 4 +1  -5.146e-05  0.943  -1.957e-04  0.897  -6.868e-06  1.667  -6.922e-07  1.772   1.365e-08 -1.422   1.280e-07  1.134
 5 -1   2.483e-05  0.889   9.493e-05  0.850  -5.434e-07  1.303  -2.117e-07  1.353  -1.040e-08  1.222  -3.297e-09 -0.679
 6 +1  -1.312e-05  0.812  -5.144e-05  0.796  -2.969e-07  1.231  -2.873e-08  1.256  -1.047e-09  0.785   9.641e-09  1.095
 7 -1   7.695e-06  0.756   3.007e-05  0.738  -4.446e-08  1.124  -1.699e-08  1.145  -7.977e-10  1.053   1.003e-09  0.821
 8 +1  -4.679e-06  0.686  -1.850e-05  0.678  -3.586e-08  1.114  -3.397e-09  1.113  -2.103e-10  0.958   1.401e-09  1.055
 9 -1   2.998e-06  0.626   1.181e-05  0.616  -7.274e-09  1.068  -2.759e-09  1.080  -1.299e-10  1.023   2.856e-10  0.950
10 +1  -1.950e-06  0.559  -7.737e-06  0.554  -7.248e-09  1.074  -6.713e-10  1.049  -4.991e-11  0.993   3.073e-10  1.035
11 -1   1.306e-06  0.498   5.163e-06  0.492  -1.750e-09  1.047  -6.603e-10  1.053  -3.136e-11  1.020   8.712e-11  0.972
12 +1  -8.771e-07  0.434  -3.487e-06  0.431  -1.997e-09  1.060  -1.788e-10  1.001  -1.486e-11  1.011   8.804e-11  1.022
L = 128
 2 +1  -5.071e-04  1.162  -1.653e-03  0.947  -1.274e-03  2.416  -1.174e-04  2.348   5.569e-06  1.624   1.623e-06  0.340
 3 -1   1.453e-04  1.124   5.105e-04  0.987  -2.430e-05  1.631  -1.119e-05  2.002  -7.827e-07  2.111  -1.341e-06  6.109
 4 +1  -5.554e-05  1.018  -2.116e-04  0.970  -6.867e-06  1.667  -6.925e-07  1.773   1.364e-08 -1.421   1.279e-07  1.134
 5 -1   2.784e-05  0.997   1.068e-04  0.956  -5.434e-07  1.303  -2.117e-07  1.353  -1.039e-08  1.222  -3.278e-09 -0.675
 6 +1  -1.545e-05  0.956  -6.063e-05  0.938  -2.967e-07  1.230  -2.881e-08  1.260  -1.047e-09  0.785   9.634e-09  1.094
 7 -1   9.546e-06  0.938   3.740e-05  0.919  -4.445e-08  1.123  -1.699e-08  1.145  -7.968e-10  1.052   1.008e-09  0.826
 8 +1  -6.180e-06  0.906  -2.447e-05  0.897  -3.578e-08  1.112  -3.429e-09  1.123  -2.102e-10  0.958   1.399e-09  1.054
 9 -1   4.239e-06  0.885   1.674e-05  0.874  -7.265e-09  1.066  -2.757e-09  1.079  -1.294e-10  1.020   2.881e-10  0.958
10 +1  -2.985e-06  0.855  -1.186e-05  0.849  -7.205e-09  1.067  -6.865e-10  1.072  -4.968e-11  0.988   3.070e-10  1.034
11 -1   2.178e-06  0.830   8.638e-06  0.823  -1.743e-09  1.042  -6.589e-10  1.051  -3.104e-11  1.010   8.851e-11  0.987
12 +1  -1.616e-06  0.800  -6.433e-06  0.796  -1.970e-09  1.046  -1.869e-10  1.046  -1.464e-11  0.996   8.812e-11  1.023
ratio extrapolated to L -> infinity: Aitken from L = 32, 64, 128 (geometric finite-size error); the L = 128 value where the change from 64 to 128 is below 1e-3 or not geometric
 2   1.172   0.956   2.416   2.348   1.624   0.340
 3   1.144   1.007   1.631   2.002   2.111   6.109
 4   1.055   1.007   1.667   1.773  -1.421   1.134
 5   1.057   1.016   1.303   1.353   1.222  -0.675
 6   1.047   1.029   1.230   1.260   0.785   1.094
 7   1.073   1.053   1.123   1.145   1.052   0.826
 8   1.104   1.095   1.112   1.124   0.958   1.054
 9   1.180   1.170   1.066   1.079   1.020   0.959
10   1.322   1.318   1.067   1.075   0.988   1.034
11   1.672   1.675   1.042   1.051   1.010   0.988
12   3.173   3.225   1.046   1.053   0.996   1.023

## (3) Held spin R1, retarded vertex (Step 12); J S E/(|g'1 g'2| s1 s2), sgn sigma1 = sgn sigma2, so vs = eps1 eps2 = (-1)^r
continuum crossover function F(beta) (equal held spins), with its small-beta form 1 - pi (3+vs) beta/4 and large-beta form -2 vs/beta^2 + 24 (1+2 vs)/beta^4
  vs=+1 beta=   0.01: F =  9.699956e-01   small-beta form  9.685841e-01   large-beta form  7.199980e+09
  vs=+1 beta=   0.03: F =  9.155432e-01   small-beta form  9.057522e-01   large-beta form  8.888667e+07
  vs=+1 beta=   0.10: F =  7.604598e-01   small-beta form  6.858407e-01   large-beta form  7.198000e+05
  vs=+1 beta=   0.30: F =  4.754809e-01   small-beta form  5.752220e-02   large-beta form  8.866667e+03
  vs=+1 beta=   1.00: F =  1.004787e-01   small-beta form -2.141593e+00   large-beta form  7.000000e+01
  vs=+1 beta=   3.00: F = -3.875257e-02   small-beta form -8.424778e+00   large-beta form  6.666667e-01
  vs=+1 beta=  10.00: F = -1.496680e-02   small-beta form -3.041593e+01   large-beta form -1.280000e-02
  vs=+1 beta=  30.00: F = -2.137889e-03   small-beta form -9.324778e+01   large-beta form -2.133333e-03
  vs=+1 beta= 100.00: F = -1.992836e-04   small-beta form -3.131593e+02   large-beta form -1.992800e-04
  vs=-1 beta=   0.01: F =  9.847956e-01   small-beta form  9.842920e-01   large-beta form -2.399980e+09
  vs=-1 beta=   0.03: F =  9.564331e-01   small-beta form  9.528761e-01   large-beta form -2.962741e+07
  vs=-1 beta=   0.10: F =  8.708995e-01   small-beta form  8.429204e-01   large-beta form -2.398000e+05
  vs=-1 beta=   0.30: F =  6.929129e-01   small-beta form  5.287611e-01   large-beta form -2.940741e+03
  vs=-1 beta=   1.00: F =  3.785504e-01   small-beta form -5.707963e-01   large-beta form -2.200000e+01
  vs=-1 beta=   3.00: F =  1.241269e-01   small-beta form -3.712389e+00   large-beta form -7.407407e-02
  vs=-1 beta=  10.00: F =  1.808965e-02   small-beta form -1.470796e+01   large-beta form  1.760000e-02
  vs=-1 beta=  30.00: F =  2.193524e-03   small-beta form -4.612389e+01   large-beta form  2.192593e-03
  vs=-1 beta= 100.00: F =  1.997607e-04   small-beta form -1.560796e+02   large-beta form  1.997600e-04
  vs=+1: F changes sign at beta_0 = 1.69838 (r_0 = beta_0 l_b / 2); vs=-1: F > 0 at every beta
lattice against continuum: D = |g'|/J = 0, 0.2, 0.5, 2; l_b = sqrt(2z)/D = inf, 17.32, 6.93, 1.73
continuum A = (8.18): -kappa_par F(beta)/r^3; continuum B = (8.18) with the off-diagonal part of the covariance (nonzero for eps1 = eps2 only)
columns per D: lattice value, ratio lattice/A, ratio lattice/B
L = 32
 2 +1  -4.6238e-04  1.059  1.106  -3.1747e-04  1.309  1.206  -1.9941e-04  1.753  1.269  -3.9503e-05 -3.139  1.516
 3 -1  -1.1983e-04  0.927  0.927  -8.6954e-05  1.018  1.018  -5.8491e-05  1.080  1.080  -1.5967e-05  1.208  1.208
 4 +1  -3.9216e-05  0.719  0.726  -1.9221e-05  1.055  0.911  -7.4366e-06  2.036  1.054   5.3250e-07  0.271  0.662
 5 -1  -1.6403e-05  0.587  0.587  -1.0329e-05  0.696  0.696  -5.9281e-06  0.758  0.758  -1.0994e-06  0.837  0.837
 6 +1  -7.1698e-06  0.444  0.446  -2.6543e-06  0.809  0.669  -5.9044e-07 -14.772  1.047   1.6996e-07  0.427  0.596
 7 -1  -3.3509e-06  0.329  0.329  -1.8867e-06  0.423  0.423  -9.6157e-07  0.473  0.473  -1.4012e-07  0.519  0.519
 8 +1  -1.5096e-06  0.221  0.222  -4.2363e-07  0.515  0.404  -3.3492e-08 -0.170 -0.903   3.2348e-08  0.282  0.340
 9 -1  -6.6588e-07  0.139  0.139  -3.3407e-07  0.190  0.190  -1.5174e-07  0.213  0.213  -1.8610e-08  0.231  0.231
10 +1  -2.5853e-07  0.074  0.074  -4.9564e-08  0.212  0.152   4.0323e-09  0.030  0.051   3.1615e-09  0.076  0.085
11 -1  -8.8087e-08  0.034  0.034  -3.8477e-08  0.047  0.047  -1.6624e-08  0.055  0.055  -3.0898e-09  0.101  0.101
12 +1  -2.4670e-08  0.012  0.012  -8.1078e-09  0.130  0.077  -5.5636e-09 -0.069 -0.093  -1.1010e-09 -0.062 -0.067
cross-check D = 0 (frequency domain) against the along-n single column (time domain), L = 32: max relative difference 1.31e-04
L = 64
 2 +1  -4.9703e-04  1.139  1.188  -3.2820e-04  1.353  1.247  -2.0223e-04  1.778  1.287  -3.9294e-05 -3.123  1.508
 3 -1  -1.3928e-04  1.077  1.077  -9.7057e-05  1.136  1.136  -6.3638e-05  1.175  1.175  -1.6878e-05  1.277  1.277
 4 +1  -5.1458e-05  0.943  0.953  -2.2335e-05  1.226  1.058  -7.9038e-06  2.164  1.120   7.1046e-07  0.362  0.883
 5 -1  -2.4828e-05  0.889  0.889  -1.4413e-05  0.971  0.971  -7.8602e-06  1.005  1.005  -1.3845e-06  1.053  1.053
 6 +1  -1.3124e-05  0.812  0.816  -3.9294e-06  1.197  0.991  -6.6556e-07 -16.652  1.181   2.6497e-07  0.665  0.930
 7 -1  -7.6949e-06  0.756  0.756  -3.8731e-06  0.868  0.868  -1.8478e-06  0.909  0.909  -2.5545e-07  0.946  0.946
 8 +1  -4.6787e-06  0.686  0.688  -9.9690e-07  1.211  0.950  -1.7632e-08 -0.090 -0.475   8.1739e-08  0.712  0.859
 9 -1  -2.9979e-06  0.626  0.626  -1.3398e-06  0.760  0.760  -5.7561e-07  0.806  0.806  -6.7748e-08  0.839  0.839
10 +1  -1.9500e-06  0.559  0.559  -2.9846e-07  1.277  0.918   3.8749e-08  0.292  0.489   2.7983e-08  0.670  0.757
11 -1  -1.3056e-06  0.498  0.498  -5.2592e-07  0.640  0.640  -2.0720e-07  0.686  0.686  -2.1722e-08  0.714  0.714
12 +1  -8.7709e-07  0.434  0.435  -9.5241e-08  1.522  0.908   2.8430e-08  0.353  0.478   1.0335e-08  0.579  0.630
L = 128
 2 +1  -5.0712e-04  1.162  1.213  -3.2958e-04  1.359  1.252  -2.0238e-04  1.779  1.288  -3.9235e-05 -3.118  1.506
 3 -1  -1.4529e-04  1.124  1.124  -9.9216e-05  1.161  1.161  -6.4553e-05  1.192  1.192  -1.7015e-05  1.287  1.287
 4 +1  -5.5538e-05  1.018  1.029  -2.2735e-05  1.248  1.077  -7.8727e-06  2.156  1.116   7.4691e-07  0.381  0.928
 5 -1  -2.7844e-05  0.997  0.997  -1.5411e-05  1.038  1.038  -8.2500e-06  1.055  1.055  -1.4330e-06  1.090  1.090
 6 +1  -1.5445e-05  0.956  0.960  -4.0969e-06  1.248  1.033  -6.2131e-07 -15.545  1.102   2.8560e-07  0.717  1.002
 7 -1  -9.5458e-06  0.938  0.938  -4.4457e-06  0.997  0.997  -2.0583e-06  1.013  1.013  -2.7876e-07  1.033  1.033
 8 +1  -6.1799e-06  0.906  0.909  -1.0765e-06  1.307  1.026   2.0663e-08  0.105  0.557   9.4103e-08  0.820  0.989
 9 -1  -4.2391e-06  0.885  0.885  -1.7021e-06  0.966  0.966  -7.0242e-07  0.984  0.984  -8.0674e-08  0.999  0.999
10 +1  -2.9846e-06  0.855  0.856  -3.3780e-07  1.445  1.039   6.9143e-08  0.521  0.873   3.5771e-08  0.857  0.967
11 -1  -2.1783e-06  0.830  0.830  -7.6770e-07  0.934  0.934  -2.8830e-07  0.955  0.955  -2.9477e-08  0.968  0.968
12 +1  -1.6157e-06  0.800  0.801  -1.1424e-07  1.825  1.089   5.1893e-08  0.645  0.872   1.5410e-08  0.863  0.940
L = 256
 2 +1  -5.0987e-04  1.168  1.219  -3.2969e-04  1.359  1.252  -2.0237e-04  1.779  1.288  -3.9225e-05 -3.117  1.505
 3 -1  -1.4698e-04  1.137  1.137  -9.9587e-05  1.166  1.166  -6.4690e-05  1.195  1.195  -1.7033e-05  1.289  1.289
 4 +1  -5.6727e-05  1.040  1.051  -2.2756e-05  1.249  1.078  -7.8563e-06  2.151  1.113   7.5255e-07  0.384  0.935
 5 -1  -2.8751e-05  1.029  1.029  -1.5592e-05  1.051  1.051  -8.3112e-06  1.063  1.063  -1.4399e-06  1.096  1.096
 6 +1  -1.6168e-05  1.000  1.005  -4.0997e-06  1.249  1.034  -6.0795e-07 -15.210  1.079   2.8886e-07  0.725  1.013
 7 -1  -1.0142e-05  0.996  0.996  -4.5556e-06  1.021  1.021  -2.0932e-06  1.030  1.030  -2.8229e-07  1.046  1.046
 8 +1  -6.6809e-06  0.980  0.982  -1.0734e-06  1.304  1.023   3.1052e-08  0.158  0.837   9.6145e-08  0.838  1.010
 9 -1  -4.6684e-06  0.975  0.975  -1.7762e-06  1.008  1.008  -7.2475e-07  1.015  1.015  -8.2754e-08  1.025  1.025
10 +1  -3.3566e-06  0.961  0.963  -3.3280e-07  1.424  1.023   7.7243e-08  0.582  0.975   3.7132e-08  0.889  1.004
11 -1  -2.5045e-06  0.955  0.955  -8.2075e-07  0.999  0.999  -3.0360e-07  1.006  1.006  -3.0821e-08  1.012  1.012
12 +1  -1.9039e-06  0.942  0.943  -1.0874e-07  1.737  1.036   5.8278e-08  0.724  0.979   1.6361e-08  0.916  0.998
ratio lattice/B extrapolated to L -> infinity: Aitken from L = 64, 128, 256 (as in block (2))
 2 +1    1.222    1.252    1.288    1.505   (continuum B: -4.182e-04  -2.632e-04  -1.572e-04  -2.605e-05)
 3 -1    1.142    1.167    1.195    1.289   (continuum B: -1.293e-04  -8.542e-05  -5.415e-05  -1.322e-05)
 4 +1    1.060    1.079    1.111    0.937   (continuum B: -5.398e-05  -2.110e-05  -7.056e-06   8.046e-07)
 5 -1    1.043    1.053    1.065    1.096   (continuum B: -2.793e-05  -1.484e-05  -7.818e-06  -1.314e-06)
 6 +1    1.025    1.034    1.068    1.016   (continuum B: -1.609e-05  -3.966e-06  -5.637e-07   2.850e-07)
 7 -1    1.024    1.027    1.033    1.048   (continuum B: -1.018e-05  -4.460e-06  -2.033e-06  -2.699e-07)
 8 +1    1.019    1.023    0.941    1.014   (continuum B: -6.801e-06  -1.050e-06   3.710e-08   9.519e-08)
 9 -1    1.022    1.019    1.022    1.030   (continuum B: -4.789e-06  -1.762e-06  -7.139e-07  -8.074e-08)
10 +1    1.023    1.023    1.012    1.012   (continuum B: -3.486e-06  -3.253e-07   7.924e-08   3.698e-08)
11 -1    1.029    1.017    1.017    1.022   (continuum B: -2.623e-06  -8.218e-07  -3.019e-07  -3.044e-08)
12 +1    1.035    1.036    1.019    1.011   (continuum B: -2.018e-06  -1.049e-07   5.952e-08   1.639e-08)
output/spinwave_tilt.txt2 KB · raw
# Leading order in 1/S: first correction dS, m = eps_h (S - dS) + O(1/S)

## Cubic torus, L -> infinity, no push (midpoint sums): dS_3 = (W - 1)/2
L=  64: dS_3 = 0.078304
L= 128: dS_3 = 0.078344
L= 256: dS_3 = 0.078354
Richardson (error ~ L^-2): dS_3 = 0.07836

## Cubic torus with push (exact Gaussian), far site (L/2,L/2,L/2)
L    eta=h_p/(JS)   dS(far)    dS(h)     zero-mode estimate sqrt(2z/(N eta))/2   max|<Q^2>-<P^2>|
  8    0.10        0.31135   0.29896   0.24206                                0.0e+00
  8    1.00        0.15197   0.11065   0.07655                                0.0e+00
  8   10.00        0.11169   0.01999   0.02421                                0.0e+00
 12    0.10        0.20637   0.19853   0.13176                                0.0e+00
 12    1.00        0.11960   0.08897   0.04167                                0.0e+00
 12   10.00        0.09770   0.01863   0.01318                                0.0e+00
 16    0.10        0.16197   0.15613   0.08558                                0.0e+00
 16    1.00        0.10561   0.07974   0.02706                                0.0e+00
 16   10.00        0.09139   0.01805   0.00856                                0.0e+00

## Ring with push (exact Gaussian), eta = 1, far site L/2
L      dS(L/2)    dS(L/2) - (1/pi) ln(L/2)
   64  1.10378    0.00061
  128  1.31488    -0.00893
  256  1.53065    -0.01380
  512  1.74882    -0.01626
 1024  1.96822    -0.01750
slope d dS / d ln L (last three sizes) = 0.31564;  1/pi = 0.31831 (Dirichlet image at the push)
Analyse with ChatGPTnDot Physics Research plugin
ChatGPT plugin

Analyse this research in ChatGPT

The free plugin nDot Physics Research gives ChatGPT read-only access to everything published here.

  1. Open ChatGPT and select the plugin in the message box.
  2. Write your question after it:nDot Physics Research Explain what 08-ilang-propagation/08-tilt establishes and what it builds on.
  3. Name the subproject when you cite an equation number, e.g. (17.7) of 03-ilang-space.
Open in ChatGPT

Interested in this research?

Join the readers' list and get an e-mail when a new stage or a correction is published. No password, and you can unsubscribe at any time.