// Gauss-Jordan Elimination, coded by David Protas, c.2004 // Any suggestions concerning this code will be appreciated // and should be sent to david.protas@csun.edu // Latest revision: February 19, 2004 import java.applet.*; import java.awt.*; public class RR extends Applet { final int N = 4; Panel top, eq1, eq2, eq3, eq4, side, buttonHolder; Label x11, x12, x13, x14, x21, x22, x23, x24, x31, x32, x33, x34, x41, x42, x43, x44; Label message; TextField a11, a12, a13, a14, b1, a21, a22, a23, a24, b2, a31, a32, a33, a34, b3, a41, a42, a43, a44, b4; TextArea results; Button button; Color babyBlue; boolean stage1 = true, nonsingular = true, solutionExists = true; double[][] a = new double[N][N+1]; int[] leadingOneRow = new int[N]; int fvc; // free variable count public void init() { setLayout(new BorderLayout()); top = new Panel(); top.setLayout(new GridLayout(4,1)); eq1 = new Panel(); eq2 = new Panel(); eq3 = new Panel(); eq4 = new Panel(); x11 = new Label("x_1 + "); x12 = new Label("x_2 + "); x13 = new Label("x_3 + "); x14 = new Label("x_4 = "); x21 = new Label("x_1 + "); x22 = new Label("x_2 + "); x23 = new Label("x_3 + "); x24 = new Label("x_4 = "); x31 = new Label("x_1 + "); x32 = new Label("x_2 + "); x33 = new Label("x_3 + "); x34 = new Label("x_4 = "); x41 = new Label("x_1 + "); x42 = new Label("x_2 + "); x43 = new Label("x_3 + "); x44 = new Label("x_4 = "); a11 = new TextField(3); a12 = new TextField(3); a13 = new TextField(3); a14 = new TextField(3); b1 = new TextField(3); a21 = new TextField(3); a22 = new TextField(3); a23 = new TextField(3); a24 = new TextField(3); b2 = new TextField(3); a31 = new TextField(3); a32 = new TextField(3); a33 = new TextField(3); a34 = new TextField(3); b3 = new TextField(3); a41 = new TextField(3); a42 = new TextField(3); a43 = new TextField(3); a44 = new TextField(3); b4 = new TextField(3); results = new TextArea(" ", 14, 60); results.setEditable(false); message = new Label(" "); button = new Button("Confirm Entries"); buttonHolder = new Panel(); side = new Panel(); side.setLayout(new GridLayout(2,1)); babyBlue = new Color(204,255,255); eq1.add(a11); eq1.add(x11); eq1.add(a12); eq1.add(x12); eq1.add(a13); eq1.add(x13); eq1.add(a14); eq1.add(x14); eq1.add(b1); eq2.add(a21); eq2.add(x21); eq2.add(a22); eq2.add(x22); eq2.add(a23); eq2.add(x23); eq2.add(a24); eq2.add(x24); eq2.add(b2); eq3.add(a31); eq3.add(x31); eq3.add(a32); eq3.add(x32); eq3.add(a33); eq3.add(x33); eq3.add(a34); eq3.add(x34); eq3.add(b3); eq4.add(a41); eq4.add(x41); eq4.add(a42); eq4.add(x42); eq4.add(a43); eq4.add(x43); eq4.add(a44); eq4.add(x44); eq4.add(b4); top.add(eq1); top.add(eq2); top.add(eq3); top.add(eq4); buttonHolder.add(button); side.add(buttonHolder); side.add(message); add("North",top); add("West",side); add("Center",results); setBackground(babyBlue); eq1.setBackground(babyBlue); eq2.setBackground(babyBlue); eq3.setBackground(babyBlue); eq4.setBackground(babyBlue); message.setForeground(Color.red); message.setBackground(babyBlue); results.setFont(new Font("Courier",Font.PLAIN,10)); top.setBackground(babyBlue); side.setBackground(babyBlue); } public boolean action(Event evt, Object arg) { if (evt.target instanceof Button) { String[][] A = new String[4][5]; boolean proceed = true; if (stage1 == true) { A[0][0] = a11.getText(); A[0][1] = a12.getText(); A[0][2] = a13.getText(); A[0][3] = a14.getText(); A[0][4] = b1.getText(); A[1][0] = a21.getText(); A[1][1] = a22.getText(); A[1][2] = a23.getText(); A[1][3] = a24.getText(); A[1][4] = b2.getText(); A[2][0] = a31.getText(); A[2][1] = a32.getText(); A[2][2] = a33.getText(); A[2][3] = a34.getText(); A[2][4] = b3.getText(); A[3][0] = a41.getText(); A[3][1] = a42.getText(); A[3][2] = a43.getText(); A[3][3] = a44.getText(); A[3][4] = b4.getText(); for (int i = 0; i < N; i++) for (int j = 0; j < N+1; j++) if (entryValid(A[i][j]) == false) proceed = false; if (proceed == true) { fvc = 0; for (int i = 0; i < N; i++) { leadingOneRow[i] = -1; for (int j = 0; j < N+1; j++) a[i][j] = doubleFromString(A[i][j]); } results.setText("Augmented matrix "); printMatrix(a); message.setText(""); stage1 = false; button.setLabel("Row Reduce"); } //end of if proceed true else message.setText("Invalid entry."); } //end of if stage1 = true else { for (int k = 0; k < N-1; k++) { partialPivot(a, k, fvc); rowReduce(a, k, fvc); if (a[k-fvc][k] == 0) { fvc++; } } if (fvc > 0) { partialPivot(a, N-1, fvc); } rowReduce(a, N-1, fvc); for (int k = N-1; k > 0; k--) { if (leadingOneRow[k] > 0) { backSubstitute(a, k); } } presentSolution(a); button.setLabel("Confirm Entries"); stage1 = true; } //end of if stage1 == false return true; } //end of if evt.target return false; } // end of action private void partialPivot(double[][] entry, int k, int c) { int ti; double[] rowMax = new double[N]; double[] tempRow = new double[N+1]; for (int i = k-c; i < N; i++) { rowMax[i] = 0; for (int j = k+1; j < N+1; j++) { rowMax[i] = Math.max(Math.abs(rowMax[i]),Math.abs(entry[i][j])); } } ti = k-c; for (int i = k-c+1; i < N; i++) { if ((Math.abs(entry[i][k])*rowMax[ti] >= Math.abs(entry[ti][k])*rowMax[i]) && (entry[i][k] != 0)) { ti = i; } } tempRow = entry[k-c]; entry[k-c] = entry[ti]; entry[ti] = tempRow; results.appendText("\n" + "Rows arranged for pivot #" + (k-c+1)); printMatrix(entry); } private void rowReduce(double[][] entry, int k, int c) { if (entry[k-c][k] != 0) { double temp; temp = entry[k-c][k]; for (int j = k; j < N+1; j++) { entry[k-c][j] = entry[k-c][j]/temp; } leadingOneRow[k] = k-c; results.appendText("\n" + "Leading 1 placed in column " + (k+1)); if ((k == N-1) && (c == 0)) { results.appendText("\n" + "Row Echelon Form"); } printMatrix(entry); if (k-c < N-1) { for (int i = k-c+1; i < N; i++) { temp = entry[i][k]; for (int j = k; j < N+1; j++) { entry[i][j] = entry[i][j] - temp*entry[k-c][j]; } } results.appendText("\n" + "0's placed below leading 1 in column " + (k+1)); if ((k == N-1) && (c == 1)) { results.appendText("\n" + "Row Echelon Form"); } printMatrix(entry); } } else { nonsingular = false; results.appendText("\n" + "No leading 1 possible for column " + (k+1) + "\n" + "Moving on to next column" + "\n"); } } private void backSubstitute(double[][] entry, int k) { double temp; for (int i = leadingOneRow[k]-1; i > -1; i--) { temp = entry[i][k]; for (int j = k; j < N+1; j++) { entry[i][j] = entry[i][j] - temp*entry[leadingOneRow[k]][j]; } } results.appendText("\n" + "0's placed above leading 1 in column " + (k+1)); if (leadingOneRow[k] == 1) { results.appendText("\n" + "Reduced Row Echelon Form"); } printMatrix(entry); } private void presentSolution(double[][] entry) { double[] coeffRowMax = new double[N]; if (nonsingular == true) { results.appendText("\n" + "The solution is: " + "\n" + "x_1 = " + rndOff(entry[0][N]) + "\n" + "x_2 = " + rndOff(entry[1][N]) + "\n" + "x_3 = " + rndOff(entry[2][N]) + "\n" + "x_4 = " + rndOff(entry[3][N])); } else { for (int i = 0; i < N; i++) { coeffRowMax[i] = 0; for (int j = i; j < N; j++) { coeffRowMax[i] = Math.max(Math.abs(coeffRowMax[i]),Math.abs(entry[i][j])); } if ((coeffRowMax[i] == 0) && (entry[i][N] != 0)) { solutionExists = false; } } if (solutionExists == true) { String line; results.appendText("\n" + "The solutions are: "); for (int k = 0; k < N; k++) { if (leadingOneRow[k] == -1) { results.appendText("\n" + "x_" + (k+1) + " = " + "r_" + (k+1)); } else { line = "x_" + (k+1) + " = "; for (int j = 0; j < N; j++) { if ((leadingOneRow[j] == -1) && (entry[leadingOneRow[k]][j] != 0)) { line = line + rndOff(-entry[leadingOneRow[k]][j]) + "r_" + (j+1) + " + "; } } line = line + rndOff(entry[leadingOneRow[k]][N]); results.appendText("\n" + line); } } } else { results.appendText("\n" + "No solution"); solutionExists = true; } } } private void printMatrix(double[][] entry) { for (int i = 0; i < N; i++) { results.appendText("\n" + rndOff(entry[i][0]) + " " + rndOff(entry[i][1]) + " " + rndOff(entry[i][2]) + " " + rndOff(entry[i][3]) + " " + rndOff(entry[i][4])); } results.appendText("\n"); } public static double doubleFromString(String str) { Double doubleObj = new Double(str); return doubleObj.doubleValue(); } public static String rndOff(double number) //to 5 places past the decimal { String strnum, bigstrnum, substrnum = " 0.00000"; int period, lngth; long longnum; if ((number >= 0.001) || (number <= -0.001)) { number = Math.pow(0.1,5)*Math.round(Math.pow(10,5)*number); strnum = String.valueOf(number); bigstrnum = " " + strnum + " "; period = bigstrnum.indexOf('.'); substrnum = bigstrnum.substring(period -4, period + 6); } else { longnum = Math.round(Math.pow(10,5)*number); if (longnum == 0) substrnum = " 0.00000"; else { strnum = String.valueOf(longnum); if (longnum < 0) strnum = strnum.substring(1); lngth = strnum.length(); switch (lngth) { case 1: substrnum = " 0.0000" + strnum; break; case 2: substrnum = " 0.000" + strnum; break; default: substrnum = " error"; } if (longnum < 0) substrnum = " -" + substrnum.substring(3); } } return substrnum; } private boolean entryValid(String entry) { boolean status; try { double number = doubleFromString(entry); status = true; } catch(NumberFormatException e) { status = false; } return status; } } //end of RR