3.4. Matrix<T>

This is a templatized class for viewing data as a matrix. A matrix, in general, does not have its own data. Instead, it views a block of data in a certain way. It is therefore possible to have multiple matrices and vectors that view the same data. Class T must have a public default constructor, copy constructor, destructor, and assignment operator. Many of the operators and member functions will only work for types that behave like standard numeric types.

3.4.1. Constructors.

Matrix<T>()

This constructs an empty matrix.

Matrix<T>(size_t n, size_t m)

This constructor creates a matrix of n rows and m columns. If T is a standard numeric type, pointer, or any type without a constructor, including std::complex<T>, then the matrix will be initialized to zero. If not, then the elements are initialized with a default constructed object. This constructor uses the Zero<T>() function to obtain the value to initialize to. Use of this contructor is therefore equivelent to Matrix<T> x(Zero<T>(), n, m).

Matrix<T>(NoInit, size_t n, size_t m)

This constructor creates a matrix of n rows and m columns, with each element initialized with the default constructor of class T. If class T has a specialized version of the VMTraits<T> structure, with the flag is_simple set to true, then the elements will not be initialized at all. This flag is set for all the standard numeric types, including std::complex<float> and std::complex<double>.

Matrix<T>(const T& a, size_t n, size_t m)

This creates a matrix of n rows and m columns, with each element initialized to the value a. This initialization is done through the copy constructor of class T.

Matrix<T>(const T* a, size_t n, size_t m, ptrdiff_t s = 1)

This creates a matrix of n rows and m columns from a C-style array given by the pointer a. The data is copied in row major order, and it is up to the user to make sure the array actually has n * m elements. Copying is done with the copy constructor of type T. The optional parameter s allows for copying from arrays with strides other than one.

Matrix<T>(const Matrix<T>& rhs)

The copy constructor makes a shallow copy of the matrix rhs. This means that it views the same data as rhs, in exactly the same way. The primary purpose of this constructor is for making permanent versions of returned temporary matrices, for example:

Mat_DP x(4.5, 10, 5), y(2.5, 10, 5);

Mat_DP z(x + y);

Matrix<complex<T> >(const Matrix<T>& re, const Matrix<T>& im)

This creates a complex matrix from two real matrices. It will only work properly for the following types: float and double.

Matrix<complex<T> >(const Matrix<T>& re, const T& im)

This creates a complex matrix from a real matrix, and a scalar. It also only works for the types above.

3.4.2. Member functions.

Matrix<T>& apply(T (*fn)(T x))

This function applies the function fn to each element of the matrix it is called for. The function must take one argument of type T, and return a value that can be cast to type T. This member function returns itself by reference, allowing for cascading.

Matrix<T>& apply(T (*fn)(const T& x))

This function applies the function fn to each element of the matrix it is called for. The function must take one argument of type T&, and return a value that can be cast to type T. This member function returns itself by reference, allowing for cascading.

Matrix<T> copy() const

This function returns a deep copy of the matrix it is called for. This means that the returned matrix will be the only object referencing its data, and that its column stride will be one, and its row stride will be equal to the number of columns. Copying is done with the copy constructor of type T.

bool isdeap() const

Returns true if the following criteria are met:

If any of these criteria are not met, false is returned.

void makedeep()

This function causes a matrix to become a deep copy of itself. It now references its own data, has a row-stride equal to its number of columns, and a column-stride of one. Its original data is not changed, although it is deallocated if the matrix it is called for is the only object referencing it. If new memory is allocated, then copying is done with the copy constructor of type T.

void reference(const Matrix<T>& x)

This causes the matrix it is called for to become a shallow copy of x. This is very useful for setting a matrix to a returned temporary, for example:

Mat_INT x(2, 10, 20), y;

y.reference(x + 2);

void free()

This sets the size of the matrix to zero (zero rows and zero columns). If the matrix is the only object referencing its data, the data is deallocated.

