CMSC-341, Spring 1999, Sections 101 and 201

Project 1


Assigned   Monday, 1 February 1999            Due   Monday, 15 February 1999


Background

Abstract Data Types (ADT) are a central idea of this course and of object-oriented programming in general. Recall that an ADT has two parts: (1) a description of the elements that make up the type, and (2) a description of the operations allowed on instances of the type. The ADT idea is implemented in C++ as a class.

The ADT is one of the most powerful and important ideas in computer science. This project will give you some exercise in writing and using ADTs.

Another important OOP idea, parametric polymorphism, is implemented in C++ by templates. This project will give you some practice with C++ templates.

The project is based on material from Chapters 1, 3 and 4 of the Heileman text. Heileman describes a Matrix ADT in Section 1.1.1. He implements the ADT in C in Section 3.5 and in C++ in Section 4.3. Both implementations use the OOP aggregation technique -- they make use of an aggregated array to store the Matrix elements.

The text provides a partial C++ implementation of the Matrix ADT. This will be a basis for your work on this project. The textbook code for matrix.C and matrix.H is in the directory:
/afs/umbc.edu/users/a/n/anastasi/pub/CMSC-341/Projects/P1/HeilemanCode
You may use it as the basis for your code. The textbook code is not guaranteed to be bug-free. In any event, you cannot use it as-is, you must modify it to meet the requirements of this project.

Exercise 4.11 describes an Array ADT. The Array is an "improved" array. A class definition of the ADT is also given. Unfortunately, the ADT operations are poorly documented.

Finally, Exercise 4.12 asks you to implement Matrix by aggregating an Array rather than a normal array. This is the central task of the project.


Description

The main task is to do Exercise 4.12 and test it by running the code in Figure 4.17.

To do this, you will have to implement the Array ADT and to modify the text's C++ implementation of the Matrix ADT.

The classes provided by the text are not well documented; but you will provide good documentation as described on the Project Organization page.

Modified versions of the text's class definitions for Matrix and for Array are provided. Also provided is the code for the Proj1.C file and sample output obtained by executing it.

Here are your tasks:

  1. Read and understand the text description of the Matrix ADT and its C++ implementation.
  2. Copy the Matrix class definition below to your file Matrix.H. Modify the class definition so it uses an aggregated Array instead of an array. Document and guard the file.
  3. Copy the Array class definition below to your file Array.H. Document and guard the file.
  4. Implement the Matrix class in your file Matrix.C.
  5. Implement the Array class in your file Array.C.
  6. Copy the main function below to your Proj1.C file. This will be the only function in the file, but you will have to add #include lines and file documentation.
  7. Write a makefile. You can copy the makefile from the Project Organization page and modify it as needed.


Grading

Project grading is described on the Project Policy page.


Academic Integrity

Cheating in any form will not be tolerated. Instances of cheating will be reported to the UMBC Academic Conduct Committee. These reports are filed by the Committee and can be used for disciplinary action such as a permanent record on your transcript. Academic honesty is absolutely required of you. You are expected to be honest yourself and to report any cases of dishonesty you see among other students in this class. Reports of dishonest behavior will be kept anonymous.
Please re-read the
Project Policy page for further details on honesty in doing projects for this course.


Array Class Definition

This is a partially-documented version of the definition of the Array class. It is similar to the definition on Page 121 of the text. Use this definition rather than the text definition.

You must decide how to handle all exceptional situations. For example, what will you do if index is out of bounds in the operator[] method? Document and implement your approaches appropriately.

Don't forget to finish the documentation.

template <class T>
class Array
{
private:
  int _size;
  T* _array;

public:
  Array();      
  Array(int sz);
  Array(T* bi_aray, int sz_bi);
  Array( Array<T>& arr);
  ~Array();

  inline int GetSize() const;

  // Increase this Array's size by the specified amount
  // Param delta:  the amount by which to increase this 
  //   Array's size
  // Pre-condition: delta greater than or equal to zero. This
  // is enforced by an assertion.
  void Grow(int delta);

  // Decrease this Array's size by the specified amount
  // Elements are removed from the right (elements from
  // A[size - delta] through A[size - 1] are lost).
  // Param delta: the amount by which to decrease this 
  //   Array's size.
  // Pre-condition: delta greater than or equal to zero and
  //      no greater than present size of this Array. This is
  // enforced by an assertion.
  void Shrink(int delta);

