// ErgodicWindow.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 ErgodicWindow	extends java.awt.Frame{	Panel dispArea;	Panel controls;		// Panel for user controls	Panel pPanel;		TextField[][] P;	Matrix pMat, wMat, rMat, zMat, mMat, xMat, tMat, cMat;	float[][] rls;	float[][] cls;	Matrix rows1, rows2, rows3, cols1, cols2, cols3, cols4, cols5;	Label pLab, wLab, zLab, rLab, mLab;		Button go;		GridBagLayout gbl, pgbl, dgbl;	GridBagConstraints cc, pcc, dcc;		int size;		Color labC;		public ErgodicWindow(int n) {		super("ErgodicChain");		size = n;	}			// Initialize applet	public void init()	{			go = new Button("Go");				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 == 5) {			P = new TextField[5][5];			P[0][0] = new TextField("0", 4);			P[0][1] = new TextField("1", 4);			P[0][2] = new TextField("0", 4);			P[0][3] = new TextField("0", 4);			P[0][4] = new TextField("0", 4);			P[1][0] = new TextField(".25", 4);			P[1][1] = new TextField("0", 4);			P[1][2] = new TextField(".75", 4);			P[1][3] = new TextField("0", 4);			P[1][4] = new TextField("0", 4);			P[2][0] = new TextField("0", 4);			P[2][1] = new TextField(".5", 4);			P[2][2] = new TextField("0", 4);			P[2][3] = new TextField(".5", 4);			P[2][4] = new TextField("0", 4);			P[3][0] = new TextField("0", 4);			P[3][1] = new TextField("0", 4);			P[3][2] = new TextField(".75", 4);			P[3][3] = new TextField("0", 4);			P[3][4] = new TextField(".25", 4);			P[4][0] = new TextField("0", 4);			P[4][1] = new TextField("0", 4);			P[4][2] = new TextField("0", 4);			P[4][3] = new TextField("1", 4);			P[4][4] = new TextField("0", 4);		}		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);				}			}		}					pLab = new Label("P = ");		pLab.setAlignment(Label.RIGHT);		wLab = new Label("w = ");		wLab.setAlignment(Label.RIGHT);		zLab = new Label("Z = ");		zLab.setAlignment(Label.RIGHT);		rLab = new Label("r = ");		rLab.setAlignment(Label.RIGHT);		mLab = new Label("M = ");		mLab.setAlignment(Label.RIGHT);				labC = new Color(100, 0, 0);				rows1 = new Matrix(rls);		rows1.setColor(labC);		rows2 = new Matrix(rls);		rows2.setColor(labC);		rows3 = new Matrix(rls);		rows3.setColor(labC);		cols1 = new Matrix(cls);		cols1.setColor(labC);		cols2 = new Matrix(cls);		cols2.setColor(labC);		cols3 = new Matrix(cls); 		cols3.setColor(labC);		cols4 = new Matrix(cls);		cols4.setColor(labC);		cols5 = new Matrix(cls);		cols5.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.weightx = 1.0;		//dcc.weighty = 1.0;				dcc.gridx = 0;		dcc.gridy = 3;		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(rows1, dcc);		dispArea.add(rows1);				dcc.gridx = 3;		dcc.gridy = 0;		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(cols1, dcc);		dispArea.add(cols1);				dcc.gridx = 3;		dcc.gridy = 1;		dcc.gridwidth = size;		dcc.gridheight = size;		dgbl.setConstraints(pPanel, dcc);		dispArea.add(pPanel);				dcc.gridx = 3 + size;		dcc.gridy = 1;		dcc.gridwidth = 2;			dcc.gridheight = 1;		dgbl.setConstraints(wLab, dcc);		dispArea.add(wLab);				dcc.gridx = 6 + size;		dcc.gridy = 0;		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(cols2, dcc);		dispArea.add(cols2);				dcc.gridx = 3 + size;		dcc.gridy = 3;		dcc.gridwidth = 2;		dcc.gridheight = 1;		dgbl.setConstraints(rLab, dcc);		dispArea.add(rLab);				dcc.gridx = 6 + size;		dcc.gridy = 2;		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(cols3, dcc);		dispArea.add(cols3);				dcc.gridx = 0;		dcc.gridy = 2 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = 2;		dcc.gridheight = 1;		dgbl.setConstraints(zLab, dcc);		dispArea.add(zLab);				dcc.gridx = 2;		dcc.gridy = 2 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = 1;		dcc.gridheight = size;		dgbl.setConstraints(rows2, dcc);		dispArea.add(rows2);				dcc.gridx = 3;		dcc.gridy = 1 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(cols4, dcc);		dispArea.add(cols4);				dcc.gridx = 3 + size;		dcc.gridy = 2 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = 2;			dcc.gridheight = 1;		dgbl.setConstraints(mLab, dcc);		dispArea.add(mLab);				dcc.gridx = 5 + size;		dcc.gridy = 2 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = 1;		dcc.gridheight = size;		dgbl.setConstraints(rows3, dcc);		dispArea.add(rows3);				dcc.gridx = 6 + size;		dcc.gridy = 1 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(cols5, dcc);		dispArea.add(cols5);				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);		mMat = Matrix.zer(size, size);		rMat = Matrix.zer(1, size);		for (int r = 0; r < size; r++) {			for (int c = 0; c < size; c++) {				mMat.matVals[r][c] = new Float((zMat.toArray()[c][c] - 					zMat.toArray()[r][c]) / wMat.toArray()[0][c]);				}			rMat.matVals[0][r] = new Float(1f / wMat.toArray()[0][r]);			}		tMat = Matrix.zer(size, size);		xMat = Matrix.subtract(Matrix.identity(size), pMat);		for (int r = 0; r < size; r++) {			for (int c = 0; c < size; c++) {				tMat.matVals[r][c] = new Float(wMat.matVals[0][c].floatValue());			}		}		xMat = Matrix.add(xMat, tMat);		zMat = xMat.inverse();		// Z is in fact the inverse of (I - P) + fixedvector matrix		wMat.round(.001f);		zMat.round(.001f);		rMat.round(.001f);		mMat.round(.001f);				dcc.gridx = 6 + size;		dcc.gridy = 1;		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(wMat, dcc);		dispArea.add(wMat);				dcc.gridx = 6 + size;		dcc.gridy = 3;		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(rMat, dcc);		dispArea.add(rMat);				dcc.gridx = 3;		dcc.gridy = 2 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = size;		dcc.gridheight = size;		dgbl.setConstraints(zMat, dcc);		dispArea.add(zMat);				dcc.gridx = 6 + size;		dcc.gridy = 2 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(mMat, dcc);		dispArea.add(mMat);				gbl = new GridBagLayout();		controls.setLayout(gbl);				cc = new GridBagConstraints();				cc.gridx = 0;		cc.gridy = 0;		cc.gridwidth = 2;		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			{        		simulate();        		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()    {	    	dispArea.remove(wMat);    	dispArea.remove(zMat);    	dispArea.remove(rMat);    	dispArea.remove(mMat);    	    	pMat = new Matrix(P);		float[][] qArr = pMat.toArray();		float total;		for (int r = 0; r < qArr.length; r++) {			total = 0;			for (int c = 0; c < qArr[0].length; c++) {				total += qArr[r][c];			}				for (int c = 0; c < qArr[0].length; c++) {				qArr[r][c] = round(qArr[r][c] / total, .001f);			}				}				for (int r = 0; r < qArr.length; r++) {			for (int c = 0; c < qArr[0].length; c++) {				P[r][c].setText(String.valueOf(qArr[r][c]));			}			}				pMat = new Matrix(qArr);				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);		mMat = Matrix.zer(size, size);		rMat = Matrix.zer(1, size);		for (int r = 0; r < size; r++) {			for (int c = 0; c < size; c++) {				mMat.matVals[r][c] = new Float((zMat.toArray()[c][c] - 					zMat.toArray()[r][c]) / wMat.toArray()[0][c]);				}			rMat.matVals[0][r] = new Float(1f / wMat.toArray()[0][r]);			}		tMat = Matrix.zer(size, size);		xMat = Matrix.subtract(Matrix.identity(size), pMat);		for (int r = 0; r < size; r++) {			for (int c = 0; c < size; c++) {				tMat.matVals[r][c] = new Float(wMat.matVals[0][c].floatValue());			}		}		xMat = Matrix.add(xMat, tMat);		zMat = xMat.inverse();				// Z is defined twice???????		wMat.round(.001f);		zMat.round(.001f);		rMat.round(.001f);		mMat.round(.001f);				dcc.gridx = 6 + size;		dcc.gridy = 1;		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(wMat, dcc);		dispArea.add(wMat);				dcc.gridx = 6 + size;		dcc.gridy = 3;		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(rMat, dcc);		dispArea.add(rMat);				dcc.gridx = 3;		dcc.gridy = 2 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = size;		dcc.gridheight = size;		dgbl.setConstraints(zMat, dcc);		dispArea.add(zMat);				dcc.gridx = 6 + size;		dcc.gridy = 2 + (int) Math.max((double) size, (double) 4);		dcc.gridwidth = size;		dcc.gridheight = 1;		dgbl.setConstraints(mMat, dcc);		dispArea.add(mMat);    	   	 	validate();	}		public float round(float num, float accuracy) {		return accuracy * Math.round(num / accuracy);	}	}