void reshape(size_t n, size_t m)

This changes the dimensions of the matrix to (n, m). The matrix no longer views its old data. Instead, it has new data of its own. The new values are initialized with the Zero<T>() function, using the copy constructor of type T.

void resize(size_t n, size_t m)

The same as reshape(), except that the data is copied. If the matrix is made shorter along either dimension, then the copied data is truncated. If it is made larger in either of its dimensions, then the new values will be initialized with the Zero<T>() function. Copying is done with the copy constructor of type T.

Matrix submatrix(size_t rb, size_t cb, size_t rn, size_t cn, ptrdiff_t rs, ptrdiff_t cs) const

This returns a new view of the data that is a submatrix of the current view. (rb, cb) is the element that the submatrix should start with, rn and cn are the dimensions of the submatrix, and rs and cs are the number of rows and columns to skip between rows and columns of the submatrix. Note that rs and cs can be negative. For example, the following views a matrix in reverse order:

Mat_DP x(10, 20);

Mat_DP y = x.submatrix(9, 19, 10, 20, -1, -1);

Matrix<T> real() const

This returns the real part of a complex<T> matrix. Note that this returns a deep copy. It is not possible to view the real and imaginary parts of complex matrices as real matrices. This function is only defined for complex<float> and complex<double>. Attempting to use it with other complex types, or with non-complex types, will almost certainly result in compiler errors.

Matrix<T> imag() const

This returns the imaginary part of a complex<T> matrix. The same limitations apply as for real().

size_t nrows() const

This returns the number of rows.

size_t ncols() const

This returns the number of columns.

ptrdiff_t rstride() const

This returns the row-stride of the matrix.

ptrdiff_t cstride() const

This returns the column-stride of the matrix.

T* data()

This returns a pointer to the beginning of the matrix's data. It is up to the user to keep track of the row and column stride.

const T* data() const

The constant version of this member function returns a constant pointer.

Matrix<T> transpose() const

This returns a view of the transpose of the matrix.

Vector<T> row(size_t i) const

This creates a vector view of the ith row of the matrix.

Vector<T> column(size_t j) const

This creates a vector view of the jth column of the matrix.

Vector<T> unwrap() const

This takes a matrix that is in contiguous order, and creates a vector view. This vector will view the matrix such that V[i*M.ncols()+j] = M(i, j). This requires that M.rstride() == M.cstride() * M.ncols().

Vector<T>::iterator rbegin(size_t i)

This returns an iterator to the beginning of row i of the matrix.

Vector<T>::iterator rend(size_t i)

This returns an iterator to the end of row i of the matrix.

Vector<T>::iterator cbegin(size_t j)

This returns an iterator to the beginning of column j of the matrix.

Vector<T>::iterator cend(size_t j)

This returns an iterator to the end of column j of the matrix.

Vector<T>::const_iterator rbegin(size_t i) const

This returns a constant iterator to the beginning of row i of the matrix.

Vector<T>::const_iterator rend(size_t i) const

This returns a constant iterator to the end of row i of the matrix.

Vector<T>::const_iterator cbegin(size_t j) const

This returns a constant iterator to the beginning of column j of the matrix.

Vector<T>::const_iterator cend(size_t j) const

This returns a constant iterator to the end of column j of the matrix.

void read(istream& in)

This reads the contents of a stream into the matrix. The matrix is reshaped to a base size of one row with 1024 columns, and if this is insufficient for reading in the entire stream, the matrix is resized by a factor of two, and so on. When the full stream is read in, the matrix is resized, if necessary, to the number of elements read. This results in the stream being read to the end, so you may need to use the clear() member function if you wish to continue using the stream. The final result is a matrix with one row.

void read(istream& in, size_t ncount)

This reads the contents of a stream into the matrix. The matrix is reshaped to size (1, ncount), and the stream is read in until either the end of the stream is reached, or until ncount elements have been read. When the full stream is read in, the matrix is resized, if necessary, to the number of elements read. This function may result in the stream being read to the end, so you may need to use the clear() member function if you wish to continue using the stream. The final result is a matrix with one row.

