Our program will consist of 3 classes: MatrixMultiplyer, MultiplyerThread, and M
ID: 3919692 • Letter: O
Question
Our program will consist of 3 classes: MatrixMultiplyer, MultiplyerThread, and MatrixRunner. Skeleton code for the matrix multiplyer class is provided:
package matrixMultiplication;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
public class MatrixMultiplyer {
private int[][] inputMatrix1;
private int[][] inputMatrix2;
private int[][] outputMatrix;
/**
* creates two integer matrixes from files, and establishes the size of
the output matrix, for when the two other matrixes are multiplied
* @param inputFileMatrix1
* @param inputFileMatrix2
* @throws Exception
*/
public MatrixMultiplyer(String inputFileMatrix1, String inputFileMatrix2) throws Exception {}
/**
* can be called by individual threads in order to multiply the rows
and columns of a matrix in parallel, the specific row and column of the
output matrix to be calculated are given as arguments
* @param row
* @param column
*/
public void multiplyOutputEntry(int row, int column) {}
/**
* searches through the text file inputFile, which contains a valid
matrix, and inputs the values into the inputMatrix
* @param inputMatrix
* @param inputFile
*/
private void parseMatrix(int[][] inputMatrix, String inputFile) {}
/**
* Searches a valid Matrix file for the number of rows in the matrix;
* @param inputFile
* @return
*/
private int matrixRows(String inputFile) {}
/**
* Searches a valid matrix file for the number of columns in the matrix
* @param inputFile
* @return
*/
private int matrixColumns(String inputFile) {}
/**
* searches through an input file to determine whether or not the input
file contains a valid matrix
* @param matrixFilePath
* @return
*/
private boolean fileContainsValidMatrix(String matrixFilePath) {}
public void printOutput() {}
public int getOutputMatrixRows() {
return outputMatrix[0].length;
}
public int getOutputMatrixColumns() {
return outputMatrix.length;
}
}
Before you get to the multithreading, you must ensure that two matrices have been provided which correctly satisfy the conditions for multiplication.
1.1) write the fileContainsValidMatrix method which should ensure that the matrix is composed of only integers and that all of the rows and columns of the matrix are of even length. The matrixes will be contained in basic text files. Two sample matrix are provided below
2 4 5 4
6 4 3 7
4 5 7 2
9 8 7
2 6 6
1 2 3
3 4 5
1.2) Write both the matrixRows and matrixColumns functions which return the number of rows / columns of a given matrix.
1.3) write the parseMatrix method which should be able to fill a two-dimensional array based on the input of a file.
1.4) write the MatrixMultiplyer constructor, the constructor should use the previously written methods in order to test if the matrices are valid, allocate the inputMatrix arrays accordingly, fill the inputMatrix arrays with the information from the files, and ensure that the number of columns in the first matrix is equal to the number of columns in the second matrix. This is a requirement for matrix multiplication. Finally, the output matrix should be initialized to the proper size.
1.5) So far, all of the methods that we have written run sequentially. The multiplyOutputEntry method is the one that will be called by the individual threads. In future problems, this is the method which due to its concurrent execution would contain a lock or some other form of concurrency control. However because each individual entry of the output matrix is a separate entity, the threads will never interfere with each other. Simply write the method so that based on a given row and Column, the specific entry of the output matrix is calculated.
1.6) To write the MultiplyerThread class you must extend Thread, which can be done in the class declaration as follows:
public class MultiplyerThread extends Thread
Give the class a row, and column integer, as well as an instance of the MatrixMultiplyer class you wrote. The constructor should look as follows:
public MultiplyerThread (int rowInput, int columnInput, MatrixMultiplyer matrixInput)
Eclipse should be giving a warning that you have not implemented the run() function. This is the fundamental method of the Thread class. Yours should only contain a single line which calls the multiplyOutputEntry method of the thread’s matrix instance. It is essential that the thread contain a reference to the MatrixMultiplyer - it is the shared memory which all of the threads access, and which in the future will need to be protected.
1.7) The final step is to create a running class, the class which will control the synchronization of the threads as well as the initialization of the MatrixMultiplyer. Create the runner class which takes the file names which contain the text matrices as command line arguments. You will then need to initialize a MultiplyerThread for each index in the output matrix.
1.8) Investigate both of the start() and join() methods. You will need to start each of the threads individually, and wait for each one of them to finish individually. When the threads have finished their calculations print out the resultant matrix.
Explanation / Answer
import java.io.FileNotFoundException;
public class MatrixMultiplierRunner
{
public static void main(String[] args)
{
if (args.length != 2)
{
usage();
}
// matrix1.txt and matrix2.txt
String fileName1 = args[0];
String filename2 = args[1];
MatrixMultiplier matrixInput = null;
// create multiplier object with 2 matrices (input files)
try
{
matrixInput = new MatrixMultiplier(fileName1, filename2);
}
catch (FileNotFoundException ex1)
{
System.err.println("Invalid file.");
System.exit(1);
}
// get number of rows and columns of the output matrix
int cols = matrixInput.getOutputMatrixColumns();
int rows = matrixInput.getOutputMatrixColumns();
// start one thread for each index of the output matrix
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
for (int i = 0; i < rows; i++)
{
// create runnable object and start thread
MultiplierThread mt = new MultiplierThread(row, col, matrixInput);
Thread t = new Thread(mt);
t.start();
}
}
}
matrixInput.printOutput();
}
private static void usage()
{
System.err.println("Usage: java MatrixMultiplierRunner file1 file2");
System.exit(1);
}
}
--------------------------------------------------------------------------------------------------------------------------
public class MultiplierThread extends Thread implements Runnable
{
// instance variables
private int row;
private int col;
private MatrixMultiplier mp;
// Create a matrix multiplier thread with the matrix object, row and column passed as arguments
public MultiplierThread (int rowInput, int columnInput, MatrixMultiplier matrixInput)
{
this.row = rowInput;
this.col = columnInput;
this.mp = matrixInput;
}
public void run()
{
mp.multiplyOutputEntry(row, col);
}
}
-------------------------------------------------------------------------------------------------------------------
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class MatrixMultiplier
{
private int [][] inputMatrix1;
private int [][] inputMatrix2;
private int [][] outputMatrix;
// Create the matrix multiplier
public MatrixMultiplier (String inputFileMatrix1, String inputFileMatrix2) throws FileNotFoundException
{
if (fileContainsValidMatrix(inputFileMatrix1) && fileContainsValidMatrix(inputFileMatrix2))
{
// number of rows and columns in the first matrix
int matrixOneCols = matrixColumns(inputFileMatrix1);
int matrixOneRows = matrixRows(inputFileMatrix1);
// number of rows and columns in the second matrix
int matrixTwoCols = matrixColumns(inputFileMatrix2);
int matrixTwoRows = matrixRows(inputFileMatrix2);
if ((matrixOneCols == matrixTwoRows))
{
// initialize input matrices
inputMatrix1 = new int[matrixOneRows][matrixOneCols];
inputMatrix2 = new int[matrixTwoRows][matrixTwoCols];
// initialize output matrix
outputMatrix = new int[matrixOneRows][matrixTwoCols];
// fill the inputMatrix arrays with the information from the files
parseMatrix(inputMatrix1, inputFileMatrix1);
parseMatrix(inputMatrix2, inputFileMatrix2);
}
else
{
outputMatrix = null;
}
}
else
{
outputMatrix = null;
}
}
public void multiplyOutputEntry(int row, int column)
{
int sum = 0;
for (int i = 0; i < inputMatrix1[0].length; i++)
{
sum += inputMatrix1[row][i] * inputMatrix2[i][column];
}
outputMatrix[row][column] = sum;
}
// Fill a two-dimensional array based on the input of a file
private void parseMatrix (int [][] inputMatrix, String inputFile) throws FileNotFoundException
{
// create File object and pass to Scanner
File file = new File(inputFile);
Scanner in = null;
int numRows = 0;
int numCols = 0;
try
{
in = new Scanner(file);
// array properties
numRows = matrixRows(inputFile);
numCols = matrixColumns(inputFile);
}
catch (FileNotFoundException ex1)
{
throw new FileNotFoundException("file " + inputFile + " not found");
}
// populate array
for (int row = 0; row < numRows; row++)
{
for (int col = 0; col < numCols; col++)
{
inputMatrix[row][col] = in.nextInt();
}
}
in.close();
}
// Searches a valid Matrix file for the number of rows in the matrix
private int matrixRows(String inputFile) throws FileNotFoundException
{
if (!fileContainsValidMatrix(inputFile))
{
return 0;
}
File file = new File(inputFile);
Scanner in = new Scanner(file, "UTF-8");
int numRows = 0;
while (in.hasNextLine())
{
numRows++;
in.nextLine();
}
in.close();
return numRows;
}
// Searches a valid matrix file for the number of columns in the matrix
private int matrixColumns(String inputFile) throws FileNotFoundException
{
if (!fileContainsValidMatrix(inputFile))
{
return 0;
}
File file = new File(inputFile);
Scanner in = new Scanner(file, "UTF-8");
Scanner line;
int numCols = 0;
if (in.hasNextLine())
{
line = new Scanner(in.nextLine());
while (line.hasNext())
{
line.next();
numCols++;
}
}
in.close();
return numCols;
}
// determine whether or not the input file contains a valid matrix
private boolean fileContainsValidMatrix(String matrixFilePath) throws FileNotFoundException
{
File file;
Scanner in;
int length = 0;
try
{
file = new File(matrixFilePath);
in = new Scanner(file);
}
catch (Exception e)
{
throw new FileNotFoundException();
}
while(in.hasNextLine())
{
String line = in.nextLine();
Scanner inputLine = new Scanner(line);
// ensure that the matrix is composed of only integers and that
while (inputLine.hasNextInt())
{
inputLine.nextInt();
length++;
}
inputLine.close();
}
in.close();
if (length == 0)
{
return false;
}
// ensure that all of rows and columns have even length
return (length % 2 == 0);
}
//Print matrix on console
public void printOutput()
{
System.out.printf("----- Output matrix ----- ");
System.out.printf("------------------- ");
for (int row = 0; row < this.outputMatrix.length; row++)
{
for (int col = 0; col < this.outputMatrix[row].length; col++)
{
System.out.printf("| ");
System.out.printf("%-4d", outputMatrix[row][col]);
}
System.out.printf("|");
System.out.printf("%s", " ------------------- ");
}
System.out.println();
}
// Getter for the number of rows in the matrix
public int getOutputMatrixRows()
{
return outputMatrix[0].length;
}
// Getter for the number of columns in the matrix
public int getOutputMatrixColumns()
{
return outputMatrix.length;
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.