Ising.java

Below is the syntax highlighted version of Ising.java from §9.8 Data Analysis.

```/******************************************************************************
*  Compilation:  javac Ising.java
*  Execution:    java Ising N kT
*
*  Create an N-by-N grid of sites. Each site has spin "up" (+1)
*  or "down" (-1).
*
*  % java Ising N 2.26918  // critical temperature
*
******************************************************************************/

import java.awt.Color;

public class Ising {
private int N;                  // N-by-N grid of sites
private double J = 1.0;         // strength of spin-spin interaction (feromagentic when J is positive)
private double kT;              // temperature (say between 1 and 4)
private boolean[][] spin;       // up (true) or down (false)

// N-by-N grid, kT = temperature, p = prob of up spin
public Ising(int N, double kT, double p) {
this.N    = N;
this.kT   = kT;
this.spin = new boolean[N][N];

// initialize at random
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
spin[i][j] = (Math.random() < p);
}

// total average magnetization (between -1 and 1)
public double magnetization() {
int M = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (spin[i][j]) M++;
else            M--;
}
}
return 1.0 * M / (N * N);
}

// total energy of site (i, j), using periodic boundary conditions
// assumes 0 <= i, j < N
private double energy(int i, int j) {
double E = 0.0;
if (spin[i][j] == spin[(i+1)%N][j])   E++;
else                                  E--;
if (spin[i][j] == spin[i][(j+1)%N])   E++;
else                                  E--;
if (spin[i][j] == spin[(i-1+N)%N][j]) E++;
else                                  E--;
if (spin[i][j] == spin[i][(j-1+N)%N]) E++;
else                                  E--;
return -J * E;
}

// total energy, using periodic boundary conditions
public double energy() {
double E = 0.0;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
E += 0.5 * energy(i, j);  // divide by two to mitigate double-counting
return E;
}

// one Monte Carlo step
public void step(int i, int j) {
double deltaE = -2 * energy(i, j);
// flip if energy decreases or get lucky
if ((deltaE <= 0) || (Math.random() <= Math.exp(-deltaE / kT)))
spin[i][j] = !spin[i][j];
}

// one Monte Carlo phase - N^2 steps
public void phase() {
for (int steps = 0; steps < N*N; steps++) {
int i = (int) (Math.random() * N);
int j = (int) (Math.random() * N);
step(i, j);
}
}

// plot it
public void draw() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (spin[i][j]) StdDraw.setPenColor(StdDraw.WHITE);
else            StdDraw.setPenColor(StdDraw.BLUE);
StdDraw.filledSquare(i + 0.5, j + 0.5, .5);
}
}

// draw lines
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < N; i++) {
StdDraw.line(i, 0, i, N);
StdDraw.line(0, i, N, i);
}
}

// string representation
public String toString() {
String NEWLINE = System.getProperty("line.separator");
String s = "";
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (spin[i][j]) s += "< ";
else            s += "> ";
}
s += NEWLINE;
}
return s;
}

public static void main(String[] args) {
int N = Integer.parseInt(args[0]);          // N-by-N lattice
double kT = Double.parseDouble(args[1]);    // temperature
Ising ising = new Ising(N, kT, 0.5);

// set scale and turn on animation mode
StdDraw.setXscale(0, N);
StdDraw.setYscale(0, N);
StdDraw.enableDoubleBuffering();

for (int t = 0; true; t++) {
ising.phase();
ising.draw();
StdDraw.show();
StdDraw.pause(50);
}
}

}
```