Matrices occur throughout mathematics, and pop up often in engineering computations. A simple template matrix class lets you manipulate matrix objects with a safe and convenient notation.
Introduction
I build scientific, mathematically intense programs for a living, and I find that matrices, like integers, floats, and complex numbers, are indispensable building blocks. I prefer matrices (rectangular, two-dimensional collections of scalars) over vectors (one-dimensional collections of scalars) because matrices are more robust. Row and column vectors can be viewed as merely degenerate matrices.
The Matrix Class
The Matrix class is based on a templatized Array class. Listing 1 shows Array's definition and part of its implementation. The Matrix class (Listing 2) declares a private member which is an Array.
Using the Matrix class, I can write code in a syntax that mimics standard math notation. Thus, the matrixbecomes
Matrix<float> A(2,2); A(0,0) = 1; A(0,1) = 2; A(1,0) = 3; A(1,1) = 4;in C++, and the column vector
becomes
Matrix<float> x(2,1); x(0,0) = 1; x(1,0) = 2;
Note that the constructor's arguments are the number of rows and columns, not element values. To set element values, I use the parentheses operator (Listing 2) . Matrix's parenthesis operator calls Array's operator[]. Array's operator[] takes a single index, so Matrix's operator() must translate rows and columns to this single index. Also, the Matrix elements' indices are zero based.
Perhaps the initializations don't look too much like standard notation, but the resemblance improves when I use the overloaded math operators. The Matrix class supplies overloaded operators for some of the most common matrix operations. First, matrices may be multiplied and divided by scalars. So, for example, the matrix equationy = x/2
becomes
Matrix<float> y = x/2;Second, matrices with equal dimensions may be added and subtracted. The equation
C = A - B
becomesMatrix<float> C = A - B;
Third, two matrices may be multiplied if the number of columns of the first matrix equals the number of rows of the second. The equation
y = A x x
becomesy = A * xThis is the inner product of linear algebra. Listing 2 shows the implementation of operator*() with two Matrix agruments.
The Matrix class also defines negation and transpose operators. The statement
y = -x
becomesy = -x;and equals
The statement
y = xT
becomes
y= ~x;
and equalsComparing this row vector with its conjugate column vector, you may think that because they have the same elements they are equal. They are not. Two matrices are equal only if they have the same element in each position, which also implies that they must have the same number of rows and the same number of columns.
The Matrix class defines equality and inequality operators, as well as the assignment operator. Matrix's operator==() and operator=() both appear in Listing 2. Note that while Matrix's operator=() simply calls Array's, Matrix's operator==() does not call Array's operator==().
The matrix class also provides a few utility functions. For example, I can get the number of rows and columns:int nRows = A.Rows(); int nCols = A.Columns();I also can get individual rows and columns:
Matrix<float> row = A.Row(0); Matrix<float> col = A.Column(1);Last, I can set individual rows and columns:
A.SetRow(0, row); A.SetColumn(1, col);Conclusion
I have used matrices to solve systems of equations. I have also used tables of matrices to define missile trajectories. I have even used the Matrix class as a base class for image processing. In short, the Matrix class is one of the most valuable members of my software toolbox. I hope you'll use it too.
Stephen O. Schulist has an M.S. in Physics from UCLA and is a Staff Scientist at Aero Optics, an aerospace consulting firm in Los Angeles. He has been programming C++ for three years and may be reached at sos@aero-optics.com.