A Matrix Class

This class illustrates a simple matrix class. Like the vector class, the matrix class overloads the indexing and insertor operators. This class also defines a slicing function. In contrast to slicing function for the vector class, every matrix renames its elements to start at (0,0).

Notice that indexing is done one step at a time. To make this work correctly, we had to define a subclass, mat_row to be the result of indexing a matrix. This subclass only defines a constructor and an indexing operation.

//
// matrix.C
//
// a simple matrix package to illustrate the fundamental ideas that
//  would be implemented in a real matrix package.
//
//
// A. B. Maccabe
// March 11, 1997
//


#include <assert.h>
#include <iostream.h>
#include <iomanip.h>

class Matrix {
public:
    // a constructor -- you must know the size when you 
    // construct a matrix
    Matrix( int r, int c ) {
	nrows = r;
	ncols = c;
	col_start = 0;
	true_cols = ncols;
	data = new double [r*c];
    }

    friend Matrix operator +( Matrix x, Matrix y ) {
	assert( x.nrows==x.nrows && x.ncols==x.ncols );

	Matrix res(x.nrows, x.ncols);
	
	for( int row = 0 ; row < x.nrows ; row++ ) {
	    for( int col = 0 ; col < x.ncols ; col++ ) {
	        // fill in the details
	    }
	}

	return res;
    };



    // a subclass for indexing
    class mat_row {
    public:
	// constructor
	mat_row( int n, double *dat ) {
	    ncols = n;
	    data = dat;
	};
	
	double& operator []( int indx ) {
	    assert( 0<=indx && indx<ncols );
	    return data[indx];
	}
	
    private:
	int ncols;
	double *data;
    };
    
    mat_row operator []( int indx ) {
	assert( 0<=indx && indx<nrows );
	
	return mat_row( ncols, &data[true_cols*indx + col_start] );
    };
	
    
    Matrix slice( int start_row, int start_col, int rows, int cols ) {
	assert( 0<=start_row && 0<=rows && start_row+rows<=nrows );
	assert( 0<=start_col && 0<=cols && start_col+cols<=ncols );

	Matrix res( &data[start_row*true_cols], rows, cols, 
		    start_col+col_start, true_cols );
	return res;
    };


    friend ostream& operator <<( ostream& os, Matrix m ) {
	int indx = m.col_start;
	
	for( int i = 0 ; i < m.nrows ; i++ ) {
	    for( int j = 0 ; j < m.ncols ; j++ ) {
		os << setw(4) << m.data[indx++];
	    }
	    indx += m.true_cols - m.ncols;
	    os << endl;
	}
	return os;
    };
    
private:

    // a private constructor
    Matrix( double *dat, int rows, int cols, int cstart, int tcols ) {
	data = dat;
	nrows = rows;
	ncols = cols;
	col_start = cstart;
	true_cols = tcols;
    };
	    

    int nrows, ncols;
    double *data;
    int col_start, true_cols;
};



int main( ) {
    Matrix m1(7,7);

    for( int i = 0 ; i < 7 ; i++ ) {
	for( int j = 0 ; j < 7 ; j++ ) {
	    m1[i][j] = 7;
	}
    }

    cout << m1 << endl;

    Matrix m2 = m1.slice( 1, 1, 4, 5 );
    cout << m2 << endl;

    for( int i = 0 ; i < 4 ; i++ ) {
	for( int j = 0 ; j < 5 ; j++ ) {
	    m2[i][j] = 3;
	}
    }
    
    cout << m1 << endl;


    Matrix m3 = m2.slice( 1, 1, 3, 2 );
    cout << m3 << endl;
    for( int i = 0 ; i < 3 ; i++ ) {
	for( int j = 0 ; j < 2 ; j++ ) {
	    m3[i][j] = 5;
	}
    }
    
    cout << m1 << endl;
}


Barney Maccabe
Last modified: Wed Apr 2 15:15:07 MST