// 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


Back to applet