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.
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:
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; }
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); };
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; }
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