// The Boltzmann Macihne: The Necker Cube Example // // by Simon Dennis // // 20th December 1995 // import java.awt.*; import java.awt.Graphics; import java.lang.Math; import java.lang.Integer; public class Necker extends java.applet.Applet { int Gx; int Gy; boolean filled = true; int a[] = {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0}; int w[][] = {{0, 2, 0, 2, 2, 0, 0, 0, -3, -3, 0, 0, 0, 0, 0, 0}, {2, 0, 2, 0, 0, 2, 0, 0, -3, -3, 0, 0, 0, 0, 0, 0}, {0, 2, 0, 2, 0, 0, 2, 0, 0, 0, -3, -3, 0, 0, 0, 0}, {2, 0, 2, 0, 0, 0, 0, 2, 0, 0, -3, -3, 0, 0, 0, 0}, {2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, -3, -3, 0, 0}, {0, 2, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, -3, -3, 0, 0}, {0, 0, 2, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, -3, -3}, {0, 0, 0, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, -3, -3}, {-3, -3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 0}, {-3, -3, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 2, 0, 0}, {0, 0, -3, -3, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 2, 0}, {0, 0, -3, -3, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 2}, {0, 0, 0, 0, -3, -3, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2}, {0, 0, 0, 0, -3, -3, 0, 0, 0, 2, 0, 0, 2, 0, 2, 0}, {0, 0, 0, 0, 0, 0, -3, -3, 0, 0, 2, 0, 0, 2, 0, 2}, {0, 0, 0, 0, 0, 0, -3, -3, 0, 0, 0, 2, 2, 0, 2, 0}}; int x[] ={25, 50, 150, 125, 25, 50, 150, 125, 125, 150, 250, 225, 125, 150, 250, 225}; int y[] = {125, 100, 100, 125, 225, 200, 200, 225, 325, 300, 300, 325, 425, 400, 400, 425}; int connected[] = {0, 1, 0, 3, 0, 4, 1, 2, 2, 3, 2, 6, 3, 7, 4, 7, 6, 7, 8, 9, 8, 12, 9, 10, 9, 13, 10, 14, 12, 13, 12, 15, 13, 14, 14, 15}; private Button OneB, TwentyB, ResetB; private Checkbox WeightsC; public void init() { resize(400,500); Panel p = new Panel(); // panel holds group of wigits Panel local = new Panel(); local.setLayout(new GridLayout(2, 2, 20, 20)); //layout manger for panel OneB = new Button("Do 1 Iteration"); local.add(OneB); TwentyB = new Button("Do 20 Iterations"); local.add(TwentyB); ResetB = new Button("Reset"); local.add(ResetB); WeightsC = new Checkbox("Weights visible?"); local.add(WeightsC); p.add(local); add(p); } public void paint(Graphics g) { int i; int j; int goodness; if (WeightsC.getState()){ for (i=0; i<16; i++) for (j=0; j<16; j++) if (w[i][j] > 0){ g.setColor(Color.blue); g.drawLine(x[i]+10, y[i]+10, x[j]+10, y[j]+10); } else if (w[i][j] < 0){ g.setColor(Color.red); g.drawLine(x[i]+10, y[i]+10, x[j]+10, y[j]+10); } } else { for (i=0; i<35; i=i+2){ g.setColor(Color.black); g.drawLine(x[connected[i]]+10, y[connected[i]]+10, x[connected[i+1]]+10, y[connected[i+1]]+10); }; }; g.setColor(Color.black); for (i=0; i< 16; i++) if (a[i] == 1){ g.drawRect(x[i],y[i], 20, 20); g.clearRect(x[i]+1,y[i]+1, 19, 19); } else { g.fillRect(x[i],y[i], 20, 20); } goodness = 0; for (i=0; i<16; i++) for (j=0; j<16; j++) goodness = goodness + w[i][j] * a[i] * a[j]; g.drawString("Goodness = " + Integer.toString(goodness), 225, 150); } public double sigmoid(double x){ return(1.0/(1+Math.exp(-x))); } public boolean action(Event evt, Object arg) { double r; int unit; float netinput; int i; int NumberOfIterations, Iterations; NumberOfIterations = 1; if ("Do 1 Iteration".equals(arg)) NumberOfIterations = 1; else if ("Do 20 Iterations".equals(arg)) NumberOfIterations = 20; else if ("Reset".equals(arg)){ for (i=0; i<16; i++) if (Math.random() < 0.5) a[i] = 0; else a[i] = 1; repaint(); return(true); }; for (Iterations=0; Iterations < NumberOfIterations; Iterations++){ unit = (int) (Math.random() *16.0); netinput = 0; for (i=0; i<16; i++) netinput = netinput + a[i] * w[unit][i] ; r = Math.random(); if (r < sigmoid((double)netinput)) a[unit] = 1; else a[unit] = 0; }; repaint(); return(true); } }