Matrix Applet
<< Guassian Elimination | OtherProjectsTrailIndex | Determinant >>
Download the Application MatrixApp.jar
Download the Java Web Start application here
Rational.java
public class Rational { private int numerator; private int denominator; public Rational(String s){ int fBar=s.indexOf("/"); if (fBar==-1){ numerator=Integer.parseInt(s); denominator=1; } else { numerator=Integer.parseInt(s.substring(0,fBar)); denominator=Integer.parseInt(s.substring(fBar+1)); simplify(); } } public Rational(int n, int d){ numerator=n; denominator=d; simplify(); } public Rational(int n){ numerator=n; denominator=1; } public Rational(){ numerator=0; denominator=1; } public Rational (Rational r){ this.numerator=r.getNumerator(); this.denominator=r.getDenominator(); } public void setNumerator(int numerator) { this.numerator = numerator; } public int getNumerator() { return numerator; } public void setDenominator(int denominator) { this.denominator = denominator; } public int getDenominator() { return denominator; } public double value(){ return (double)(numerator)/denominator; } public Rational reciprocal(){ return new Rational(this.getDenominator(),this.getNumerator()); } public String toString(){ if (denominator ==1) return Integer.toString(numerator); return Integer.toString(numerator)+"/"+Integer.toString(denominator); } public String toString(int n){ String result= Integer.toString(numerator)+"/"+Integer.toString(denominator); if (denominator ==1) result= Integer.toString(numerator); while (result.length()<n) result=" "+result; return result; } public Rational multiply(Rational other){ int n=this.getNumerator()*other.getNumerator(); int d=this.getDenominator()*other.getDenominator(); Rational result=new Rational(n,d); return result; } public Rational add(Rational other){ int n=this.getNumerator()*other.getDenominator()+ other.getNumerator()*this.getDenominator(); int d=this.getDenominator()*other.getDenominator(); Rational result=new Rational(n,d); return result; } public void simplify(){ int p=2; if (denominator<0){ numerator*=-1; denominator*=-1; } while (p<= Math.max(numerator, denominator)){ while(numerator%p==0 && denominator%p==0){ numerator/=p; denominator/=p; } if (p==2) p++; else p+=2; } if (numerator==0 ) denominator=1; if (numerator==denominator ){ denominator=1; numerator=1; } } }
Matrix.java
public class Matrix { private int rows; private int cols; Rational[][] m; public Matrix(int r, int c){ rows=r; cols=c; m=new Rational[rows][cols]; for(int i=0;i<rows;i++) for(int j=0;j<cols;j++){ m[i][j]=new Rational(); } } public Matrix(Matrix o){ rows=o.getRows(); cols=o.getCols(); m=new Rational[rows][cols]; for(int i=0;i<rows;i++) for(int j=0;j<cols;j++){ m[i][j]=o.get(i, j); } } public Matrix(String s){ String[] r=s.split("\n"); rows = r.length; String[] c=r[0].split(" "); cols = c.length; m=new Rational[rows][cols]; for(int i=0;i<rows;i++){ c=r[i].split(" "); cols = c.length; for (int j=0;j<cols;j++){ this.set(i, j, new Rational(c[j])); } } } public int getRows(){ return rows; } public int getCols(){ return cols; } public void set(int r, int c, Rational q){ m[r][c]=q; } public Rational get(int r, int c){ return m[r][c]; } public String toString(){ String result=""; for (int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ result+=m[i][j].toString()+" "; } result+="\n"; } return result; } public String toString(int n){ String result=""; for (int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ result+=m[i][j].toString(n); } result+="\n"; } return result; } public void swap(int row1, int row2) { for (int j=0; j<cols;j++){ Rational q=this.get(row1, j); this.set(row1, j, this.get(row2, j)); this.set(row2, j, q); } } public void multiply(int row, Rational number) { for (int j=0; j<cols;j++){ Rational q = number.multiply(this.get(row, j)); this.set(row, j, q); } } public void addMultiple(int row1, Rational number, int row2) { for (int j=0; j<cols;j++){ Rational q = number.multiply(this.get(row1, j)); q=q.add(this.get(row2, j)); this.set(row2, j, q); } } /** * * @return determinant or null if matrix is not square */ public Rational det(){ if (rows!=cols) return null; return det(this); } public Rational det(Matrix m1){ if (m1.getRows()==1) return m1.get(0, 0); Rational result = new Rational(0); for(int j=0;j<m1.getCols();j++){ Rational cofactor=new Rational((int)Math.pow(-1, j)); cofactor=cofactor.multiply(m1.get(0, j)); cofactor=cofactor.multiply(det(m1.minor(0,j))); result=result.add(cofactor); } return result; } public Matrix minor(int r, int c){ Matrix result= new Matrix(this.rows-1, this.cols-1); //top for (int i=0; i<r;i++){ //left for (int j=0; j<c; j++){ result.set(i, j, this.get(i, j)); } //right for (int j=c+1; j<cols;j++) result.set(i, j-1, this.get(i, j)); } //bottom for(int i=r+1; i<rows;i++){ //left for (int j=0; j<c;j++) result.set(i-1,j,this.get(i, j)); //right for (int j=c+1; j<cols;j++) result.set(i-1, j-1, this.get(i, j)); } return result; } /** * for rref, we mult 1/n to the leading coeff * then add -1*the number below and add this multiple to * it untill there is no other */ public void rref(){ if (rows<2) return; for (int i=0; i<rows; i++){ Rational r=this.get(i, i); if (r.value()!=0){ r=r.reciprocal(); } else if(i!=rows-1){ this.swap(i, i+1); r=this.get(i, i); if (r.value()!=0) r=r.reciprocal(); } this.multiply(i, r); for (int k=i+1;k<rows; k++){ Rational q=this.get(k, i); q=q.multiply(new Rational(-1)); this.addMultiple(i, q, k); } } for(int i=rows-1; i>=0; i--){ Rational r=this.get(i, i); for (int k=i-1; k>=0; k--){ Rational q=this.get(k, i); q=q.multiply(new Rational(-1)); this.addMultiple(i, q, k); } } } }
MatrixApp.java
import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Frame; import java.awt.Panel; import java.awt.TextArea; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; @SuppressWarnings("serial") public class MatrixApp extends Frame implements ActionListener{ TextArea t; Button editButton,detButton, invButton, rrefButton,swapButton, multButton, addButton, undoButton; int rows,cols; Matrix a,b; final int WIDTH=7; //making these global will 'remember' the order of the last matrix JTextField r=new JTextField("2"); JTextField c=new JTextField("2"); public MatrixApp(){ super("Matrix App 1.0"); setSize(800,600); this.addWindowListener( new WindowListener() { public void windowClosing(WindowEvent e) {System.exit(0);} public void windowClosed(WindowEvent e) {} public void windowOpened(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} }); t=new TextArea(); t.setFont(new Font("Courier", Font.BOLD,20)); t.setForeground(new Color(251,182,0)); t.setBackground(new Color(44,23,0)); t.setEditable(false); rows=2; cols=2; a=new Matrix(2,2); parseMatrix(identityString(2,2)); b=new Matrix(a); editButton=new Button("Edit Matrix"); editButton.addActionListener(this); detButton=new Button("Determinant"); detButton.addActionListener(this); invButton=new Button("Inverse"); invButton.addActionListener(this); rrefButton=new Button("rref"); rrefButton.addActionListener(this); swapButton=new Button("Swap"); swapButton.addActionListener(this); multButton=new Button("Multiply"); multButton.addActionListener(this); addButton=new Button("Add a Multiple"); addButton.addActionListener(this); undoButton=new Button("Undo"); undoButton.addActionListener(this); this.setLayout(new BorderLayout()); this.add(t, BorderLayout.CENTER); Panel buttonPanel=new Panel(new FlowLayout()); buttonPanel.add(editButton); buttonPanel.add(detButton); buttonPanel.add(invButton); buttonPanel.add(swapButton); buttonPanel.add(multButton); buttonPanel.add(addButton); buttonPanel.add(rrefButton); buttonPanel.add(undoButton); this.add(buttonPanel, BorderLayout.NORTH); } public static void main(String[] args) { MatrixApp app= new MatrixApp(); app.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { Object buttonPressed=e.getSource(); if (buttonPressed==editButton){ doEditDialog(); t.append("\n"); } else if(buttonPressed==swapButton){ doSwapDialog(); t.append("\n"); } else if(buttonPressed==detButton){ if (a.getRows()!=a.getCols()) t.append("The determinent is undefined for non-square matrices\n"); else t.append("The Determinant is "+a.det()+"\n"); } else if(buttonPressed==invButton){ if (a.getRows()!=a.getCols()) t.append("This matrix is not square\n"); else if (a.det().value()==0){ t.append("This matrix is singular\n"); } else { t.append("The Inverse of this matrix is \n"+Matrix.inverse(a).toString(WIDTH)+"\n"); } } else if(buttonPressed==multButton){ doMultDialog(); t.append("\n"); } else if(buttonPressed==rrefButton){ Matrix d=new Matrix(a); d.rref(); t.append("The row reduced echelon form of this matrix is\n"+d.toString(WIDTH)+"\n"); } else if(buttonPressed==addButton){ doAddDialog(); t.append("\n"); } else if(buttonPressed==undoButton){ Matrix c=new Matrix(a); a=new Matrix(b); b=new Matrix(c); t.append("Undo selected\n"+a.toString(WIDTH)); } } public String identityString(int r, int c){ String result=""; for (int i=0;i<r;i++){ for (int j=0; j<c;j++){ if (i==j) result+="1 "; else result+="0 "; } result+="\n"; } return result; } public void doEditDialog(){ final JComponent[] order = new JComponent[] { new JLabel("rows: "), r, new JLabel("cols: "), c, }; JOptionPane.showMessageDialog(this, order, "Order of Matrix", JOptionPane.PLAIN_MESSAGE); try{ rows=Integer.parseInt(r.getText()); cols=Integer.parseInt(c.getText()); doMatrixDialog(); t.append("\n"); }catch( Exception exception){ t.append("\nHuh? try again - only one space between columns"); } } public void doSwapDialog(){ JTextField r1=new JTextField("1"); JTextField r2=new JTextField("2"); final JComponent[] swap = new JComponent[] { new JLabel("Swap row: "), r1, new JLabel("with row: "), r2, }; JOptionPane.showMessageDialog(this, swap, "Swap 2 Rows", JOptionPane.PLAIN_MESSAGE); int row1,row2; try{ row1=Integer.parseInt(r1.getText()); row2=Integer.parseInt(r2.getText()); b=new Matrix(a); a.swap(row1-1,row2-1); t.append("r"+row1+" <-> r"+row2+"\n"+a.toString(WIDTH)); }catch( Exception exception){ t.append("\nCan't swap those rows. Try again\n"); } } public void doMultDialog(){ JTextField r=new JTextField("1"); JTextField q=new JTextField("1"); final JComponent[] mult = new JComponent[] { new JLabel("Multiply row: "), r, new JLabel("by what number: "), q, }; JOptionPane.showMessageDialog(this, mult, "Multiply a Row", JOptionPane.PLAIN_MESSAGE); int row; Rational number; try{ row=Integer.parseInt(r.getText()); number=new Rational(q.getText()); b=new Matrix(a); a.multiply(row-1, number); t.append("R"+row+" = "+number.toString()+" * r"+row+"\n"+a.toString(WIDTH)); }catch( Exception exception){ t.append("\nSomething is wrong: bad row or malformed number. Try again\n"); } } public void doAddDialog(){ JTextField r1=new JTextField("1"); JTextField q=new JTextField("1"); JTextField r2=new JTextField("2"); final JComponent[] addDialog = new JComponent[] { new JLabel("Multiply row: "), r1, new JLabel("by what number: "), q, new JLabel("and add it to what row: "), r2, }; JOptionPane.showMessageDialog(this, addDialog, "Add a Multiple of a Row and Add it to Another Row", JOptionPane.PLAIN_MESSAGE); int row1, row2; Rational number; try{ row1=Integer.parseInt(r1.getText()); row2=Integer.parseInt(r2.getText()); number=new Rational(q.getText()); b=new Matrix(a); a.addMultiple(row1-1, number, row2-1); t.append("R"+row2+" = "+number.toString()+" * r"+row1+" + r"+row2+"\n"+a.toString(WIDTH)); }catch( Exception exception){ t.append("\nSomething is wrong: bad row or malformed number. Try again\n"); } } public void doMatrixDialog(){ String sample=identityString(rows,cols); if (rows==a.getRows()&&cols==a.getCols()) sample=a.toString(); Object[] o=new Object[1]; TextArea m=new TextArea(sample); m.setFont(new Font("Courier", Font.BOLD,20)); o[0]=m; int res = JOptionPane.showConfirmDialog(this, o, "Enter Matrix Values (separate columns with a single space)", JOptionPane.OK_CANCEL_OPTION); if (res == JOptionPane.CANCEL_OPTION) return; parseMatrix(m.getText()); } public void parseMatrix(String s){ b=new Matrix(a); a=new Matrix(rows,cols); t.setText("Order of this matrix is "+rows+" x "+cols+"\n"); String[] r=s.split("\n"); for(int i=0;i<rows;i++){ String[] c=r[i].split(" "); for (int j=0;j<cols;j++){ a.set(i, j, new Rational(c[j])); } } t.append(a.toString(WIDTH)); t.append("\n"); } }
MatrixApplet.java
import java.applet.Applet; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Panel; import java.awt.TextArea; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.JTextField; @SuppressWarnings("serial") public class MatrixApplet extends Applet implements ActionListener{ TextArea t; Button editButton,detButton,swapButton, multButton, addButton, undoButton; int rows,cols; Matrix a,b; final int WIDTH=7; //making these global will 'remember' the order of the last matrix JTextField r=new JTextField("2"); JTextField c=new JTextField("2"); public void init(){ t=new TextArea(); t.setFont(new Font("Courier", Font.BOLD,20)); t.setForeground(new Color(251,182,0)); t.setBackground(new Color(44,23,0)); t.setEditable(false); rows=2; cols=2; a=new Matrix(2,2); parseMatrix(identityString(2,2)); b=new Matrix(a); editButton=new Button("Edit Matrix"); editButton.addActionListener(this); detButton=new Button("Determinant"); detButton.addActionListener(this); swapButton=new Button("Swap"); swapButton.addActionListener(this); multButton=new Button("Multiply"); multButton.addActionListener(this); addButton=new Button("Add a Multiple"); addButton.addActionListener(this); undoButton=new Button("Undo"); undoButton.addActionListener(this); this.setLayout(new BorderLayout()); this.add(t, BorderLayout.CENTER); Panel buttonPanel=new Panel(new FlowLayout()); buttonPanel.add(editButton); buttonPanel.add(detButton); buttonPanel.add(swapButton); buttonPanel.add(multButton); buttonPanel.add(addButton); buttonPanel.add(undoButton); this.add(buttonPanel, BorderLayout.NORTH); } @Override public void actionPerformed(ActionEvent e) { Object buttonPressed=e.getSource(); if (buttonPressed==editButton){ doEditDialog(); t.append("\n"); } else if(buttonPressed==swapButton){ doSwapDialog(); t.append("\n"); }else if(buttonPressed==detButton){ if (a.getRows()!=a.getCols()) t.append("The determinent is undefined for non-square matrices\n"); else t.append("The Determinant is "+a.det()+"\n"); } else if(buttonPressed==multButton){ doMultDialog(); t.append("\n"); } else if(buttonPressed==addButton){ doAddDialog(); t.append("\n"); } else if(buttonPressed==undoButton){ Matrix c=new Matrix(a); a=new Matrix(b); b=new Matrix(c); t.append("Undo selected\n"+a.toString(WIDTH)); } } public String identityString(int r, int c){ String result=""; for (int i=0;i<r;i++){ for (int j=0; j<c;j++){ if (i==j) result+="1 "; else result+="0 "; } result+="\n"; } return result; } public void doEditDialog(){ final JComponent[] order = new JComponent[] { new JLabel("rows: "), r, new JLabel("cols: "), c, }; JOptionPane.showMessageDialog(this, order, "Order of Matrix", JOptionPane.PLAIN_MESSAGE); try{ rows=Integer.parseInt(r.getText()); cols=Integer.parseInt(c.getText()); doMatrixDialog(); t.append("\n"); }catch( Exception exception){ t.append("\nHuh? try again - only one space between columns"); } } public void doSwapDialog(){ JTextField r1=new JTextField("1"); JTextField r2=new JTextField("2"); final JComponent[] swap = new JComponent[] { new JLabel("Swap row: "), r1, new JLabel("with row: "), r2, }; JOptionPane.showMessageDialog(this, swap, "Swap 2 Rows", JOptionPane.PLAIN_MESSAGE); int row1,row2; try{ row1=Integer.parseInt(r1.getText()); row2=Integer.parseInt(r2.getText()); b=new Matrix(a); a.swap(row1-1,row2-1); t.append("r"+row1+" <-> r"+row2+"\n"+a.toString(WIDTH)); }catch( Exception exception){ t.append("\nCan't swap those rows. Try again\n"); } } public void doMultDialog(){ JTextField r=new JTextField("1"); JTextField q=new JTextField("1"); final JComponent[] mult = new JComponent[] { new JLabel("Multiply row: "), r, new JLabel("by what number: "), q, }; JOptionPane.showMessageDialog(this, mult, "Multiply a Row", JOptionPane.PLAIN_MESSAGE); int row; Rational number; try{ row=Integer.parseInt(r.getText()); number=new Rational(q.getText()); b=new Matrix(a); a.multiply(row-1, number); t.append("R"+row+" = "+number.toString()+" * r"+row+"\n"+a.toString(WIDTH)); }catch( Exception exception){ t.append("\nSomething is wrong: bad row or malformed number. Try again\n"); } } public void doAddDialog(){ JTextField r1=new JTextField("1"); JTextField q=new JTextField("1"); JTextField r2=new JTextField("2"); final JComponent[] addDialog = new JComponent[] { new JLabel("Multiply row: "), r1, new JLabel("by what number: "), q, new JLabel("and add it to what row: "), r2, }; JOptionPane.showMessageDialog(this, addDialog, "Add a Multiple of a Row and Add it to Another Row", JOptionPane.PLAIN_MESSAGE); int row1, row2; Rational number; try{ row1=Integer.parseInt(r1.getText()); row2=Integer.parseInt(r2.getText()); number=new Rational(q.getText()); b=new Matrix(a); a.addMultiple(row1-1, number, row2-1); t.append("R"+row2+" = "+number.toString()+" * r"+row1+" + r"+row2+"\n"+a.toString(WIDTH)); }catch( Exception exception){ t.append("\nSomething is wrong: bad row or malformed number. Try again\n"); } } public void doMatrixDialog(){ String sample=identityString(rows,cols); if (rows==a.getRows()&&cols==a.getCols()) sample=a.toString(); Object[] o=new Object[1]; TextArea m=new TextArea(sample); m.setFont(new Font("Courier", Font.BOLD,20)); o[0]=m; int res = JOptionPane.showConfirmDialog(this, o, "Enter Matrix Values (separate columns with a single space)", JOptionPane.OK_CANCEL_OPTION); if (res == JOptionPane.CANCEL_OPTION) return; parseMatrix(m.getText()); } public void parseMatrix(String s){ b=new Matrix(a); a=new Matrix(rows,cols); t.setText("Order of matrix is "+rows+" x "+cols+"\n"); String[] r=s.split("\n"); for(int i=0;i<rows;i++){ String[] c=r[i].split(" "); for (int j=0;j<cols;j++){ a.set(i, j, new Rational(c[j])); } } t.append(a.toString(WIDTH)); t.append("\n"); } }