Sunday, January 16, 2011

Matrix Multiplication using Threads.

In general Matrix Multiplication requires m*n*r steps where the First Matrix is m*n, the second n*r and the result matrix m*r. However, realizing that the calculation of all the m*r entries of the result matrix are independent of each other we can do these calculations in parallel. In this application I have tried to contrast both these methods. The savings are pretty dramatic as the size of the matrices is increased. If the Threads were to be run on different processors the savings should be even more dramatic.


This application has two parts Main.java & MatrixMultiplicationForm.java

Main.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package threadedmatrixmultiplication;


public class Main {

    /**
     * @param args the command line arguments
     */
       public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MatrixMultiplicationForm().setVisible(true);
            }
        });
    }

}


MatrixMultiplicationForm.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MatrixMultiplicationForm.java
 *
 * Created on Jan 15, 2011, 8:57:03 PM
 */

package threadedmatrixmultiplication;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MatrixMultiplicationForm extends javax.swing.JFrame {

    private long t1,t2;
    private int NoofThread;
    private class MultiplyThread extends Thread
    {
    private int i,k,n;
    public MultiplyThread(int i,int k,int n)
    {
        this.i=i;
        this.k=k;
        this.n=n;
    }
    //**************************************************************@Override
    private synchronized void reduce()
    {
        NoofThread--;
        if(NoofThread<=0)
            t2=new java.util.Date().getTime();
        l2.setText("Thread Time = " + (t2-t1));
    }
    @Override
    public void run()
    {
        m3[i][k].setText("0");
        for(int j=0;j<=n-1;j++)
            m3[i][k].setText("" + (Integer.parseInt(m3[i][k].getText()) + Integer.parseInt(m1[i][j].getText())*Integer.parseInt(m2[j][k].getText())));
       
reduce();
    }
    }
    //***************************************************************


    /** Creates new form MatrixMultiplicationForm */
    private JPanel p1,p2,p3,p4;
    private JTextField txtM,txtN,txtR;
    private JButton bttnFirstMatrix,bttnSecondMatrix,bttnSolve,bttnReset;
    private JTextField[][] m1,m2,m3;
    private JLabel l1,l2;


    public MatrixMultiplicationForm() {
        initComponents();
        l1=new JLabel();
        l2=new JLabel();
        setLayout(new GridLayout(2,2));
        p1=new JPanel();
        p2=new JPanel();
        p3=new JPanel();
        p4=new JPanel();
        p1.setBackground(Color.GREEN);
        p2.setBackground(Color.GREEN);
        p3.setBackground(Color.YELLOW);
        p4.setBackground(Color.PINK);
        add(p1);
        add(p2);
        add(p3);
        add(p4);
        p4.setLayout(new GridLayout(6,2));
        txtM=new JTextField();
        txtN=new JTextField();
        txtR=new JTextField();
        p4.add(l1);
        p4.add(l2);
        p4.add(new JLabel("M"));
        p4.add(txtM);
         p4.add(new JLabel("N"));
        p4.add(txtN);
         p4.add(new JLabel("R"));
        p4.add(txtR);
        bttnFirstMatrix=new JButton("First Matrix");
        bttnSecondMatrix=new JButton("Second Matrix");
        bttnSolve=new JButton("Solve");
        bttnReset=new JButton("Reset");
        p4.add(bttnFirstMatrix);
        p4.add(bttnSecondMatrix);
        p4.add(bttnSolve);
        p4.add(bttnReset);

        bttnSolve.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                try
                {
                   
                    t1=(new java.util.Date()).getTime();
 int m=Integer.parseInt(txtM.getText());
int r=Integer.parseInt(txtR.getText());
    int n=Integer.parseInt(txtN.getText());
    int i,j,k;
    for(i=0;i<=m-1;i++)
        for(j=0;j<=r-1;j++)
            m3[i][j].setText("0");


    for(i=0;i<=m-1;i++)
        for(j=0;j<=n-1;j++)
            for(k=0;k<=r-1;k++)
                m3[i][k].setText("" + (Integer.parseInt(m3[i][k].getText()) + Integer.parseInt(m1[i][j].getText())*Integer.parseInt(m2[j][k].getText())));
     t2=(new java.util.Date()).getTime();
     l1.setText("Direct Time taken = " + (t2-t1));


JOptionPane.showMessageDialog(rootPane,"Now multiplying using Threads");
//Total Number of Thread
NoofThread=m*r;
t1=new java.util.Date().getTime();
for(i=0;i<=m-1;i++)
    for(k=0;k<=r-1;k++)
    {
        MultiplyThread t=new MultiplyThread(i, k, n);
        t.start();

    }


                }
                catch(Exception ex)
                {
                    JOptionPane.showMessageDialog(rootPane, ex);
                }
            }
        });





        bttnSecondMatrix.addActionListener(
                new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                try
                {
                    int m=Integer.parseInt(txtM.getText());
int r=Integer.parseInt(txtR.getText());
    int n=Integer.parseInt(txtN.getText());
    m2=new JTextField[n][r];
    p2.removeAll();
    p3.removeAll();
    p2.setLayout(new GridLayout(n,r));
    for(int i=0;i<=n-1;i++)
        for(int j=0;j<=r-1;j++)
        {
            m2[i][j]=new JTextField();
            p2.add(m2[i][j]);
        }
    p2.doLayout();

     p3.setLayout(new GridLayout(m,r));
     m3=new JTextField[m][r];
    for(int i=0;i<=m-1;i++)
        for(int j=0;j<=r-1;j++)
        {
            m3[i][j]=new JTextField();
            p3.add(m3[i][j]);
        }
    p3.doLayout();
                }
                catch(Exception ex)
                {
                    JOptionPane.showMessageDialog(rootPane, ex);
                }
            }
        }
                );

bttnFirstMatrix.addActionListener(
        new ActionListener()
{
    public void actionPerformed(ActionEvent evt)
    {
try
{
    int m=Integer.parseInt(txtM.getText());
    int n=Integer.parseInt(txtN.getText());
    m1=new JTextField[m][n];
    p1.removeAll();
    p1.setLayout(new GridLayout(m,n));
    for(int i=0;i<=m-1;i++)
        for(int j=0;j<=n-1;j++)
        {
            m1[i][j]=new JTextField();
            p1.add(m1[i][j]);
        }
    p1.doLayout();
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(rootPane, ex);
}
    }
});

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Matrix Multiplication");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 452, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                       

    /**
    * @param args the command line arguments
    */


    // Variables declaration - do not modify                    
    // End of variables declaration                  

}




1 comment:

  1. did you test the program for large matrix for example million by million matrix

    ReplyDelete