//---------------------------------------------------------------- // vmatrix.h // // Defines a dynamically allocated matrix of fractions. // // programmer: ALLAN CRUSE // written on: 15 SEP 1992 // revised on: 28 NOV 2002 // revised on: 28 APR 2011 -- added public 'obtain()' method // revised on: 29 APR 2011 -- corrected input-prompt message //---------------------------------------------------------------- #include "fraction.h" class FractionMatrix { Fraction *tableau; unsigned int nrows, ncols; unsigned int locn( unsigned int r, unsigned int k ); public: FractionMatrix( int r, int k ); // default constructor ~FractionMatrix( void ) { delete [] tableau; } Fraction obtain( unsigned int i, unsigned int j ); void assign( unsigned int i, unsigned int j, Fraction f ); void exchange_rows( int i, int j ); void rescale_row( Fraction x, int i ); void combine_rows( Fraction x, int i, int j ); int row_reduced( Fraction& determinant ); friend ostream& operator << ( ostream& s, FractionMatrix& a ); friend istream& operator >> ( istream& s, FractionMatrix& a ); }; inline unsigned int FractionMatrix::locn( unsigned int r, unsigned int k ) { return k + ncols * r; } FractionMatrix::FractionMatrix( int r, int k ) { unsigned int size; nrows = ( r > 0 ) ? r : 0; ncols = ( k > 0 ) ? k : 0; size = nrows * ncols; tableau = new Fraction[ size ]; } void FractionMatrix::exchange_rows( int i, int j ) { Fraction temp; for (int k = 0; k < ncols; k++) { temp = tableau[ locn(i,k) ]; tableau[ locn(i,k) ] = tableau[ locn(j,k) ]; tableau[ locn(j,k) ] = temp; } } void FractionMatrix::rescale_row( Fraction x, int i ) { if ( x == 0 ) return; for (int k = 0; k < ncols; k++) tableau[ locn(i,k) ] /= x; } void FractionMatrix::combine_rows( Fraction x, int i, int j ) { for (int k = 0; k < ncols; k++) tableau[ locn(j,k) ] -= x * tableau[ locn(i,k) ]; } int FractionMatrix::row_reduced( Fraction& determinant ) { int r = 0, k = 0; // dimensions of row-reduced submatrix while (( r < nrows )&&( k < ncols )) { int u = r; // scan the next unreduced submatrix while (( tableau[ locn(u,k) ] == 0 )&&( ++u < nrows )); if (( u == nrows )&&( ++k < ncols )) continue; if ( k == ncols ) { determinant = 0; break; } Fraction x = tableau[ locn(u,k) ]; if ( x != 1 ) { rescale_row( x, u ); determinant *= x; return 0; } if ( u > r ) { exchange_rows( u, r ); determinant *= -1; return 0; } for (int i = 0; i < nrows; i++) if (( i != u )&&( (x = tableau[ locn(i,k) ] )!= 0 )) { combine_rows( x, u, i ); return 0; } ++r; } return 1; } Fraction FractionMatrix::obtain( unsigned int i, unsigned int j ) { if (( i < nrows )&&( j < ncols )) return this->tableau[ locn(i,j) ]; else return 0; } void FractionMatrix::assign( unsigned int i, unsigned int j, Fraction f ) { if (( i < nrows )&&( j < ncols )) this->tableau[ locn(i,j) ] = f; } ostream& operator << ( ostream& s, FractionMatrix& a ) { for (int i = 0; i < a.nrows; i++) { s << endl; for (int j = 0; j < a.ncols; j++) s << a.tableau[ a.locn(i,j) ] << "\t"; } s << endl; return s; } istream& operator >> ( istream& s, FractionMatrix& a ) { // input the matrix-entries by rows for (int i = 0; i < a.nrows; i++) { cout << "\nEnter vector-components for "; cout << "for row-vector #" << 1+i << ":\n" << endl; for (int j = 0; j < a.ncols; j++) { Fraction x; cin >> x; a.assign( i, j, x ); } cout << endl; } return s; }