// SimulateWindow.java // Written by Julian Devlin, 8/97, for the text book // "Introduction to Probability," by Charles M. Grinstead & J. Laurie Snell import java.applet.Applet; import java.awt.*; public class SimulateWindow extends java.awt.Frame { Panel dispArea; Panel controls; // Panel for user controls Panel pPanel; Label numl; // Controls TextField num; TextField[][] P; TextArea output; Matrix pMat, wMat, xMat, zMat, cMat; float[][] rls; float[][] cls; String[] names; int[] count; float[] fraction; Matrix rows, columns1, columns2; Label pLab, wLab; Checkbox print; Button go; GridBagLayout gbl, pgbl, dgbl; GridBagConstraints cc, pcc, dcc; JRandom myRand; int size; Color labC; public SimulateWindow(int s) { super("SimulateChain"); size = s; } // Initialize applet public void init() { go = new Button("Go"); output = new TextArea(15, 30); numl = new Label("No."); // Create controls num = new TextField("250", 4); count = new int[size]; fraction = new float[size]; rls = new float[size][1]; for (int i = 0; i < size; i++) { rls[i][0] = i + 1; } cls = new float[1][size]; for (int i = 0; i < size; i++) { cls[0][i] = i + 1; } if (size == 3) { P = new TextField[3][3]; P[0][0] = new TextField(".5", 4); P[0][1] = new TextField(".25", 4); P[0][2] = new TextField(".25", 4); P[1][0] = new TextField(".5", 4); P[1][1] = new TextField("0", 4); P[1][2] = new TextField(".5", 4); P[2][0] = new TextField(".25", 4); P[2][1] = new TextField(".25", 4); P[2][2] = new TextField(".5", 4); names = new String[3]; names[0] = new String("R"); names[1] = new String("N"); names[2] = new String("S"); } else { P = new TextField[size][size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { P[i][j] = new TextField("0", 4); } } names = new String[size]; for (int i = 0; i < size; i++) { names[i] = new String(String.valueOf(i + 1)); } } pLab = new Label("P = "); pLab.setAlignment(Label.RIGHT); wLab = new Label("w = "); wLab.setAlignment(Label.RIGHT); labC = new Color(100, 0, 0); rows = new Matrix(rls); rows.setColor(labC); columns1 = new Matrix(cls); columns1.setColor(labC); columns2 = new Matrix(cls); columns2.setColor(labC); dispArea = new Panel(); // Set up window controls = new Panel(); pPanel = new Panel(); setLayout(new BorderLayout(5, 5)); add("South", controls); add("Center", dispArea); pgbl = new GridBagLayout(); pcc = new GridBagConstraints(); pPanel.setLayout(pgbl); for (int r = 0; r < size; r++) { for (int c = 0; c < size; c++) { pcc.gridx = c; pcc.gridy = r; pgbl.setConstraints(P[r][c], pcc); pPanel.add(P[r][c]); } } dgbl = new GridBagLayout(); dcc = new GridBagConstraints(); dispArea.setLayout(dgbl); //dcc.fill = GridBagConstraints.BOTH; dcc.gridx = 0; dcc.gridy = size / 2; dcc.gridwidth = 2; dcc.gridheight = 1; dgbl.setConstraints(pLab, dcc); dispArea.add(pLab); dcc.gridx = 2; dcc.gridy = 1; dcc.gridwidth = 1; dcc.gridheight = size; dgbl.setConstraints(rows, dcc); dispArea.add(rows); dcc.gridx = 3; dcc.gridy = 0; dcc.gridwidth = size; dcc.gridheight = 1; dgbl.setConstraints(columns1, dcc); dispArea.add(columns1); dcc.gridx = 3; dcc.gridy = 1; dcc.gridwidth = size; dcc.gridheight = size; dgbl.setConstraints(pPanel, dcc); dispArea.add(pPanel); dcc.gridx = 0; dcc.gridy = size + 2; dcc.gridwidth = 2; dcc.gridheight = 1; dgbl.setConstraints(wLab, dcc); dispArea.add(wLab); dcc.gridx = 3; dcc.gridy = 1 + size; dcc.gridwidth = size; dcc.gridheight = 1; dgbl.setConstraints(columns2, dcc); dispArea.add(columns2); pMat = new Matrix(P); xMat = Matrix.add(Matrix.subtract(Matrix.identity(size), pMat), Matrix.con(size, size)); zMat = xMat.inverse(); cMat = Matrix.con(1, size); wMat = Matrix.multiply(cMat, zMat); wMat.round(.0001f); dcc.gridx = 3; dcc.gridy = 2 + size; dcc.gridwidth = size; dcc.gridheight = 1; dgbl.setConstraints(wMat, dcc); dispArea.add(wMat); gbl = new GridBagLayout(); controls.setLayout(gbl); cc = new GridBagConstraints(); cc.gridx = 0; cc.gridy = 0; cc.gridwidth = 2; cc.gridheight = 10; gbl.setConstraints(output, cc); controls.add(output); cc.gridx = 0; cc.gridy = 10; cc.gridwidth = 1; cc.gridheight = 1; gbl.setConstraints(numl, cc); controls.add(numl); cc.gridx = 1; cc.gridy = 10; cc.gridwidth = 1; cc.gridheight = 1; gbl.setConstraints(num, cc); controls.add(num); print = new Checkbox("Print"); print.setState(true); cc.gridx = 0; cc.gridy = 11; cc.gridwidth = 2; gbl.setConstraints(print, cc); controls.add(print); cc.gridx = 0; cc.gridy = 12; cc.gridwidth = 2; gbl.setConstraints(go, cc); controls.add(go); myRand = new JRandom(); validate(); } // Handle events public boolean handleEvent(Event evt) { String minStr, maxStr; if (evt.target instanceof Button) { if (evt.target == go && evt.id == Event.ACTION_EVENT) // When button is clicked { simulate(Integer.valueOf(num.getText()).intValue()); return true; // Generate correct number of tosses } } if (evt.id == Event.WINDOW_DESTROY) { hide(); dispose(); } return super.handleEvent(evt); // Handle other events as usual } // Calculate probabilities public void simulate(int num) { dispArea.remove(wMat); pMat = new Matrix(P); float[][] pArr = pMat.toArray(); float total; for (int r = 0; r < pArr.length; r++) { total = 0; for (int c = 0; c < pArr[0].length; c++) { total += pArr[r][c]; } for (int c = 0; c < pArr[0].length; c++) { pArr[r][c] = round(pArr[r][c] / total, .001f); } } for (int r = 0; r < pArr.length; r++) { for (int c = 0; c < pArr[0].length; c++) { P[r][c].setText(String.valueOf(pArr[r][c])); } } pMat = new Matrix(pArr); xMat = Matrix.add(Matrix.subtract(Matrix.identity(size), pMat), Matrix.con(size, size)); zMat = xMat.inverse(); cMat = Matrix.con(1, size); wMat = Matrix.multiply(cMat, zMat); wMat.round(.0001f); dcc.gridx = 3; dcc.gridy = 2 + size; dcc.gridwidth = size; dcc.gridheight = 1; dgbl.setConstraints(wMat, dcc); dispArea.add(wMat); output.setText(""); for (int i = 0; i < size; i++) { count[i] = 0; fraction[i] = 0; } float r; int state = 0; for (int i = 1; i < num; i++) { r = myRand.nextFloat(0, 1); for (int j = 0; j < size; j++) { r -= pMat.toArray()[state][j]; if (r < 0) { state = j; if (print.getState() == true) { output.appendText(names[state]); if (i % 30 == 29) output.appendText("\n"); } j = size; } } count[state]++; } output.appendText("\n\nState Times Fraction\n"); for (int i = 0; i < size; i++) { fraction[i] = round((float) count[i] / (float) num, .001f); output.appendText(names[i] + " " + String.valueOf(count[i]) + " " + String.valueOf(fraction[i]) + "\n"); } validate(); } public float round(float num, float accuracy) { return accuracy * Math.round(num / accuracy); } }