CS 314 Specification 2 - 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 2: Individual Assignment. You must complete this assignment on your own. You may not acquire from any source (e.g. another student, an internet site, generative AI / chatbot such as chatGPT or GitHub coPilot) a partial or complete solution to a problem or project that has been assigned. You may not show another student your solution to the assignment. You may not have another person (current student, former student, tutor, friend, anyone) “walk you through” how to solve the assignment. You may get help from the instructional staff. You may discuss general ideas and approaches with other students but you may not develop code together. Review the class policy on collaboration from the syllabus.
The purposes of this assignment are
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 |
Description: Implement a class that represents a mathematical matrix. You are implementing a stand alone class that is a new data type.
Matrices are used in applications such as physics, engineering, probability and statistics, economics, biology, and computer science. (especially in the area of computer graphics. One use of mathematical matrices is to solve systems of linear equations. Here is a page on how matrices are used to perform rotations on 3d objects in a graphics system. ) There is a course in the UT Math department that covers matrices, 340L, and many CS students take this course. Dr. Maggie Meyers and CS Professor Robert van de Geijn offer an online linear algebra with a programming component.
Matrices appear in the following form:
These matrices could 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 the matrices will only contain java
int
s. 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.
Requirements: The provided source file MathMatrix.java contains a skeleton implementation of a class to model mathematical matrices.
Implement all of the methods in MathMatrix.java under the constraints of the general requirements.
You may use other classes and methods from the Java standard library on this assignment.
Add conditional statements (ifs) to check preconditions for
public methods and throw
IllegalArgumentException
s if the preconditions are violated.
You must use a "native" two dimensional array of
int
s 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 dimensional array of ints
// is NOT a MathMatrix!
The first row of a MathMatrix
is numbered 0. The first column of a
MathMatrix
is numbered 0. zero based indexing in other words.
The provided source file, MathMatrixTester.java
contains various tests for the MathMatrix
class. Your MathMatrix
class must pass the included tests. Delete the provided tests in the version of
MathMatrixTester.java that you turn in.
Add at least 2 new tests for each of the public methods you are completing (22 tests total.) Add the tests to MathMatrixTester.java. I encourage you to share you tests with others via the class discussion group. Everyone must write their own tests, but you are allowed to share the tests you write to check your code.
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.
In CS312 we emphasize minimizing redundant code. That still holds true. In CS314 we also want to minimize redundant instance variables. Do no add unnecessary instance variables.
Note, once a MathMatrix
object is created there are
no methods to alter its size. So unlike the
IntList
we created in lecture it does NOT 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. (This implies it
is not necessary to keep track of the number of rows and columns with separate
instance variables.)
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 top of MathMatrixTester.java. Recall, you cannot share your experiment code with others. You CAN share tests on Piazza to help each test your solution code with a wide variety of test cases. The tests you turn in must be your own.
Include the code that conducts the experiments in the MathMatrixTester.java class, but comment it 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 has methods that return the elapsed time in seconds or nanoseconds between starting and stopping the Stopwatch. See the Stopwatch class documentation for more details.
Experiment 1: Create two matrices and fill them with random values. Initially try matrices that are 1000 by 1000 in size. You may have to adjust the dimension as described below. Reuse the same initla matrix of each size for the following experiments. Repeat each experiment 1000 times and note the total time of the 1000 experiments for each value of N. (3 total, N, 2N, 4N)
Use the Stopwatch class to record the time it takes to add
the 2 MathMatrix
objects together.
You must choose a value for the number of rows and columns so the total time of the 1000 tests give a result of at least 1 second of elapsed time. (1 second total for all 1000 tests, NOT 1 second per test.) You should, of course, automate these 1000 repetitions. Do not create new Matrix objects for each test. Simply reuse the Matrix objects you create at the beginning of the experiment.
Record the dimension of the matrix and the total time it took for the add operation based on 1000 repetitions.
Now double the dimension of the matrix, create two
matrices with random values, and repeat the
experiment. For example if 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 total time it took for the add operation on the larger matrix based on 1000 repetitions.
Double the dimension of the matrix one more time, create two matrices with random values, and conduct 1000 additions, and determine the total time.
If you get an out of heap space error, increase the size of the heap. All of the possible command line flags are on this page. In Eclipse you can set a command line flag for your program. Follow the instructions for enabling assertions and include the flag -Xmxsize where size is the new requested heap size. For example, to increase the heap size to 120 mb include the command line flag -Xmx120m.
Experiment 2:
Perform the same basic experiment as experiment 1, but use
the multiply
method instead of the add
method.
You can likely start with a smaller value of N than you initially used for
the experiments involving the add method. Repeat the experiment 100 (one hundred not 1000 in this case) times to get the
total time.
Again, do not create new Matrix objects for each test. Simply reuse the Matrix objects you create at the beginning of the experiment.
You must choose a value for the number of rows and columns so the total time of the 100 tests give a result of at least 1 second of elapsed time. (1 second total for all 100 tests, NOT 1 second per test.) You should, of course, automate these 100 repetitions.
Questions. Answer the following questions. Place your answers in your comment at the top of MathMatrixTester.java along with the results of your experiments.
Based on the results of experiment 1, how long do you
expect the add method to take if you doubled the dimension size of the
MathMatrix
objects again?
What is the Big O of the add operation given two N by N matrices based on an analysis of your code? Does your timing data support this?
Based on the results of experiment 2, how long do you
expect the multiply method to take if you doubled the dimension size of
the MathMatrix
objects again?
What is the Big O of the multiply operation given two N by N matrices based on analysis of your code? Does your timing data support this?
How large a matrix can you create before your program runs
out of heap memory? (When using the default heap size. No command line
flag to increase heap size.) In other words what size matrix causes a Java
OutOfMemoryError
, 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 requires 4 bytes.) State your answer in gigabytes.
What percentage of your computer's RAM did your program use before
crashing?
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 as required. I will use plagiarism detection software on your submissions. If you copy solution code from another source you are cheating. I will submit an academic dishonesty case with a recommended penalty of an F in the course.
Turn in your MathMatrix.java and MathMatrixTester.java files to
the appropriate assignment on Gradescope.
Checklist: Did you remember to:
Tips:
MathMatrix
objects and the 2d array of int
s
that serves as the storage container.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
on ALL of the rows, even the last one.
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();
Implementing the toString
method using just loops and
String
s (and / or StringBuilder
s) and if
statements is an interesting exercise. Alternatively 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. Avoid creating too many unnecessary Strings.
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 consists of the cells
whose row and column are equal. (Runs for the top left to the bottom right.) The values of the elements on the main
diagonal and above it don't have to be zero, just the ones below it. A 1 by 1 matrix is upper triangular.