helpful progress reporting
[IRC.git] / Robust / src / Benchmarks / Prefetch / MicroBenchmarks / State.java
1 /*************************************************************************
2  *  Compilation:  javac State.java
3  *  Execution:    java State N T
4  *  Dependencies: StdDraw.java
5  *  
6  *  Create an N-by-N grid of sites.
7  *
8  *  % java 50 2
9  *
10  *  % java 50 2.1
11  * 
12  *  % java 50 2.2
13  *
14  *************************************************************************/
15
16 public class State {
17   private int N;                  // N-by-N grid
18   private Cell[][] lattice;       // N-by-N lattice of cells
19
20   // N-by-N grid, p = prob of up spin
21   public State(int N, double p) {
22     this.N  = N;
23     this.lattice = new Cell[N][N];
24
25     // initialize at random
26     for (int i = 0; i < N; i++)
27       for (int j = 0; j < N; j++)
28         lattice[i][j] = new Cell(p);
29   }
30
31
32   // total magnetization
33   public double magnetization() {
34     double M = 0.0;
35     for (int i = 0; i < N; i++)
36       for (int j = 0; j < N; j++)
37         M += lattice[i][j].magnetization();
38     return M;
39   }
40
41   // total energy of site (i, j), using periodic boundary conditions
42   // assumes 0 <= i, j < N
43   private double energy(int i, int j) {
44     double E = 0.0;
45     E += lattice[(i+1)%N][j].magnetization();
46     E += lattice[i][(j+1)%N].magnetization();
47     E += lattice[(i-1+N)%N][j].magnetization();
48     E += lattice[i][(j-1+N)%N].magnetization();
49     E *= lattice[i][j].magnetization();
50     return -E;
51   }
52   // total energy, using periodic boundary conditions
53   public double energy() {
54     double E = 0.0;
55     for (int i = 0; i < N; i++)
56       for (int j = 0; j < N; j++)
57         E += energy(i, j); 
58     return 0.5 * E;   // divide by two to mitigate double-counting
59   }
60
61   // flip spin of cell i-j if energy decreases or Metropolis increase
62   public void metropolis(int i, int j, double kT) {
63     double deltaE = -2 * energy(i, j);
64     if ((deltaE <= 0) || (Math.random() <= Math.exp(-deltaE  / kT)))
65       lattice[i][j].flip();
66   }
67
68   // one Metropolis phase - N^2 random steps
69   // kT = temperature (say between 1 and 4)
70   public void phase(double kT) {
71     for (int steps = 0; steps < N*N; steps++) {
72       int i = (int) (Math.random() * N);
73       int j = (int) (Math.random() * N);
74       metropolis(i, j, kT);
75     }
76   }
77
78   // plot Ising state
79   public void draw() {
80     /*
81     for (int i = 0; i < N; i++)
82       for (int j = 0; j < N; j++)
83         lattice[i][j].draw(i + 0.5, j + 0.5);
84
85     // draw grid lines
86     StdDraw.setPenColor(StdDraw.BLACK);
87     for (int i = 0; i < N; i++) {
88       StdDraw.line(i, 0, i, N);
89       StdDraw.line(0, i, N, i);
90     }
91     */
92   }
93
94   // string representation
95   public String toString() {
96     String NEWLINE = System.getProperty("line.separator");
97     String s = "";
98     for (int i = 0; i < N; i++) {
99       for (int j = 0; j < N; j++) {
100         s += lattice[i][j] + " ";
101       }
102       s += NEWLINE;
103     }
104     return s;
105   }
106
107
108   public static void main(String[] args) {
109     int N = Integer.parseInt(args[0]);          // N-by-N lattice
110     double kT = Double.parseDouble(args[1]);    // temperature
111     State state = new State(N, 1.0);
112
113     //StdDraw.setXscale(0, N);
114     //StdDraw.setYscale(0, N);
115
116     System.out.println("warming up");
117     for (int t = 0; t < 10000; t++) state.phase(kT);
118     System.out.println("done warming up");
119
120     double sumM = 0.0;
121     for (int t = 1; true; t++) {
122       state.phase(kT);
123       sumM += state.magnetization();
124       if (t % 10000 == 0) { 
125         System.out.println("kT = " + kT +  " (" + t + "): " + sumM / t / (N*N));
126       }
127     }
128   }
129
130 }
131