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:


Sunday, 29 September 2013

Motorcyclist having to cope with ignorant idiots on the road.

A message to the bloke in the big black Seat that had a blonde lady next to him in the passenger seat and was driving past St James' Park at about 16.30 on Saturday 28 September 2013.

The reason you wouldn't let me into the traffic stream is not, as you so gracefully tried to sign to me, because I am a wanker. It is because you are a very rude, immature, ignorant and dumb old fart.

Rude, because if you had any sense of decency you would not have tried to push me out of the lane by driving up my left. Considering the traffic at that time, it would have been kind to let me in even if I was, which I wasn't by the way, in the wrong.

You see this is why you are ignorant because if you knew anything, you would have known that motorcycles are allowed to filter up the right of traffic and then merge in again. Mostly, the reason it becomes difficult to merge into traffic, is because immature people like you, apparently, are afraid that some body part is going to shrink or fall off if you let a motorcyclist get in front of you. I can assure you this is not the case. You can ask your doctor if you don't believe me. 

You must be dumb or else you would have done something by now to improve you knowledge of driving skills and traffic. You seemed to be about my age, give or take 5 years which means you have had more than enough time to do this.

Lastly you are an old fart just because of all of the above and "old fart" pretty much sums up the whole lot.

Friday, 31 May 2013

Suzuki Burgman UH200

In June 2009 I bought myself a brand new Sym Symply 125cc scooter for about £1500 to get myself to and from University. 15000 miles later I sold the Symply back to the agent for £200 because it would just cost too much to keep it on the road. However, I still needed something to get to uni and back. So I put the £200 towards buying a second hand Suzuki Burgman. I have been riding the Burgman that last two weeks and it really is such a delight. Despite the horrible weather we have had up here in the north of England I find myself  enjoying every minute of the trip.

One of the major advantages of the Burgman is that it has a massive luggage space under the seat. Unlike the Symply my helmet actually fits in there. Apparently it can take two helmets. I haven't tried two helmets but I'm pretty sure it will do it easily. I'm one of those people that are forever carrying myself to death with my backpack that I cart along with me wherever I go. The backpack fits under the seat with all my other goods and gadgets with ease.

The second thing that makes the actual ride such a joy is the seat. It is really comfortable. The seat is nice and wide and it has a little bit of a support behind your back. With more leg space you can stretch your legs out a bit making it much more relaxing. The Burgman is also much lower and I can put both my feet down flat when I stop, again making for a much more relaxed ride (or stop if you please).

The Symply had a little hook onto which one could hang a bag by your feet. When you hung a bag in the footwell though you had to swing your leg over the seat to get onto the scooter. Although, I guess, this kept me supple it was a bit of a drag and a couple of times the hooks on my boot nipped a tear in the seat which was  very annoying. With the big luggage compartment on the Burgman this problem does not arise.

I have only filled up the tank twice so I haven't worked out the fuel consumption yet, but the fuel tank on the Burgman is at least double the size of the Symply's. I did at least 120 miles after the first fill-up and the tank wasn't empty yet.

So both thumbs up for the Burgman!

The Suzuki Burgman UH200

The Sym Symply 125 when it was new.

Monday, 18 July 2011

Lack-of-service-BT continues ...

So, about 3 weeks ago someone from BT calls me and offers to put me through to their disputes team. Being in the middle of the day on a Friday while I'm in the lab, I couldn't take the call, so I was told to call back and ask for disputes. Today, after about 3 weeks it was the first time I was home during the day so that I could make the call. As usual I had to venture through an endless maze of menu options before someone answered the phone. Between being put on hold and arguing the fact that I actually want to talk to disputes and not pay extra to get out of a contract that was mis-sold to me, I was cut off after 19 minutes and 55 seconds. Then the first amazing thing happened. I was called back within seconds and offered an apology for being cut off. I was then transfered to someone whom I believe must be in disputes. I had to explain the whole static IP address again and was then transferred to someone to me that they just have to tell me that they are going to investigate the issue and have to inform me that they will be retrieving and listening to the original calls. Amazing! This is what I've been wanting from the beginning. So, hopefully in the next 5 working days I'll hear from them and get this resolved.