CS 307Assignment, Implementing a Class - Mathematical Matrix

"Linear algebra is a fantastic subject On the one hand it is clean and beautiful. If you have three vectors in 12 dimensional space, you can almost see them."
- Gilbert Strang, Linear Algebra and its Applications

Programming Assignment 3: Individual Assignment. You must complete this assignment on your own. You may not discuss their work with anyone except the instructor and other members of the instructional staff (TA, section leader, or lab proctor). You may not acquire from any source (e.g., another student or an internet site) a partial or complete solution to a problem or project that has been assigned. You may not show another student your solution to an assignment. You may not have another person (current student, former student, tutor, friend, anyone) “walk you through” how to solve an assignment. Review the class policy on collaboration from the syllabus.

The purposes of this assignment are

1. To practice implementing a stand alone class.
2. To work with two dimensional arrays.

Description: Implement a class that represents a mathematical matrix. You are implementing a stand alone class that is a new data type similar to the way we implemented an `IntList` class in lecture.

Mathematical matrices are used  to solve systems of linear equations. Matrices are used in applications such as physics, engineering, probability and statistics, economics, biology, and computer science. (especially in the area of computer graphics. For example here is a page on how matrices are used to perform rotations on 3d objects in a graphics system. )

Matrices appear in the following form:

These matrices represent this system of linear equations:

x +  5y + 10z + 5w =   4
6x +  4y + 12z + 4w =   5
10x +  5y + 12z + 11w = 12
5x + 11y + 23z + 9w  =  7

The above matrix has 4 rows and 4 columns, but the number of rows and columns do not have to be equal. In other words mathematical matrices do not need to be square, but they must be rectangular. Each entry can be an integer or real number. For this assignment you will only deal with matrices of integers. You will implement a class, `MathMatrix`, that models a mathematical matrix and supports various operations on matrices. See this page for an explanation of the mathematical operations you are implementing. The Wikipedia article may also be useful. After calculus, most students then take a course entitled Matrices and Matrix Calculations.

Provided Files:

 File Responsibility Implementation MathMatrix.java Provided by me and you. (Okay, mostly you.) Documentation MathMatrix.html Provided by me. Implementation Stopwatch.java (For use in experiments) Provided my me Documentation Stopwatch.html Provided by me Testing MathMatrixTester.java Provided by me and you Submission MathMatrix.java and MathMatrixTester.java. Provided by you.

Requirements: The provided source file MathMatrix.java contains a skeleton implementation of a class for modeling mathematical matrices. MathMatrix.java

Implement all of the methods in MathMatrix.java under the constraints of the general requirements.

• You may use any other classes and methods from the Java standard library you wish on this assignment. The ``` Arrays``` class has many useful methods for dealing with arrays. You may use other classes and methods from the standard library if you wish.

• Add either assertions or if statements that throw ``` IllegalArgumentException```s to methods to check preconditions of methods.

• You must use a "native" two dimensional array of ints as your underlying storage container in the matrix class:

private int[][] values;
// or nums or cells or some other appropriate name
// DO NOT USE some variation of mathMatrix or matrix.
// That is much too confusing. The two d array of int
// is NOT a MathMatrix!

• The first row of a `MathMatrix` is numbered 0. The first column of a `MathMatrix` is numbered 0.

• The provided source file, MathMatrixTester.java contains various tests for the `MathMatrix` class. Some of these tests may be incorrect. You must find and fix any incorrect tests. Your `MathMatrix` class must pass the included tests. I encourage you to use the class listserv to identify incorrect tests.

• Add at least 1 new tests per public method to this class. (12 tests total.) I encourage you to share you tests with others via the class discussion group on piazzza.

• You are encouraged to create `private` helper methods and use other `public` methods in the `MathMatrix` class when completing methods in the ``` MathMatrix``` class if this simplifies the solution.

• Note, once a `MathMatrix` object is created there are no methods to alter its size. So unlike the `IntList` we created in class it doesn't make sense to have extra capacity. The size of the 2d array of ints will be the same size as the Mathematical Matrix it is representing.

Experiment: In addition to completing the MathMatrix.java class and adding tests to the MathMatrixTester.java class, perform the following experiments and answer the following questions. Place your results and answers in a comment at the bottom of MathMatrixTester.java.

The code that conducts the experiments is to be included in the MathMatrixTester.java class, but commented out.

Use the Stopwatch class to record the time it takes to perform various operations on `MathMatrix` objects.

```Stopwatch s = new Stopwatch(); s.start(); //code to time s.stop();```

The Stopwatch class can show the elapsed time in seconds or nanoseconds. See the Stopwatch class documentation for more details.

Experiment 1:

• Create 2 square matrix objects. (The number of rows equals the number of columns.) Fill the matrix objects with random values.

• Use the Stopwatch class to record the time it takes to add the 2 `MathMatrix` objects together.

• Repeat the experiment 100 times and record the average time in milliseconds it takes to add the 2 MathMatrix objects together.

• You must choose a value for the number of rows and columns so that all of the 100 tests give a result of at least 10 milliseconds elapsed time per test. (10 millisecond is 0.01 seconds) You should, of course, automate these 100 repetitions.