  Array<T>& operator= ( Array<T> & A);
  T& operator[] (int indx) const;
  friend ostream& operator<< (ostream& os, const Array<T>& arr);
};

template<class T>
inline 
int Array<T>::GetSize() const
{  
  return _size; 
}


Matrix Class Definition

This is an undocumented version of the definition of the Matrix class. It is similar to the definition on Page 112 of the text. Use this definition rather than the text definition. Note the declaration of the element data field.

Note that this definition uses an Array rather than an array.

You must decide how to handle all exceptional situations. For example, what will you do if rdim is negative in the constructor Matrix(int rdim, int cdim)? Document and implement your approaches appropriately.

Note that the definition of the transpose of a matrix is given in the text in Exercise 3.8 on page 85.

Don't forget to document the file and the class.

template<class T>
class Matrix 
{
private:
  int  _row_dim, _col_dim;
  Array< Array<T> * > _element;
public:
  Matrix();
  Matrix(int rdim, int cdim);
  Matrix(int rdim, int cdim,  T& initval);
  Matrix(int rdim, int cdim, T* initval);
  Matrix(const Matrix<T>& m);
  ~Matrix();

  inline int GetRowSize() const;
  inline int GetColSize() const;

  Matrix<T>& operator=(Matrix<T>& m);

  friend ostream& operator<<(ostream& os, const Matrix<T>& m);
  friend Matrix<T> operator+(const Matrix<T>& m1, const Matrix<T>& m2);
  friend Matrix<T> Transpose(const Matrix<T>& m);
};


Main Function Definition

This is an undocumented version of the definition of the main function in file Proj1.C. It is similar to the definition of test.C on Page 116 of the text. Use this definition rather than the text definition.

Don't forget to document it.

#include <stdlib.h>
#include "Matrix.H"

int main()
{
  static int data1[] = {1, 2, 3, 4};
  static float data2[] = {0.1, 0.3};

  Matrix<int> a(2, 2, data1);
  Matrix<int> b(2, 2);
  Matrix<float> c(2, 1, data2);
  Matrix < Matrix<float> > d(2, 2, c);
  Matrix<int> e(1, 4, data1);
  
  cout.precision(4);
  cout.setf(ios::showpoint);
  
  b = a;
  
  cout << "a + b = " << endl;
  cout << a + b << endl;
  cout << "d = " << endl;
  cout << d << endl;
  
  cout << "Transpose(a) =" << endl;
  cout << Transpose(a) << endl;

  cout << "e = " << endl;
  cout << e << endl;
  cout << "Transpose(e) =" << endl;
  cout << Transpose(e) << endl;

  e = a;
  cout << "After e = a,  e =" << endl;
  cout << e << endl;
  cout << "and a =" << endl;
  cout << a << endl;

  return EXIT_SUCCESS;
}


Sample Output

This is the output obtained by executing Proj1 on umbc9
a + b = 
element(0,0) = 2
element(0,1) = 4
element(1,0) = 6
element(1,1) = 8

d = 
element(0,0) = element(0,0) = 0.1000
element(1,0) = 0.3000

element(0,1) = element(0,0) = 0.1000
element(1,0) = 0.3000

element(1,0) = element(0,0) = 0.1000
element(1,0) = 0.3000

element(1,1) = element(0,0) = 0.1000
element(1,0) = 0.3000


Transpose(a) =
element(0,0) = 1
element(0,1) = 3
element(1,0) = 2
element(1,1) = 4

e = 
element(0,0) = 1
element(0,1) = 2
element(0,2) = 3
element(0,3) = 4

Transpose(e) =
element(0,0) = 1
element(1,0) = 2
element(2,0) = 3
element(3,0) = 4

After e = a,  e =
element(0,0) = 1
element(0,1) = 2
element(1,0) = 3
element(1,1) = 4

and a =
element(0,0) = 1
element(0,1) = 2
element(1,0) = 3
element(1,1) = 4

Last modified on Sunday January 31, 1999 (21:03:06 EST) by Alan Baumgarten
email:
abaumg1@cs.umbc.edu

Back up to Spring 1999 CMSC-341 Section 1 and 2 Homepage