C++ track: lab 2: Matrix Madness


Goals

This week, you will design and implement a C++ class which can be used to manipulate integer matrices.

Language concepts covered this week

Program to write:

Define a class called Matrix which handles all of the operations illustrated in the "user's code" below:

#include "Matrix.hh"
#include <iostream>

using namespace std;

int main()
{
    // Create a new matrix with two rows and three columns.
    Matrix a(2, 3);  

    // Print out some information about the size of this matrix.
    cout << "Matrix a is " << a.getrows() << " rows tall." << endl;
    cout << "Matrix a is " << a.getcols() << " columns wide." << endl;

    // Print out the contents of this matrix (should be all zeroes!).
    for (int r = 0; r < a.getrows(); r++)
    {
        for (int c = 0; c < a.getcols(); c++)
        {
            cout << "Element (" << r << ", " << c << ") = " 
                 << a.getelem(r,c) << endl;
        }
    }

    // Fill in a few values.
    a.setelem(1, 2, -5280);  // Bottom right element is now -5280.
    a.setelem(0, 1, 123);    // Top center element is now 123.

    // Create an identical copy of this matrix.
    Matrix b(a);

    // Change the original matrix some more.
    a.setelem(1, 2, 555);  // Bottom right element is now 555.

    // Examine some elements of each matrix.
    cout << "(1, 2) of a = " << a.getelem(1, 2) 
         << " [should be 555]" << endl;
    cout << "(1, 2) of b = " << b.getelem(1, 2) 
         << " [should be -5280]" << endl;

    // So if a and b are different, let's copy a into a new matrix and add b to it.
    Matrix c(a);
    c.add(b);

    // Now let's copy c into another new matrix and subtract a from it.
    Matrix d(c);
    d.subtract(a);

    // Hmm...  that means d should be b, no?
    if (d.equals(b)) 
    {
        cout << "Woo hoo!  d = b!" << endl;
    }
    else 
    {
        cout << "Oh oh!  Something went wrong, d isn't b!" << endl;
    }

    // Let's create a tiny 0 by 0 matrix using the default constructor.
    Matrix e;
    cout << "0x0 matrix e is " << e.getrows() << " by " << e.getcols() << endl;

    // Of course, e and d are different, since they have different sizes!
    if (!e.equals(d))
    {
        cout << "e and d are indeed different!" << endl;
    }
    else
    {
        cout << "Oh well, back to the drawing board...." << endl;
    }

    // Okay, enough of this; destroy all those matrices and end the program.
    return 0;
}

(You can get the above file here: simplematrixtest.cc)

Got all that? Here's a quick summary:


Dealing with abuse

Whether it's arithmetic with matrices of incompatible sizes or a simple attempt to create a matrix with a negative number of columns, sooner or later, someone will try to do something stupid with your matrix class. The question is, what (if anything) should you do about it?

For this lab, the answer will be: Do something. Something reasonable would be nice. Trip an assertion, print an error message to cerr, return a special "error" value, call an error-handling function, throw an exception if you know what those are -- just don't pretend it'll never happen. Because sooner or later, it will.

A good rule of thumb is that if you think that something should never happen in a correctly-written program, an assertion is best; if something bad could legitimately happen, then you might want to think about the other options listed above.


Testing your class

For now, use the program above (or one of your own design) to test out all of the methods of your class. We will be expanding on our Matrix class next week and we'll give you a more comprehensive test suite then.

To compile the lab, use

g++ -Wall simplematrixtest.cc Matrix.cc -o simplematrixtest

Any warning or error messages you may see will most likely be due to problems in your class declaration or implementation. If you can't find the problem, ask for help! You should attempt to fix all warnings and errors before proceeding.

Run the simplematrixtest program.

Please bear in mind that this program can not and will not test everything! Just because it doesn't turn up any problems doesn't mean none exist. There are also many areas (error handling, coding style, class design) which an automated program can only test in a very limited fashion, if at all. Remember that we will be grading your entire program, not just the output of some test program.


Anything else?

Between this page, the provided test program, and the material from lecture, you should have a pretty good idea of what your class needs to do and what its public interface needs to look like. How you choose to implement these features is up to you. If you're not sure where to start, ask for help!

Be careful about adding extra features such as different operators, alternate constructors, or new methods to your class. Though you are not prohibited from doing so, you might want to talk about it with me before expanding your class's public interface. It's often the case that adding too many "features" to an interface will actually make it more difficult to use or maintain, especially if the new methods overly expose your class's internal implementation details.


To hand in

The Matrix.hh and Matrix.cc files.