JMU CS488 - Computer Graphics Applications
Help Policies Solutions Study-Aids Syllabus Tools
Programming Assignment 4


1 Overview

Your Matrix and Vector classes from programming assignment 3 suffer from a few design flaws. In particular:

To overcome these shortcomings, in this assignment if you need a row Vector you will use a \(1 \times n\) Matrix and if you need a column Vector you will use a \(m \times 1\) Matrix instead. However, you will still have a Vector "class" because it will contain the friend functions that are specific to Vector objects.

This assignment is about specialization in C++ (and, to a lesser extent, about templates). It does not use any new topics from our study of vector/matrix arithmetic.

2 Detailed Specification

The specifications for the classes in this assignment are available in "documentation format". That is, you are being provided with the documentation for the classes, and your implementation must conform to the documentation.

Note that, as is traditional in many applications including computer graphics, we are now only considering column vectors. (If you need a row vector for some reason you can use a \(1 \times n\) matrix.)

3 A Development Strategy

You should start by making a copy of your Matrix class from from programming assignment 3.

Next, you should make the following modifications to the copy:

  1. Add the default constructor that constructs a \(2 \times 2\) Matrix.
  2. Delete the constructor that is passed a Vector. (It isn't necessary since a Vector "is a" Matrix in this version.)
  3. Add the friend function with the signature double dot(const Matrix& a, const Matrix& b) that calculates the dot product (more commonly known as the scalar product) of two Matrix objects. (As with vectors, the dot/scalar product is the sum of the component-wise products of the elements. The dot/scalar product is only defined for matrices that have the same size.)
  4. Add the method with the signature double get(int i) const and another with the signature double& operator()(int i) that return a particular element of the calling Matrix if it contains a single row or single column. They must throw an out_of_range if i is out of range and length_error is the Matrix is neither a single row or single column.
  5. Add the method with the signature Matrix getColumn(int c) const that returns a column of the calling Matrix.
  6. Delete the friend function with the signature Matrix multiply(const Vector& a, const Vector& b). (It isn't necessary since a Vector "is a" Matrix in this version.)
  7. Add the friend function with the signature Matrix operator|(const Matrix& a, const Matrix& b) that concatenates the columns of the a and the columns of b.
  8. Delete the friend functions with the signature Vector operator*(const Vector& v, const Matrix& m) and Vector operator*(const Matrix& m, const Vector& v). (They aren't necessary since a Vector "is a" Matrix in this version.)
  9. Add the protected method with the signature void setValues(const Matrix& other); that is used by the copy constructor and the assignment operator.
  10. Add/modify other methods as necessary.

4 Unit Testing

Now that you know about templates, you can use an improved version of the "home grown" unit testing framework/harness. This version includes a templated assertEquals() method that can be passed an object that has an operator==() function. It also includes an assertThrows() method that makes use of lambda expressions.

5 Submission

You must submit a file named pa4.zip that contains just Vector.h, Vector.cpp, Matrix.h, Matrix.cpp using Autolab.

6 Grading

Points will be awarded as follows:

7 Questions to Think About

In this assignment, though the Vector class specializes the Matrix class, it does not contain any additional methods (other than constructors), nor does it override any methods in the Matrix class. In fact, the Vector class only exists to add friend functionality to the Matrix class.

One could, instead, have a Vector class that "really" specializes the Matrix class and use distinct Matrix and Vector objects. However, such a design would have several awkward aspects. You should ask yourself the following questions about such a design.

  1. What is the result of multiplying a Vector object and a Matrix? What are the reasonable options?
  2. Does it make sense to add an appropriately sized Matrix to either a column or row Vector? What is the type of the result?
  3. What methods would need to be overridden in the Vector class in order to provide type safety?

8 Looking Ahead

In the next assignment you will create templates from your Matrix and Vector classes. The parameter(s) of the templates will be the size(s) of the objects (i.e., the number of rows and columns).

Copyright 2020