// 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();   	}}
