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