On my old computer a `MathMatrix` dimension equal to 800 (So the `MathMatrix` was 800 by 800, 640,000 total elements) led to all measured times being greater than 10 milliseconds. Your results will vary based on the speed of the computer you run the test on.

• Record the dimension of the matrix and the average time it took for the add operation based on 100 repetitions.

• Now double the dimension of the matrix and repeat the experiment. In my example the original `MathMatrix` was 800 by 800. In this step the size would be increased to 1600 by 1600.

• Record the dimension of the matrix and the average time it took for the add operation on the larger matrix based on 100 repetitions.

Experiment 2:

• Perform the same basic experiment as experiment 1, but use the `multiply` method instead of the `add` method.

• You can use a much smaller dimension than in experiment 1 and still avoid measured times of less than 1 millisecond. You must choose a size that results in at least 10 milliseconds for the experiment. On my old computer a dimension of 200 (a 200 by 200 matrix. 40,000 elements) avoided any times below 10 milliseconds.

1. Based on the results of experiment 1, how long would you expect the add method to take if you doubled the dimension size of the `MathMatrix` objects again?

2. Based on the results of experiment 2, how long would you expect the multiply method to take if you doubled the dimension size of the `MathMatrix` objects again?

3. How large a matrix can you create before your program runs out of heap memory? Estimate the amount of memory your program is allocated based on the largest possible matrix object it can create successfully. (Recall, an int in Java takes up 4 bytes.)

4. The logic of the add and subtract methods of the ``` MathMatrix``` class are very similar. Code so similar should make you want to generalize it into a method. You are not required to do this on the assignment, but what do you think could be done to generalize the add and subtract methods?

Submission: Fill in the header for MathMatrix.java and MathMatrixTester.java. Replace <NAME> with your name. Note, you are stating, on your honor, that you did the assignment on your own.

When finished use the turnin program to turn in the MathMatrix.java and MathMatrixTester.java files to your cs307 folder.

Checklist: Did you remember to:

• review and follow the general assignment requirements?
• work on the assignment by yourself?
• fill in the headers in the MathMatrixTester class? If using Eclipse be sure to expand the header comment.
• implement the required methods?
• ensure your program does not suffer a compile error or runtime error?
• find and fix any incorrect tests in MathMatrixTester?
• ensure your program passes the tests in MathMatrixTeser?
• add tests to the main method of MathMatrixTester?
• complete the experiments and place you answers in a comment at the bottom of the MathMatrixTester file?
• turn in your files named MathMatrix.java and MathMatrixTester.java to the proper account via the turnin program before 11 pm, Tuesday, July 5?

Tips:

1. Be clear on the difference between `MathMatrix` objects and the 2d array of ints that serves as the storage container for the ints that make up a `MathMatrix` object.

Assume the 2d array of int that is the instance variable for each MathMatrix object is named myCells.

{   MathMatrix result = new MathMatrix(numRows(), numCols(), 0);
int valueFromThisMathMatrix = myCells[0][0];
int valueFromRightHandSide = rightHandSide.myCells[0][0];
int valueFromResult = result.myCells[0][0];

// the following line results in syntax error
// valueFromRightHandSide = rightHandSide[0][0];

2. Familiarize yourself with the concept of deep copying. (As opposed to shallow copying.) One of the constructors requires you make a deep copy of a 2d array of ints. Implement your copying without using the clone() method. Here is the Wikipedia article on object copying.

3. If possible use other methods from the `MathMatrix` class instead of repeating code.

4. An explanation of the requirements for the `toString` method.

In the String that is returned from the `toString` method the space for each "cell" is equal to the longest value in the matrix plus 1. (Don't forget to consider a minus sign in on of the values.) All cell entries are right justified with newline characters  between rows. For example, given the following `MathMatrix`.

 10 100 101 -1000 1000 10 55 4 1 -1 4 0

You should return a String that would appear like this. Use newline characters ("\n") to create line breaks.

10   100   101 -1000
1000    10    55     4
1    -1     4     0

In example above it can be hard to tell how many spaces there are between numbers. In this example the spaces have been replaced by periods to the number of "spaces" is more clearly shown.

....10...100...101.-1000
..1000....10....55.....4
.....1....-1.....4.....0

Note, the last line includes a newline character.

One way of finding the length of an int is to convert it to a `String` and find the length of the `String`. Here is an example:

int x;
//code to give x a value.
String s = "" + x;
int lengthOfInt = s.length();

//or more simply given an int x
int lengthOfX = ("" + x).length();

Doing the `toString` method using just loops and `String`s and if statements is actually a very interesting exercise. Or you can learn how to use the format method from the String class and formatting string syntax. Here is an introduction to formatting String syntax.

5. The `isUpperTriangular` method determines if the `MathMatrix` is an upper triangular matrix. A matrix is upper triangular if it is a square matrix and all values below the main diagonal are 0. The main diagonal is all the cells whose row and column are equal. The values of the elements on the main diagonal don't have to be zero, just the ones below it. A 1 by 1 matrix is always considered upper triangular.

Back to the CS 307 homepage.