void write(ostream& out) const

This outputs the contents of the matrix to a stream in row major form. The rows are separated with a carriage return delimiter, and elements of the row are separated by a tab delimiter. To output in column major form, simply call this function for a transpose view of the matrix.

template <class G> Matrix<T>& fill(const G& gen)

This function fills the matrix with values from the generator gen. Class G must have a function call operator which takes no arguments, and returns a value that can be cast to type T. This includes the four random number generator classes BaseGen, IntGen, UniformGen, and NormalGen. Ordinary function pointers can be passed as well, but note that the compiler will not be able to resolve the function if it is overloaded. This member function returns itself by reference, allowing for cascading.

template <class G> Matrix<T>& fill2(const F& fn)

This function applies the function object fn to each element of the matrix it is called for. Class F must have a function call operator which takes one argument of type T, and returns a value that can be cast to type T. Ordinary function pointers can be passed as well, but note that the compiler will not be able to resolve the function if it is overloaded. This member function returns itself by reference, allowing for cascading.

template <class U> Matrix<U> convert(const U& a) const

This creates a matrix of type U from a matrix of type T. It must be possible to explicitly cast type T to type U. a is a dummy value that is used simply to tell the compiler what type to convert to. Example:

Mat_DP x(4.5, 10, 4);

Mat_SP y = x.convert(float());

template <class U> Matrix<U> shallow_cast(const U& a) const

This creates a shallow copy of the matrix it is called for, but of type Matrix<U>. This is done using pointer casting, which means the new matrix views the same data as the original, but views it as data of type U instead of as type T. For example, the internal representation if int and long is the same on many platforms. This function allows you to view a matrix of type int as a matrix of type long, without making a seperate copy of the data. If used for non-standard types with non-trivial constructors, this function has the potential to cause some serious bugs, since the wrong destructor may be called to destroy the matrix elements. Types T and U must have the same size.

3.4.3. Overloaded operators.

Matrix<T>& operator=(const Matrix<T>& rhs)

This uses the assignment operator of type T to do an element-by-element copy of rhs to the matrix it is called for, which is the left hand side of the expression. The matrices must have the same dimensions.

Matrix<T>& operator=(const T& rhs)

This uses the assignment operator of type T to copy rhs to each element of the matrix it is called for.

Matrix<T>& operator+=(const Matrix<T>& rhs)

Matrix<T>& operator-=(const Matrix<T>& rhs)

Matrix<T>& operator*=(const Matrix<T>& rhs)

Matrix<T>& operator/=(const Matrix<T>& rhs)

Matrix<T>& operator%=(const Matrix<T>& rhs)

Matrix<T>& operator&=(const Matrix<T>& rhs)

Matrix<T>& operator^=(const Matrix<T>& rhs)

Matrix<T>& operator|=(const Matrix<T>& rhs)

Matrix<T>& operator>>=(const Matrix<T>& rhs)

Matrix<T>& operator<<=(const Matrix<T>& rhs)

These operators use the arithmetic assignment operators of type T to do element-by-element arithmetic assignment. The matrices must have the same dimensions.

Matrix<T>& operator+=(const T& rhs),

Matrix<T>& operator-=(const T& rhs),

Matrix<T>& operator*=(const T& rhs),

Matrix<T>& operator/=(const T& rhs),

Matrix<T>& operator%=(const T& rhs),

Matrix<T>& operator&=(const T& rhs),

Matrix<T>& operator^=(const T& rhs),

Matrix<T>& operator|=(const T& rhs),

Matrix<T>& operator>>=(const T& rhs),

Matrix<T>& operator<<=(const T& rhs),

These operators use the arithmetic assignment operators of type T to perform the corrosponding operation on the matrix.

Matrix<T> operator+() const

