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