/**************************************************************************\ MODULE: matrix SUMMARY: Macros are deined providing template-like classes for dynamic-sized, recatngular matrices. The macro NTL_matrix_decl(T,vec_T,vec_vec_T,mat_T) declares a new class mat_T representing matrices over T, where vec_T and vec_vec_T are classes representing "NTL vectors" over T and vec_T, respectively. The implementation of mat_T can be instantiated with NTL_matrix_impl(T,vec_T,vec_vec_T,mat_T). If T supports I/O and/or equluality testing, then mat_T can also be made to support these. For example, the declaration mat_T M; creates a 0 x 0 matrix. We can make it have 10 rows and 20 columns like this: M.SetDims(10, 20); A row can be accessed as M[i], indexing from 0, or as M(i), indexing from 1. A matrix entry can be accessed as M[i][j], indexing from 0, or as M(i, j), indexing from 1. A matrix is represented as a vec_vec_T: a vector of rows, where each row is a vec_T. Any attempt to resize one of the rows so as to create a non-rectangular matrix will result in a run-time error. The dimensions of an existing matrix may be changed. If the number of columns does not change, then the matrix is just "resized" like a vector, and no information is lost. Otherwise, if the number of columns changes, the matrix is completely destroyed, and a new matrix is created \**************************************************************************/ class mat_T { mat_T(); // initially 0 x 0 mat_T(const mat_T& a); mat_T& operator=(const mat_T& a); ~mat_T(); mat_T(INIT_SIZE_TYPE, long n, long m); // mat_T(INIT_SIZE, n, m) initializes an n x m matrix, invoking // the default constructor for T to initialize entries. void SetDims(long n, long m); // M.SetDims(n, m) makes M have dimension n x m. If the number of // columns (m) changes, previous storage is freed, and space for M // is reallocated and initialized; otherwise, more rows are // allocated as necessary (when number of rows increases), // excess rows are retained (when number of rows decreases), // and--importantly--the contents do not change. void kill(); free storage and make 0 x 0 long NumRows() const; // M.NumRows() returns the number of rows of M long NumCols() const; // M.NumCols() returns the number of columns of M vec_T& operator[](long i); const vec_T& operator[](long i) const; // access row i, initial index 0. Any attempt to change the length // of this row will raise an error. vec_T& operator()(long i); const vec_T& operator()(long i) const; // access row i, initial index 1. Any attempt to change the length // of this row will raise an error. T& operator()(long i, long j); const T& operator()(long i, long j) const; // access element (i, j), both indices starting at 1 long position(const vec_T& a) const; // returns index of a in matrix, or -1 if not present; // equivalent to rep(*this).position(a). long position1(const vec_T& a) const; // returns index of a in matrix, or -1 if not present; // equivalent to rep(*this).position1(a). }; const vec_vec_T& rep(const mat_T& a); // read-only access to underlying representation void swap(mat_T& X, mat_T& Y); // swaps X and Y (by swapping pointers) void MakeMatrix(mat_T& x, const vec_vec_T& a); // copies a to x, checking that it is "rectangular" /**************************************************************************\ Input/Output The I/O operators can be declared with NTL_io_matrix_decl(T,vec_T,vec_vec_T,mat_T), and implemented using NTL_io_matrix_impl(T,vec_T,vec_vec_T,mat_T). I/O is implemented using the underlying I/O operators for vec_vec_T. \**************************************************************************/ istream& operator>>(istream&, mat_T&); ostream& operator<<(ostream&, const mat_T&); /**************************************************************************\ Equality Testing The equality testing operators == and != can be declared NTL_eq_matrix_decl(T,vec_T,vec_vec_T,mat_T), and implemented using NTL_eq_matrix_impl(T,vec_T,vec_vec_T,mat_T). Equality testing is implemented using the underlying equality operators for vec_vec_T. \**************************************************************************/ long operator==(const mat_T& a, const mat_T& b); long operator!=(const mat_T& a, const mat_T& b);