This returns a matrix such that each element is the result of applying the unary + operator to each element of the original matrix. This operator must be available for type T.

Matrix<T> operator-() const

This returns a matrix such that each element is the negation of the original value. The unary - operator must be available for type T.

Matrix<bool> operator!() const

This returns a matrix of bool values such that B(i, j) = !M(i, j), where B is the returned matrix, and M is the original matrix. This operator must be available for type T.

Matrix<T> operator~() const

This returns a matrix by applying the ~ operator to each element. This operator must be available for type T.

T& operator()(size_t i, size_t j)

Indexing. This returns a reference to the (i, j) element of the matrix.

const T& operator()(size_t i, size_t j) const

The constant version of this operator returns a constant reference.

Vector<T>::iterator operator[](size_t i)

This returns an iterator to the ith row of the matrix. This is identical to the rbegin() member function, except that bounds-checking on the row is only done if bounds-checking is enabled. It is provided to facilitate C-style indexing. Example:

Mat_DP x(10,20);

UniformGen gen(0);

x.fill(gen);

cout << x[5][4];

This is less efficient that using the () operator, and is included to allow compatibility with software like Numerical Recipes in C++.

Vector<T>::const_iterator operator[](size_t i) const

The constant version of this operator returns a constant iterator.

3.4.4. Global Functions.

These functions mimic the Standard Library functions of the same name, performing the associated operation on every element of the matrix.

Matrix<T> abs(const Matrix<T>& x)

Matrix<T> abs(const Matrix<complex<T> >& x)

Matrix<T> acos(const Matrix<T>& x)

Matrix<T> asin(const Matrix<T>& x)

Matrix<T> atan(const Matrix<T>& x)

Matrix<T> atan2(const Matrix<T>& x, const Matrix<T>& y)

Matrix<T> atan2(const Matrix<T>& x, const T& y)

Matrix<T> atan2(const T& x, const Matrix<T>& y)

Matrix<T> cos(const Matrix<T>& x)

Matrix<T> cosh(const Matrix<T>& x)

Matrix<T> exp(const Matrix<T>& x)

Matrix<T> log(const Matrix<T>& x)

Matrix<T> log10(const Matrix<T>& x)

Matrix<T> pow(const Matrix<T>& x, const Matrix<T>& y)

Matrix<T> pow(const Matrix<T>& x, const T& y)

Matrix<T> pow(const T& x, const Matrix<T>& y)

Matrix<T> sin(const Matrix<T>& x)

Matrix<T> sinh(const Matrix<T>& x)

Matrix<T> sqrt(const Matrix<T>& x)

Matrix<T> tan(const Matrix<T>& x)

Matrix<T> tanh(const Matrix<T>& x)

Matrix<T> arg(const Matrix<complex<T> >& x)

Matrix<T> norm(const Matrix<complex<T> >& x)

Matrix<complex<T> > polar(const Matrix<T>& rho, const Matrix<T>& theta)

Matrix<complex<T> > polar(const Matrix<T>& rho, const T& theta)

Matrix<complex<T> > polar(const T& rho, const Matrix<T>& theta)

Matrix<complex<T> > conj(const Matrix<complex<T> >& x)

Matrix<T> real(const Matrix<complex<T> >& x)

Matrix<T> imag(const Matrix<complex<T> >& x)

Note that the real() and imag() functions only work for complex types with a specialization of the VMTraits<T> structure. Similarly, the complex version of the abs() function only works for these types. Attempting to use these functions for other types will probably result in compiler errors.

3.4.5. Global Operators.

Binary Operators For Two Matrices.

These operators perform the associated operation element by element. The two matricess must have the same size. The result is a new matrix with the appropriate values.

Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator-(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator*(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator/(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator%(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator&(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator^(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator|(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator<<(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<T> operator>>(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<bool> operator==(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<bool> operator!=(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<bool> operator<(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<bool> operator>(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<bool> operator<=(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<bool> operator>=(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<bool> operator&&(const Matrix<T>& lhs, const Matrix<T>& rhs)

Matrix<bool> operator||(const Matrix<T>& lhs, const Matrix<T>& rhs)

These operators perform the associated operation element-by-element. The two matrices must have the same dimensions. The result is a new matrix with the appropriate values.

Binary Operators for Matrices and Scalers.

These operators perform the associated operation element-by-element with a scalar. The result is a new matrix with the appropriate values.

Matrix<T> operator+(const Matrix<T>& lhs, const T& a)

Matrix<T> operator+(const T& a, const Matrix<T>& rhs)

Matrix<T> operator-(const Matrix<T>& lhs, const T& a)

Matrix<T> operator-(const T& a, const Matrix<T>& rhs)

Matrix<T> operator*(const Matrix<T>& lhs, const T& a)

Matrix<T> operator*(const T& a, const Matrix<T>& rhs)

Matrix<T> operator/(const Matrix<T>& lhs, const T& a)

Matrix<T> operator/(const T& a, const Matrix<T>& rhs)

Matrix<T> operator%(const Matrix<T>& lhs, const T& a)

Matrix<T> operator%(const T& a, const Matrix<T>& rhs)

Matrix<T> operator&(const Matrix<T>& lhs, const T& a)

Matrix<T> operator&(const T& a, const Matrix<T>& rhs)

Matrix<T> operator^(const Matrix<T>& lhs, const T& a)

Matrix<T> operator^(const T& a, const Matrix<T>& rhs)

Matrix<T> operator|(const Matrix<T>& lhs, const T& a)

Matrix<T> operator|(const T& a, const Matrix<T>& rhs)

Matrix<T> operator<<(const Matrix<T>& lhs, const T& a)

Matrix<T> operator<<(const T& a, const Matrix<T>& rhs)

Matrix<T> operator>>(const Matrix<T>& lhs, const T& a)

Matrix<T> operator>>(const T& a, const Matrix<T>& rhs)

Matrix<bool> operator==(const Matrix<T>& lhs, const T& a)

Matrix<bool> operator==(const T& a, const Matrix<T>& rhs)

Matrix<bool> operator!=(const Matrix<T>& lhs, const T& a)

Matrix<bool> operator!=(const T& a, const Matrix<T>& rhs)

Matrix<bool> operator<(const Matrix<T>& lhs, const T& a)

Matrix<bool> operator<(const T& a, const Matrix<T>& rhs)

Matrix<bool> operator>(const Matrix<T>& lhs, const T& a)

Matrix<bool> operator>(const T& a, const Matrix<T>& rhs)

Matrix<bool> operator<=(const Matrix<T>& lhs, const T& a)

Matrix<bool> operator<=(const T& a, const Matrix<T>& rhs)

Matrix<bool> operator>=(const Matrix<T>& lhs, const T& a)

Matrix<bool> operator>=(const T& a, const Matrix<T>& rhs)

Matrix<bool> operator&&(const Matrix<T>& lhs, const T& a)

Matrix<bool> operator&&(const T& a, const Matrix<T>& rhs)

Matrix<bool> operator||(const Matrix<T>& lhs, const T& a)

Matrix<bool> operator||(const T& a, const Matrix<T>& rhs)

Streaming IO Operators.

These operators provide insertion and extraction operators for using matrices with iostreams. The corresponding operators must exist for type T.

ostream& operator<<(ostream& out, const Matrix<T>& x)

This functions identically to the write() member function, except that it returns a reference to the stream, for cascading.

istream& operator>>(istream& in, Matrix<T>& x)

This reads a stream into a matrix. Unlike the read() member function, this does not reshape the matrix. It simply reads in from the stream until either the stream ends, or the end of the matrix is reached. Data is read in row major form. To read in column major form, simply pass the operator a transpose view of the matrix.

Next Section

Back to Classes