// CLTIndTrials.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 CLTIndTrials extends java.applet.Applet { Float[] xSpikes; // Variables for simulation Float[] ySpikes; Float[] xLines; Float[] yLines; LineSpikeGraph lsg; // AWT elements Panel dispArea; Panel controls; // Panel for user controls Panel prob; Label numl1, numl2, numl3, numl4, numl5, numl6, numl7; // Controls TextField num1, num2, num3; Label[] pl; TextField[] p; Button go; GridBagLayout gbl, gblp; GridBagConstraints cc, ccp; float[] density; float mean, std; // Initialize applet public void init() { numl1 = new Label("n ="); // Create controls num1 = new TextField("5", 4); numl2 = new Label("kmin ="); // Create controls num2 = new TextField("", 4); numl3 = new Label("kmax ="); // Create controls num3 = new TextField("", 4); numl4 = new Label("exact ="); numl5 = new Label(" "); numl6 = new Label("approx ="); numl7 = new Label(" "); go = new Button("Go"); pl = new Label[10]; p = new TextField[10]; for (int i = 0; i < 10; i++) { pl[i] = new Label("P(" + i + ") ="); p[i] = new TextField("0", 4); } p[1].setText(".2"); p[2].setText(".2"); p[3].setText(".2"); p[4].setText(".2"); p[5].setText(".2"); lsg = new LineSpikeGraph(); // initialize a graphing space dispArea = new Panel(); // Set up window controls = new Panel(); prob = new Panel(); setLayout(new BorderLayout(5, 5)); add("South", controls); add("West", prob); add("Center", dispArea); dispArea.setLayout(new GridLayout(1, 1)); dispArea.add(lsg); gblp = new GridBagLayout(); ccp = new GridBagConstraints(); prob.setLayout(gblp); for (int i = 0; i < 10; i++) { ccp.gridx = 0; ccp.gridy = i; gblp.setConstraints(pl[i], ccp); prob.add(pl[i]); ccp.gridx = 1; gblp.setConstraints(p[i], ccp); prob.add(p[i]); } gbl = new GridBagLayout(); controls.setLayout(gbl); cc = new GridBagConstraints(); cc.gridx = 1; cc.gridy = 0; gbl.setConstraints(numl1, cc); controls.add(numl1); cc.gridx = 2; gbl.setConstraints(num1, cc); controls.add(num1); cc.gridx = 0; cc.gridy = 1; gbl.setConstraints(numl2, cc); controls.add(numl2); cc.gridx = 1; gbl.setConstraints(num2, cc); controls.add(num2); cc.gridx = 2; gbl.setConstraints(numl3, cc); controls.add(numl3); cc.gridx = 3; gbl.setConstraints(num3, cc); controls.add(num3); cc.gridx = 0; cc.gridy = 2; gbl.setConstraints(numl4, cc); controls.add(numl4); cc.gridx = 1; gbl.setConstraints(numl5, cc); controls.add(numl5); cc.gridx = 2; gbl.setConstraints(numl6, cc); controls.add(numl6); cc.gridx = 3; gbl.setConstraints(numl7, cc); controls.add(numl7); cc.gridx = 0; cc.gridy = 3; cc.gridwidth = 4; gbl.setConstraints(go, cc); controls.add(go); 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 { minStr = num2.getText().trim(); maxStr = num3.getText().trim(); if (minStr.length() != 0 && maxStr.length() != 0) simulate(Integer.valueOf(num1.getText()).intValue(), Integer.valueOf(minStr).intValue(), Integer.valueOf(maxStr).intValue()); else if (minStr.length() != 0) simulate(Integer.valueOf(num1.getText()).intValue(), Integer.valueOf(minStr).intValue(), Integer.valueOf(maxStr).intValue()); else simulate(Integer.valueOf(num1.getText()).intValue()); return true; // Generate correct number of tosses } } return super.handleEvent(evt); // Handle other events as usual } public float normal(float x, float mu, float sigma) { return 1 / (sigma * (float) Math.pow(2 * Math.PI, .5)) * (float) Math.pow(Math.E, -1 * Math.pow(x - mu, 2) / (2 * Math.pow((double) sigma, 2))); } public float normalArea(float a, float b) { float mu = 0f; float sigma = 1f; int subdivisions = (int) Math.max(100, 20 * (double) Math.round( (double) b - (double) a + .5)); float dx = (b - a) / (float) subdivisions; float sum = normal(a, mu, sigma) + normal(b, mu, sigma); float x; for (int k = 1; k < subdivisions; k++) { x = a + (float) k * dx; if (k % 2 == 1) sum += 4 * normal(x, mu, sigma); else sum += 2 * normal(x, mu, sigma); } return dx / 3 * sum; } public float[] convolve(float[] d1, float[] d2) { float[] results = new float[d1.length + d2.length - 1]; for (int i = 0; i < results.length; i++) { results[i] = 0; } for (int i = 0; i < d1.length; i++) { for (int j = 0; j < d2.length; j++) { results[i + j] += d1[i] * d2[j]; } } return results; } public float[] getSnDensity(int n, float[] prob) { float[] density = prob; for (int c = 2; c <= n; c++) { density = convolve(density, prob); } return density; } public void setPoints(int num) { float temp; float[] prob = new float[10]; float sum = 0; for (int i = 0; i < 10; i++) { prob[i] = Float.valueOf(p[i].getText()).floatValue(); sum += prob[i]; } for (int i = 0; i < 10; i++) { prob[i] /= sum; p[i].setText(String.valueOf(prob[i])); } density = getSnDensity(num, prob); mean = 0; float variance = 0; for (int k = 0; k < density.length; k++) { mean += k * density[k]; variance += (int) Math.pow((double) k, 2) * density[k]; } variance -= (float) Math.pow((double) mean, 2); std = (float) Math.pow((double) variance, .5); if (std == 0) std = 1 / (num * 9); //?????????????? float xmin = -4f; float xmax = 4f; float dx = (xmax - xmin) / 100f; // +-1 int kmin = (int) Math.floor(Math.max(0, (double) (mean - 4 * std))) + 1; int kmax = (int) Math.ceil(Math.min((double) num * 9, (double) (mean + 4 * std))) - 1; xLines = new Float[101]; yLines = new Float[101]; xSpikes = new Float[kmax - kmin + 1]; ySpikes = new Float[kmax - kmin + 1]; for (int k = kmin; k <= kmax; k++) { xSpikes[k - kmin] = new Float((k - mean) / std); temp = (float) density[k] * std; ySpikes[k - kmin] = new Float(temp); } for (int i = 0; i < 101; i++) { xLines[i] = new Float(xmin + i * dx); yLines[i] = new Float(normal(xmin + i * dx, 0f, 1f)); } } // Calculate probabilities public void simulate(int num) { setPoints(num); dispArea.remove(lsg); lsg = new LineSpikeGraph(xLines, yLines, xSpikes, ySpikes); // Create new LineSpikeGraph dispArea.add(lsg); // Put up the graph validate(); } // Calculate probabilities public void simulate(int num, int min, int max) { setPoints(num); dispArea.remove(lsg); lsg = new LineSpikeGraph(xLines, yLines, xSpikes, ySpikes, ((float) min - mean) / std, ((float) max - mean) / std); // Create new LineSpikeGraph dispArea.add(lsg); // Put up the graph if (min == max) { numl5.setText(String.valueOf(density[min])); numl7.setText(String.valueOf(normal((min - mean) / std, 0f, 1f) / std)); } else { float sum = 0; for (int k = min; k <= max; k++) { sum += density[k]; } int flag = 1; numl5.setText(String.valueOf(sum)); numl7.setText(String.valueOf(normalArea((min - mean) / std - .5f / std * flag, (max - mean) / std + .5f / std * flag))); } validate(); } }