/**************************************************************************\ MODULE: matrix SUMMARY: Matrix templates. 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 \**************************************************************************/ // EXCEPTIONS: all functions below do not throw any exceptions, // except as noted template<class T> class Mat { typedef typename Vec<T>::value_type value_type; typedef typename Vec<T>::reference reference; typedef typename Vec<T>::const_reference const_reference; Mat(); // initially 0 x 0 Mat(const Mat<T>& a); // copy constructor // EXCEPTIONS: may throw Mat& operator=(const Mat<T>& a); // assignment // EXCEPTIONS: may throw, weak ES (but dimensions of LHS // will be either that of old LHS or RHS) ~Mat(); // destructor Mat(Mat&& other) noexcept; #ifndef NTL_DISABLE_MOVE_ASSIGN Mat& operator=(Mat&& other) noexcept; #endif // move semantics (C++11 only) Mat(INIT_SIZE_TYPE, long n, long m); // Mat(INIT_SIZE, n, m) initializes an n x m matrix, invoking // the default constructor for T to initialize entries. // EXCEPTIONS: may throw 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. // EXCEPTIONS: strong ES (although underlying vector representation // may be reallocated) 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. // Even if one has read/write access to a row, any attempt // to change its length will raise an error. // EXCEPTIONS: may throw if range checking is turned on Vec<T>& operator()(long i); const Vec<T>& operator()(long i) const; // access row i, initial index 1. // Even if one has read/write access to a row, any attempt // to change its length will raise an error. // of this row will raise an error. // EXCEPTIONS: may throw if range checking is turned on reference operator()(long i, long j); const_reference operator()(long i, long j) const; // access element (i, j), both indices starting at 1 // EXCEPTIONS: may throw if range checking is turned on const_reference get(long i, long j) const; // access element (i, j), both indices starting at 0 // EXCEPTIONS: may throw if range checking is turned on void put(long i, long j, const T& a); // same as M[i].put(j, a) template <class U> void put(long i, long j, const U& a); // same as M[i].put(j, a) 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). long alias(const Vec<T>& a) const; // returns 1 if a aliases a row of the matrix, and 0 otherwise. void swap(Mat<T>& other); // quick swap *this and other void move(Mat<T>& other); // quick move other to *this }; template<class T> const Vec< Vec<T> >& rep(const Mat<T>& a); // read-only access to underlying representation template<class T> void swap(Mat<T>& X, Mat<T>& Y); // quick swap of X and Y template<class T> void MakeMatrix(Mat<T>& x, const vec_vec_T& a); // copies a to x, checking that it is "rectangular" // EXCEPTIONS: may thow, weak ES (but dimensions of x either // remain unchanged or are set to the new dimensions implied by a) /**************************************************************************\ Input/Output \**************************************************************************/ template<class T> istream& operator>>(istream&, Mat<T>&); // EXCEPTIONS: may throw, weak ES template<class T> ostream& operator<<(ostream&, const Mat<T>&); // EXCEPTIONS: may throw, weak ES /**************************************************************************\ Equality Testing \**************************************************************************/ template<class T> long operator==(const Mat<T>& a, const Mat<T>& b); template<class T> long operator!=(const Mat<T>& a, const Mat<T>& b);