
/*****************************************************************************\

MODULE: matrix

SUMMARY:

The template-like class matrix(T) is used to
represent 2-dimensional matrices.
Each row is a vector(T) of the same length,
and any attempt to create a non-rectangular matrix
will raise an error.


\*****************************************************************************/

class matrix(T) {
   matrix(T)(); // initially 0 x 0

   matrix(T)(const matrix(T)& a);
   void operator=(const matrix(T)& a);
   ~matrix(T)();

   matrix(T)(INIT_SIZE_TYPE, long n, long m); // initially n x m

   void kill(); frre storage and make 0 x 0

   void SetDims(long n, long m); 
   // make n x m
   // If the number of columns changes, previous storage is freed;
   // otherwise, extra rows are allocated if necessary,
   // but any extra rows are retained, and the contents do not change.

   long NumRows() const;
   // number of rows

   long NumCols() const;
   // number of colums

   vector(T)& operator[](long i);
   const vector(T)& operator[](long i) const;
   // access row i, initial index 0

   vector(T)& operator()(long i);
   const vector(T)& operator()(long i) const;
   // access row i, initial index 1

   T& operator()(long i, long j);
   const T& operator()(long i, long j) const; 
   // access element (i, j), both indices starting at 1

   friend const vector(vector(T))& rep(const matrix(T)& a);
   // read-only access to underlying representation

};

void swap(matrix(T)& X, matrix(T)& Y);
// swaps X and Y (by swapping pointers)

void operator<<(matrix(T)& x, const vector(vector(T))& a);
// conversion operator

/*****************************************************************************\

                                     Input/Output

The I/O operators can be declared with matrix_io_decl(T),
and implemented using matrix_io_impl(T).
Elements are read and written using the underlying I/O operators
<< and >> for T.

\*****************************************************************************/


istream& operator>>(istream&, matrix(T)&);
ostream& operator<<(ostream&, const matrix(T)&); 

/*****************************************************************************\

                              Equality Testing

The equality testing operators == and != can be declared
with matrix_eq_decl(T) and implemented with matrix_eq_impl(T).

\*****************************************************************************/


long operator==(const matrix(T)& a, const matrix(T)& b);
long operator!=(const matrix(T)& a, const matrix(T)& b);

