Tuesday 2 September 2014

Conway's Game of Life written in Processing

When I feel a bit "down in the dumps" and I don't fancy getting up to do anything, I program. I think it is because it allows me to cut off from the world and focus on one tiny thing. So I have been meaning to look into Conway's Game-of-Life, but never got around to it. The past few days I have been struggling to focus on writing my thesis and ended up writing one in Processing. It's nothing spectacular, but quite fascinating to watch the different patterns grow (or not). Here is my code:

001 int size = 100;
002 int cellsize=4;
003 int displaysize = size * cellsize ;
004 int[][] world = new int[size][size];
005 int[][] newworld = new int[size][size];
006 int r1 = (int)random(size);
007 int c1 = (int)random(size);
008 boolean pause = true;
009 color alive = color(000);
010 color dead = color(255255255);
011 
012 
013 void setup() {
014   size(displaysize, displaysize);
015   // initialise world with zeros
016   for (int x = 0; x < size; x++) {
017     for (int y = 0; y < size; y++) {
018       world[x][y0;
019     }
020   }
021 
022   // start life
023   // gun
024   world[39][39]=1;
025   world[40][39]=1;
026   world[39][40]=1;
027   world[40][40]=1;
028 
029   world[49][39]=1;
030   world[49][40]=1;
031   world[49][41]=1;
032   world[50][38]=1;
033   world[50][42]=1;
034   world[51][37]=1;
035   world[51][43]=1;
036   world[52][37]=1;
037   world[52][43]=1;
038   world[53][40]=1;
039   world[54][38]=1;
040   world[54][42]=1;
041   world[55][39]=1;
042   world[55][40]=1;
043   world[55][41]=1;
044   world[56][40]=1;
045 
046   world[59][39]=1;
047   world[59][38]=1;
048   world[59][37]=1;
049   world[60][39]=1;
050   world[60][38]=1;
051   world[60][37]=1;
052 
053   world[61][36]=1;
054   world[61][40]=1;
055 
056   world[63][35]=1;
057   world[63][40]=1;
058   world[63][36]=1;
059   world[63][41]=1;
060 
061   world[73][38]=1;
062   world[73][37]=1;
063   world[74][38]=1;
064   world[74][37]=1;
065 
066 
067   // oscillator Blinker
068   world[10][10]=1;
069   world[11][10]=1;
070   world[12][10]=1;
071   world[9][11]=1;
072   world[10][11]=1;
073   world[11][11]=1;
074 
075   //DieHard  
076   world[20][10]=1;
077   world[21][10]=1;
078   world[21][11]=1;
079   world[25][9]=1;
080   world[24][11]=1;
081   world[25][11]=1;
082   world[26][11]=1;
083 
084   stroke(dead);
085 }
086 
087 void draw() {
088   for (int c = 0; c < size; c++) {
089     for (int r = 0; r < size; r++) {
090       // if there isn't life, make the point white;
091       if (world[c][r]==0fill(dead);
092       // if there is life make the point black
093       if (world[c][r]==1fill(alive);
094       //if (world[r][c]==1) System.out.println("life at " + r + "," + c);
095       rect(c*cellsize, r*cellsize, cellsize, cellsize);
096     }
097   }
098   if (!pausemakeworld();
099 }
100 
101 void makeworld() {
102 
103   // initialise newworld
104   for (int x = 0; x < size; x++) {
105     for (int y = 0; y < size; y++) {
106       newworld[x][y= world[x][y];
107     }
108   }
109 
110   // Determine life in the new world
111   for (int c = 0; c < size; c++) {
112     for (int r = 0; r < size; r++) {
113       // initialise neighbours
114       int neighbours = 0;
115       //check surrounding life
116       for int ic = (c-1); ic <= (c+1); ic++) {
117         for int ir = (r-1); ir <= (r+1); ir++) {
118           if (((ic>=0)&&(ic<size))&&((ir>=0)&&(ir<size))) {
119             // don't include self
120             if (!(ic == c && ir == r)) {
121               // if there is life increment neighbours
122               if (world[ic][ir]==1neighbours++;
123             }
124           }
125         }
126       }
127 
128       // apply game of life rules
129       // if there is life
130       if (world[c][r== 1) {
131         if (neighbours < || neighbours > 3) {
132           newworld[c][r0// Cell dies
133         }
134         // if there isn't life
135       else {// i.e. world[c][r] == 0
136         if (neighbours == 3) {
137           newworld[c][r1;  // Cell becomes alive
138         }
139       }
140     }
141   }
142 
143   // initialise newworld
144   for (int x = 0; x < size; x++) {
145     for (int y = 0; y < size; y++) {
146       world[x][y= newworld[x][y];
147     }
148   }
149 }
150 
151 
152 void mousePressed() {
153   if (pause) {
154     pause = false;
155   else {
156     pause = true;
157     System.out.println("pause");
158   }
159   
160 }

Java2html

 
 


  
   


Wednesday 23 July 2014

ODEs with Java using the Apache Commons Math library

It drives me nuts when I struggle to get my head around something just to, when I eventually do, discover that it is not really as complicated as the documentation makes it out to be. Simple examples are what I need. Here is an example of how to implement the Lorenz System. Not that I really know much about the Lorenz System but it is always a simple system to use when you want to try out a new way of solving differential equations. More information about the Lorenz System can be found in Wikipedia.

The first thing to do is to create a class containing the equations. The Lorenz system consists of the following three equations:


Doing this using the Apache Commons Math library means that we have to create a class that implements the FirstOrderDifferentialEquations interface. This interface requires two methods to be implemented, which are computeDerivatives and getDimension:


01 import org.apache.commons.math3.exception.DimensionMismatchException;
02 import org.apache.commons.math3.exception.MaxCountExceededException;
03 import org.apache.commons.math3.ode.FirstOrderDifferentialEquations;
04 
05 public class Lorenz implements FirstOrderDifferentialEquations {
06 
07         double sigma = 10.0;
08         double beta = 3;
09         double rho = 28.0;
10         double X, Y, Z;
11 
12         @Override
13         public void computeDerivatives(double t, double[] y, double[] yDot)
14                         throws MaxCountExceededException, 

                           DimensionMismatchException {
15                 X = y[0];
16                 Y = y[1];
17                 Z = y[2];
18                 yDot[0= sigma * (Y - X);
19                 yDot[1= X * (rho - Z- Y;
20                 yDot[2(X * Y(beta * Z);
21         }
22 
23         @Override
24         public int getDimension() {
25                 // TODO Auto-generated method stub
26                 return 3;
27         }
28 }
Java2html

The next step is to write the code that will call the integrator. There are various integrators. For this application we'll use the ClassicalRungeKuttaIntegrator. You will also need a step handler to capture each step of the integration:

01 import org.apache.commons.math3.ode.FirstOrderDifferentialEquations;
02 import org.apache.commons.math3.ode.nonstiff.ClassicalRungeKuttaIntegrator;
03 import org.apache.commons.math3.ode.sampling.StepHandler;
04 
05 public class LorenzMain {
06 
07         public static void main(String[] args) {
08 
09                 ClassicalRungeKuttaIntegrator rk4 = 

                           new ClassicalRungeKuttaIntegrator(0.01);
10                 FirstOrderDifferentialEquations ode = new Lorenz();
11                 double[] y = new double[] { 10.0, -2.050 }// initial state
12                 StepHandler stepHandler = new 

                           WriteToFileStepHandler("lorenz.csv");
13                 rk4.addStepHandler(stepHandler);
14                 rk4.integrate(ode, // equations
15                                 0.0// start time
16                                 y, // initial conditions
17                                 100.0// end time
18                                 y)// result
19                 for (int i = 0; i < y.length; i++) {
20                         System.out.println(y[i]);
21                 }
22         }
23 }
Java2html

The step handler has to implement the StepHandler class. For the step handler below I created a constructor that takes a filename so that the results can be written to a csv file. Obviously you can do whatever you want with this data:

01 import java.io.File;
02 import java.io.PrintWriter;
03 import java.util.ArrayList;
04 
05 import org.apache.commons.math3.exception.MaxCountExceededException;
06 import org.apache.commons.math3.ode.sampling.StepHandler;
07 import org.apache.commons.math3.ode.sampling.StepInterpolator;
08 
09 
10 public class WriteToFileStepHandler implements StepHandler {
11         ArrayList<String> steps = new ArrayList<String>();
12         String filename;
13         
14         public WriteToFileStepHandler(String filename) {
15                 this.filename = filename;
16         }
17         @Override
18         public void handleStep(StepInterpolator interpolator, boolean isLast)
19                         throws MaxCountExceededException {
20                 double t = interpolator.getCurrentTime();
21                 double[] y = interpolator.getInterpolatedState();
22                         String onestep = "" + t;
23                         for (int i = 0; i < y.length; i++) {
24                                 onestep += ", " + y[i];
25                         }
26                         steps.add(onestep);
27                 if (isLast) {
28                         try {
29                                 PrintWriter writer = 

30                                 new PrintWriter(new File(filename)
                                   "UTF-8");                                    
31                                 for (String step : steps) {
32                                         writer.println(step);
33                                 }
34                                 writer.close();
35                         catch (Exception e) {
36                         }
37                         ;
38                 }
39         }
40 
41         @Override
42         public void init(double t0, double[] y0, double t) {
43                 // TODO Auto-generated method stub
44 
45         }
46 
47 }
Java2html
Last but not the least I read the file with R and created the graph: