PHY 411-506 Home Home  |  Course Outline  |  Lectures  |  Homework  |  Files

Lecture 40: April 30


Forest fire automaton model

The following applet is based on the program ForestFire.java, which is an implementation of Problems 15.12 and 15.13 on pages 523-4 of the textbook.

Here is the code which generates this applet:

// ForestFire.java

import java.awt.*;
import java.awt.event.*;
import comphys.graphics.*;
import comphys.Easy;

public class ForestFire extends Animation {

    double pt = 0.2;            // initial probability of tree at site
    double p = 0.2;             // growth probability
    double f = 0.1;             // lightning strike probability

    int L = 30;                 // number of trees = L * L
    final int EMPTY = 0;
    final int ALIVE = 1;
    final int AFIRE = 2;
    final int STUMP = 3;
    final int SHOOT = 4;
    final int LIGHT = 5;
    int[][] site;               // current state of forest
    int[][] oldSite;            // from previous time step
    int[] np;                   // for cluster labeling
    boolean instantaneous;      // lightning model instantaneous spreading

    int t;                      // time

    void copyToOld () {
        for (int i = 0; i <= L + 1; i++) {
            for (int j = 0; j <= L + 1; j++) {
                oldSite[i][j] = site[i][j];
            }
        }
    }

    void initial () {
        if (site == null || site.length < L + 2) {
            site = new int[L + 2][L + 2];
            oldSite = new int[L + 2][L + 2];
            np = new int[(L + 2) * (L + 2)];
        }
        // empty boundary
        site[0][0] = site[0][L + 1] = EMPTY;
        site[L + 1][0] = site[L + 1][L + 1] = EMPTY;
        for (int i = 1; i <= L; i++) {
            site[0][i] = site[i][0] = site[i][L + 1] = site[L + 1][i] = EMPTY;
        }
        // interior trees alive with probability p_t
        for (int i = 1; i <= L; i++) {
            for (int j = 1; j <= L; j++) {
                if (Math.random() < pt) {
                    if (!instantaneous && Math.random() < f)
                        site[i][j] = AFIRE;
                    else
                        site[i][j] = ALIVE;
                } else {
                    site[i][j] = EMPTY;
                }
            }
        }
        copyToOld();
        t = 0;
    }

    void simpleSpreadingRule () {
        // model on page 523
        for (int i = 1; i <= L; i++) {
            for (int j = 1; j <= L; j++) {
                switch (oldSite[i][j]) {
                case STUMP:
                    site[i][j] = EMPTY;
                case EMPTY:
                    if (Math.random() < p)
                        site[i][j] = SHOOT;
                    break;
                case SHOOT:
                    site[i][j] = ALIVE;
                case ALIVE:
                    if (oldSite[i][j - 1] == AFIRE ||
                        oldSite[i][j + 1] == AFIRE ||
                        oldSite[i - 1][j] == AFIRE ||
                        oldSite[i + 1][j] == AFIRE )
                        site[i][j] = AFIRE;
                    break;
                case LIGHT:
                case AFIRE:
                    site[i][j] = STUMP;
                }
            }
        }
    }

    // Hoshen-Kopelman cluster labeling algorithm

    int proper (int label) {
        // recursive function
        if (np[label] == label)
            return label;
        else
            return proper(np[label]);
    }

    void label_min (int x, int y, int left, int down) {
        // both neighbors occupied, determine minimum cluster number
        if (site[left][y] == site[x][down]) {
            // both neighbors have same cluster label
            site[x][y] = site[left][y];
        } else {
            // determine minimum cluster label
            int cl_left = proper(site[left][y]);
            int cl_down = proper(site[x][down]);
            int nmax = cl_left;
            int nmin = cl_down;
            if (cl_down > cl_left) {
                nmax = cl_down;
                nmin = cl_left;
            }
            site[x][y] = nmin;
            if (nmin != nmax)
                np[nmax] = nmin; // set improper label nmax = nmin
        }
    }

    void neighbor (int x, int y) { // determine occupancy of neighbors
        int down = y - 1;
        int left = x - 1;
        if (site[x][down] * site[left][y] > 0) { // both neighbors occupied
            label_min(x, y, left, down);
        } else if (site[x][down] > 0) {          // down neighbor occupied
            site[x][y] = site[x][down];
        } else {                                 // left neighbor occupied
            site[x][y] = site[left][y];
        }
    }

    int maxClusterNumber;

    void assign () {
        // assign cluster numbers to occupied sites
        for (int i = 0; i < np.length; i++)
            np[i] = 0;
        int ncluster = 0;                          //  cluster number
        for (int y = 1; y <= L; y++) {
            for (int x = 1; x <= L; x++) {
                if (site[x][y] < 0) {              // site occupied
                    int down = y - 1;              // square lattice
                    int left = x - 1;
                    if (site[x][down] + site[left][y] == 0) {
                        ++ncluster;                // new cluster
                        site[x][y] = ncluster;
                        np[ncluster] = ncluster;   // proper label
                    } else {
                        neighbor(x, y);
                    }
                }
            }
        }
        // assign proper labels to cluster array
        maxClusterNumber = 0;
        for (int y = 1; y <= L; y++) {
            for (int x = 1; x <= L; x++) {
                site[x][y] = proper(site[x][y]);
                if (site[x][y] > maxClusterNumber)
                    maxClusterNumber = site[x][y];
            }
        }
    }

    boolean[] clusterOnFire;
    
    void instantaneousSpreadingRule () {
        // model on page 524
        for (int i = 1; i <= L; i++) {
            for (int j = 1; j <= L; j++) {
                switch (oldSite[i][j]) {
                case STUMP:
                    oldSite[i][j] = site[i][j] = EMPTY;
                case EMPTY:
                    if (Math.random() < p)
                        oldSite[i][j] = SHOOT;
                    break;
                case SHOOT:
                    oldSite[i][j] = ALIVE;
                case ALIVE:
                    site[i][j] = -1; // needs to be assigned to a cluster
                    if (Math.random() < f)
                        oldSite[i][j] = LIGHT;
                    break;
                case LIGHT:
                    oldSite[i][j] = AFIRE;
                    site[i][j] = EMPTY;
                    break;
                case AFIRE:
                    site[i][j] = EMPTY;
                    oldSite[i][j] = STUMP;
                    break;
                }
            }
        }
        // use Hoshen-Kopelman algorithm (page 426) to label clusters
        assign();
        // determine which clusters are on fire
        if (clusterOnFire == null ||
            clusterOnFire.length < maxClusterNumber + 1)
            clusterOnFire = new boolean[maxClusterNumber + L];
        for (int i = 1; i <= maxClusterNumber; i++)
            clusterOnFire[i] = false;
        for (int i = 1; i <= L; i++) {
            for (int j = 1; j <= L; j++) {
                if (oldSite[i][j] == LIGHT)
                    clusterOnFire[site[i][j]] = true;
            }
        }
        for (int i = 1; i <= L; i++) {
            for (int j = 1; j <= L; j++) {
                if (site[i][j] == EMPTY) {
                    site[i][j] = oldSite[i][j];
                } else {
                    if (clusterOnFire[site[i][j]]) {
                        if (oldSite[i][j] == LIGHT)
                            site[i][j] = LIGHT;
                        else
                            site[i][j] = AFIRE;
                    } else {
                        site[i][j] = oldSite[i][j];
                    }
                }
            }
        }
    }

    void takeStep () {
        copyToOld();
        if (instantaneous) {
            instantaneousSpreadingRule();
        } else {
            simpleSpreadingRule();
        }
        ++t;
    }

    Color lightGreen = new Color(51, 255, 0);
    Color darkGreen = new Color(0, 153, 0);
    Color brown = new Color(204, 153, 0);

    class Forest extends Plot {
        public void paint () {
            clear();
            setWindow(0, L, 0, L);
            for (int i = 1; i <= L; i++) {
                for (int j = 1; j <= L; j++) {
                    switch (site[i][j]) {
                    case EMPTY:
                        osg.setColor(brown);
                        break;
                    case ALIVE:
                        osg.setColor(darkGreen);
                        break;
                    case AFIRE:
                        setColor("yellow");
                        break;
                    case STUMP:
                        setColor("black");
                        break;
                    case SHOOT:
                        osg.setColor(lightGreen);
                        break;
                    case LIGHT:
                        setColor("red");
                        break;
                    }
                    boxArea(i - 1, i + 0.1, j - 1, j + 0.1);
                }
            }
        }
    }

    Forest forest;
    TextField pTextField, fTextField;
    Checkbox instantaneousBox;
    Reader LReader, ptReader;

    void pGet () {
        try {
            p = new Double(pTextField.getText()).doubleValue();
        } catch (Exception e) {
            pTextField.setText("" + Easy.format(p, 4));
        }
    }

    void fGet () {
        try {
            f = new Double(fTextField.getText()).doubleValue();
        } catch (Exception e) {
            fTextField.setText("" + Easy.format(f, 4));
        }
    }

    public void init () {
        initial();
        add(forest = new Forest());
        add(LReader = new Reader("L = ", L));
        add(ptReader = new Reader("p_t = ", pt, 4));
        Panel pPanel = new Panel(new GridLayout(1, 2));
        pPanel.add(new Label("P(new tree) ="));
        pTextField = new TextField("" + Easy.format(p, 4));
        pTextField.addActionListener(new ActionListener () {
            public void actionPerformed (ActionEvent ae) {
                pGet();
            }
        });
        pPanel.add(pTextField);
        add(pPanel);
        Panel fPanel = new Panel(new GridLayout(1, 2));
        fPanel.add(new Label("P(set fire) ="));
        fTextField = new TextField("" + Easy.format(f, 4));
        fTextField.addActionListener(new ActionListener () {
            public void actionPerformed (ActionEvent ae) {
                fGet();
            }
        });
        fPanel.add(fTextField);
        add(fPanel);
        add(instantaneousBox = new Checkbox("Lightning!", instantaneous));
        instantaneousBox.addItemListener(new ItemListener() {
            public void itemStateChanged (ItemEvent ie) {
                instantaneous = instantaneousBox.getState();
            }
        });
        addControlPanel();
    }

    public void step () {
        takeStep();
        forest.repaint();
    }

    public void reset () {
        L = LReader.readInt();
        pt = ptReader.readDouble();
        pGet();
        fGet();
        initial();
        forest.repaint();
    }

    public static void main (String[] args) {
        ForestFire forestFire = new ForestFire();
        forestFire.frame("Forest Fire Automaton Model", 430, 600);
    }
}

Neural networks and associative memory

Click for diagrams of the nervous system and neurons.

The following applet is based on the program Hopfield.java, which is an implementation of Problems 15.12 and 15.13 on pages 523-4 of the textbook.

Here is the code which generates this applet:

// Hopfield.java

import comphys.graphics.*;
import comphys.Easy;

public class Hopfield extends Animation {

    static final int plotWidth = 400;
    static final int plotHeight = 400;
    static final int maxN = 100;

    int N;
    int[][][][] J;              // connection strength
    int[][] B;                  // bias term
    int[][][] L;
    int M;
    int P;                      // probability
    int[] H;                    // Hamming distances
    double sumH;
    int[] X, Y;                 // visited neurons
    int t;

    void initial () {
        N = 10;
        M = 1;
        P = 30;
        J = new int [10][10][10][10];
        B = new int [10][10];
        L = new int [10][10][10];
        H = new int [26];
        X = new int [26];
        Y = new int [26];
    }

    void initializeNetwork() {
        int i, j, k, l, m;
        for (i = 0; i < N; ++i)
            for (j = 0; j < N; ++j)
                for (k = 0; k < N; ++k)
                    for (l = 0; l < N; ++l)
                        J[i][j][k][l] = 0;
        for (m = 0; m < M; ++m)
            for (i = 0; i < N; ++i)
                for (j = 0; j < N; ++j)
                    for (k = 0; k < N; ++k)
                        for (l = 0; l < N; ++l)
                            J[i][j][k][l] += Letter[m][i][j] * Letter[m][k][l];
        for (i = 0; i < N; ++i)
            for (j = 0; j < N; ++j)
                J[i][j][i][j] = B[i][j] = 0;
        for (i = 0; i < N; i++)
            for (j = 0; j < N; j++)
                for (k = 0; k < N; k++)
                    for (l = 0; l < N; l++)
                        B[i][j] += J[i][j][k][l];
        if (L.length < M)
            L = new int [M][N][N];
        for (m = 0; m < M; ++m)
            for (i = 0; i < N; ++i)
                for (j = 0; j < N; ++j)
                    if (Math.random() > P / 100.0)
                        L[m][i][j] = Letter[m][i][j];
                    else L[m][i][j] = -Letter[m][i][j];
        t = 0;
        iNext = 0;
        jNext = -1;
    }

    boolean regularSweep;
    boolean bias;
    int iNext;
    int jNext = -1;

    void takeStep() {
        if (++jNext == N) {
            jNext = 0;
            if (++iNext == N)
                iNext = 0;
        }
        for (int m = 0; m < M; ++m) {
            int i = 0;
            int j = 0;
            if (regularSweep) {
                i = iNext;
                j = jNext;
            } else {
                i = (int) (Math.random() * N);
                j = (int) (Math.random() * N);
            }
            X[m] = j;
            Y[m] = i;
            double E_flip = 0;
            for (int k = 0; k < N; ++k)
                for (int l = 0; l < N; ++l)
                    E_flip += J[i][j][k][l] * L[m][k][l];
            if (bias)
                E_flip -= 0.5 * B[i][j];
            E_flip *= 2 * L[m][i][j] / (double) M;
            if (E_flip < 0)
                L[m][i][j] = -L[m][i][j];
        }
        computeHammingDistances();
        ++t;
    }

    void computeHammingDistances() {
        sumH = 0;
        for (int m = 0; m < M; ++m) {
            H[m] = 0;
            for (int i = 0; i < N; ++i) {
                for (int j = 0; j < N; ++j) {
                    int d = Letter[m][i][j] - L[m][i][j];
                    H[m] += d * d;
                }
            }
            sumH += H[m] / (double) (4 * N * N);
        }
    }

    boolean running;

    class Network extends Plot {
        public void paint () {
            clear();
            int Lx = (int) Math.sqrt(M);
            if (Lx * Lx != M)
                Lx += 1;
            int Ly = Lx;
            int margin = plotWidth / (N * Lx);
            int letterSize = (plotWidth - (Lx + 1) * margin) / Lx;
            int pixelSize = letterSize / N;
            int radius = pixelSize / 4;
            if (radius < 1)
                radius = 1;
            int m = 0;
            int x = 0;
            int y = 0;
            while (m < M) {
                for (int j = 0; j < N; ++j) {
                    for (int i = 0; i < N; ++i) {
                        if (L[m][j][i] == 1) {
                            if (H[m] == 0)
                                setColor("black");
                            else setColor("red");
                        } else setColor("yellow");
                        osg.fillRect(margin +
                                     x * (margin + letterSize) + i * pixelSize,
                                     margin +
                                     y * (margin + letterSize) + j * pixelSize,
                                     pixelSize - 2, pixelSize - 2);
                    }
                }
                if (running && H[m] != 0) {
                    setColor("green");
                    osg.fillOval(margin + radius +
                                 x * (margin + letterSize) + X[m] * pixelSize,
                                 margin + radius +
                                 y * (margin + letterSize) + Y[m] * pixelSize,
                                 2 * radius, 2 * radius);
                }
                if (++x == Lx) {
                    ++y;
                    x = 0;
                }
                ++m;
            }
            setColor("blue");
            osg.drawString("t = " + t, 40, plotHeight - 10);
            osg.drawString("Total Hamming Distance = " + Easy.format(sumH, 4),
                           150, plotHeight - 10);
        }
    }

    Network network;
    Reader MReader, PReader, sweepReader, biasReader;

    public void init () {
        initial();
        add(network = new Network());
        add(MReader = new Reader("Memories =", M));
        add(PReader = new Reader("% Errors =", P));
        add(sweepReader = new Reader("Regular sweep", regularSweep));
        add(biasReader = new Reader("Bias term", bias));
        addControlPanel();
        initializeNetwork();
        computeHammingDistances();
    }

    public void step () {
        takeStep();
        computeHammingDistances();
        if (sumH == 0) {
            stopAnimation();
            running = false;
        } else {
            running = true;
        }
        network.repaint();
    }

    public void reset () {
        M = MReader.readInt();
        if (M < 1)
            M = 1;
        if (M > 26)
            M = 26;
        P = PReader.readInt();
        if (P < 0)
            P = 0;
        if (P > 100)
            P = 100;
        regularSweep = sweepReader.readBoolean();
        bias = biasReader.readBoolean();
        initializeNetwork();
        computeHammingDistances();
        running = false;
        network.repaint();
    }

    public static void main (String[] args) {
        Hopfield hopfield = new Hopfield();
        hopfield.frame("Hopfield neural network model", 430, 600);
    }

    int Letter[][][] = {
        {
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, +1, +1, +1, +1, -1, -1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {+1, +1, +1, -1, -1, -1, -1, +1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, -1, -1, -1},
            {-1, +1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, +1, +1, +1, +1, +1, -1, -1, -1},
            {-1, -1, +1, +1, +1, +1, +1, -1, -1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, +1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, -1, -1, -1}
        },         {
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, +1, +1, +1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, +1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1}
        },         {
            {+1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {+1, +1, +1, +1, +1, +1, +1, -1, -1, -1}
        },         {
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, -1, -1},
            {+1, +1, -1, -1, -1, -1, -1, -1, -1, -1},
            {+1, +1, +1, +1, +1, +1, -1, -1, -1, -1},
            {+1, +1, +1, +1, +1, +1, -1, -1, -1, -1},
            {+1, +1, -1, -1, -1, -1, -1, -1, -1, -1},
            {+1, +1, -1, -1, -1, -1, -1, -1, -1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, -1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {+1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {+1, +1, -1, -1, -1, -1, -1, -1, -1, -1},
            {+1, +1, -1, -1, -1, -1, -1, -1, -1, -1},
            {+1, +1, -1, -1, -1, -1, +1, +1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, +1, +1, +1},
            {+1, +1, +1, -1, -1, -1, -1, +1, +1, +1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1}
        },         {
            {-1, +1, +1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, -1, +1, +1}
        },         {
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1}
        },         {
            {-1, -1, -1, +1, +1, +1, +1, +1, +1, -1},
            {-1, -1, -1, +1, +1, +1, +1, +1, +1, -1},
            {-1, -1, -1, -1, -1, -1, +1, +1, +1, -1},
            {-1, -1, -1, -1, -1, -1, -1, +1, +1, -1},
            {-1, -1, -1, -1, -1, -1, -1, +1, +1, -1},
            {-1, -1, -1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1}
        },         {
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, +1, +1, -1},
            {+1, +1, -1, -1, -1, -1, +1, +1, -1, -1},
            {+1, +1, -1, -1, -1, +1, +1, -1, -1, -1},
            {+1, +1, +1, +1, +1, -1, -1, -1, -1, -1},
            {+1, +1, +1, +1, +1, -1, -1, -1, -1, -1},
            {+1, +1, -1, -1, -1, +1, +1, -1, -1, -1},
            {+1, +1, -1, -1, -1, -1, +1, +1, -1, -1},
            {+1, +1, -1, -1, -1, -1, -1, +1, +1, -1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1}
        },         {
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1}
        },         {
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, +1, -1, -1, -1, -1, +1, +1, +1},
            {+1, +1, +1, +1, -1, -1, +1, +1, +1, +1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {+1, +1, -1, +1, +1, +1, +1, -1, +1, +1},
            {+1, +1, -1, -1, +1, +1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1}
        },         {
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, +1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, +1, +1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, +1, +1, -1, -1, -1, +1, +1},
            {+1, +1, -1, +1, +1, +1, -1, -1, +1, +1},
            {+1, +1, -1, -1, +1, +1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, +1, +1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, +1, +1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, +1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {+1, +1, +1, -1, -1, -1, -1, +1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, +1, -1, -1, -1, -1, +1, +1, +1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, -1, -1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {+1, +1, +1, -1, -1, +1, +1, +1, -1, -1},
            {+1, +1, -1, -1, -1, -1, +1, +1, -1, -1},
            {+1, +1, -1, -1, -1, -1, +1, +1, -1, -1},
            {+1, +1, -1, +1, +1, -1, +1, +1, -1, -1},
            {+1, +1, -1, -1, +1, +1, +1, +1, -1, -1},
            {+1, +1, +1, -1, -1, +1, +1, +1, -1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, +1, +1, +1, +1, -1, -1, -1, +1, +1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, +1, +1, -1, +1, +1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, +1, +1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, +1, +1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1}
        },         {
            {-1, -1, -1, +1, +1, +1, +1, +1, -1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, -1, -1, -1, -1, -1, -1, +1, +1, -1},
            {-1, -1, -1, -1, -1, -1, -1, +1, +1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, -1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1}
        },         {
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, +1, -1, -1, +1, +1, +1, -1},
            {-1, -1, +1, +1, +1, +1, +1, +1, -1, -1}
        },         {
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, -1, +1, +1, +1, +1, -1, -1, -1},
            {-1, -1, -1, +1, +1, +1, +1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1}
        },         {
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {+1, +1, -1, -1, +1, +1, -1, -1, +1, +1},
            {+1, +1, -1, +1, +1, +1, +1, -1, +1, +1},
            {+1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {+1, +1, +1, +1, -1, -1, +1, +1, +1, +1},
            {+1, +1, +1, -1, -1, -1, -1, +1, +1, +1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1}
        },         {
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, -1, +1, +1, +1, +1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, +1, +1, +1, +1, -1, -1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1}
        },         {
            {+1, +1, -1, -1, -1, -1, -1, -1, +1, +1},
            {-1, +1, +1, -1, -1, -1, -1, +1, +1, -1},
            {-1, -1, +1, +1, -1, -1, +1, +1, -1, -1},
            {-1, -1, -1, +1, +1, +1, +1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, +1, +1, +1, +1, -1, -1, -1}
        },         {
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, -1, -1, -1, -1, -1, +1, +1, +1, -1},
            {-1, -1, -1, -1, -1, -1, +1, +1, -1, -1},
            {-1, -1, -1, -1, -1, +1, +1, -1, -1, -1},
            {-1, -1, -1, -1, +1, +1, -1, -1, -1, -1},
            {-1, -1, -1, +1, +1, -1, -1, -1, -1, -1},
            {-1, -1, +1, +1, +1, -1, -1, -1, -1, -1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1},
            {-1, +1, +1, +1, +1, +1, +1, +1, +1, +1}
        }
    };
}


UB Physics Home Questions or comments: phygons@acsu.buffalo.edu