Task 1 of 6
A magnet, stripped to almost nothing: a grid of arrows, each one either
up (+1) or down (−1), and a single
rule — neighbours would rather agree. Ernst Ising's 1925 model is that sentence and no more,
and it is still the standard proving ground for phase transitions, because it is simple
enough to be solved exactly and rich enough to have one.
Agreement is written as energy. Every neighbouring pair contributes −s·s':
−1 when the two agree, +1 when they do not, so the lattice's total
energy falls as more spins line up. Now ask what one spin flipping would do. Its four bonds
all reverse, so the change is
ΔE = 2 · s · (up + down + left + right)
and because every spin and every neighbour is ±1, that has exactly five possible
values: −8 when all four neighbours disagree with you (flipping is a bargain),
through 0, up to +8 when all four agree (flipping is the most expensive
move on the board). This lattice is a torus — the right edge is glued to the
left, the top to the bottom — so there are no boundary cells to special-case, and every one of
the 16,384 threads does the identical four reads. Pure gather, the shape Thinking in Parallel
calls the one that always parallelises.
[y][x] holds
2 · s[y][x] · (sum of its four neighbours), with the neighbour indices wrapping
round the lattice.(x + n - 1) % n, never (x - 1) % n2 * s[y][x] * sumThis spin's share of the energy is −s · (neighbour sum). Flip it and the
share becomes +s · (neighbour sum). The difference between those two is
2 · s · (neighbour sum) — the bonds do not just vanish, they reverse, so the
change is twice the share, not once.
(x - 1) % n is -1 at x = 0, in JavaScript and in
gpu.js's GLSL alike — both keep the sign of the left operand. Reading
s[y][-1] gives you undefined on the CPU backend and a zero out of
nowhere on WebGL. Add the size before you subtract:
const left = s[y][(x + n - 1) % n];
const right = s[y][(x + 1) % n];
const up = s[(y + n - 1) % n][x];
const down = s[(y + 1) % n][x];const sum = s[y][(x + 1) % n] + s[y][(x + n - 1) % n]
+ s[(y + 1) % n][x] + s[(y + n - 1) % n][x];
return 2 * s[y][x] * sum;repeat instead of doing modular arithmetic
at all. The five-value structure matters too: a stencil whose result comes from a tiny
discrete set is exactly the case where production Ising codes drop the exponential and look
the answer up in a five-entry table.
This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.