Features


Versatile Matrix Addition and Subtraction

K.B. Williams

Even the simplest of matrix operations is easy to get wrong. Doing it right once and for all can really pay off.


Introduction

The function described in this article was born of necessity after I had been programming for some 18 years. I was assigned to two programming projects that required many matrix manipulations with transposes, additions, and subractions of vectors and matrices. One of the projects applied Kalman filtering to reentry missile tracking data. The other project involved reconstructing the track of the missile by second-order methods, again using Kalman techniques.

The program is called madsub (for matrix addition and subtraction) and was fashioned after matmpy, which I described in [1] .

In the years since I wrote madsub, I dont know what I would have done without it. I later wrote an interactive coordinate transformation program that involved some 25 transformations. Function madsub proved to be invaluable. Other projects have come up along the way that were ideally suited for madsubs capabilities. One project involved aircraft tracking and identification using Kalman filtering techniques (again).

I wrote the original in CDC Fortran, a dialect of Fortran IV. I later translated it to Ratfor and finally, to C.

Early versions of the program made no error checks on the consistency of dimensions given to the matrices involved. Big mistake. I added code to do the checking and added two parameters to the calling sequence to express the expected dimensions of the output matrix. For some reason I had trouble getting the dimensions right when adding and subtracting but no problems at all when multiplying. After making the changes, several of my users came to me and thanked me. It was good to know that I had company.

Using Function madsub

Function madsub can perform the following functions:

1. A + B (Matrix Sum) 
2. A + BT (T means transpose)
3. AT + B
4. AT + BT 
Matrix Difference (any of 1-4 Negative of Matrix Sum (any of 1-4 above)

The calling sequence is long but simple:

               
void madsub(A, I, J, B, K, L, C, M, N, TOPT, ROPT)

where A is the I x J augend matrix 
      B is the K x L addend matrix 
      C is the M x N result matrix

and TOPT and ROPT are option codes defined in matdefs.h

as follows:

TOPT (Transpose Option)
Code Operate On
AB   A & B (No Transposes)
ATB  AT & B
ABT  A & BT
ATBT AT & BT
 
ROPT (Result Option)
Code Operation
APB  A + B
AMB  A - B
MAMB -(A + B)

In a way, madsub has the flavor of Magic Matrix Multiply [1] because it handles the chore of transposing the matrices automatically with no extra memory required.

The code for madsub is shown in Listing 1. I made liberal use of the assert macro and NDEBUG to analyze and detect errors in dimension parameters. When NDEBUG is not defined, variables NumRowsA, NumColsA, NumRowsB, NumColsB are declared within the #ifndef clause. When NDEBUG is defined, I use the two assignments in the #else clause to keep the compiler from wagging its finger at me for not using parameters nra and nrb. The compiler should optimize these assignment statements out of existence.

The first two if/else statements set up the control variables for row and column operations. The first if/else sets up controls for the augend matrix, A. If caller has selected m1 as AB or ABT (defined in header file matdefs.h, Listing 2) madsubs indexing controls are set to handle matrix a in the normal fashion. If not (m1 is either ATB or ATBT), madsub accesses elements of matrix a as a transpose. The second if/else sets up similar controls for addend matrix b.

As you can see, Ive interspersed the consistency checks throughout the code. These should be activated at least during checkout.

The remainder of the code, following the two assert statements, shows how two-dimensional arrays are accessed as singly-dimensioned ones and how the transposing is effected through indexing controls. The inner for loop forms each sum (or difference), checks for complemented sum, and stores the result. Indexing controls are updated at the bottom of both inner and outer for loops.

Source Code

The source code that accompanies this article is available electonically (see page 3) and includes the following:

1. madsub.c — fully commented code (Listing 1)
2. matdefs.h — header file (Listing 2)
3. tstmadsb.c — a test driver
4. makefile — for generating test executable

To compile the test driver and madsub just say

    nmake
or  bmake
or  make

or whatever the name of your favorite make utility is. The makefile is set up to use Microsoft C/C++ but a simple change will enable you to do your thing with any other compiler.

Reference

1. K. B. Williams. "Magic Matrix Multiply," C/C++ Users Journal, June: 1995, pp. 19-24.

K.B. Williams received a B.A. in Mathematics from California State University at Sacramento in 1955. He is a veteran of forty years in the scientific applications programming trenches and is the founder of King Baker Enterprises, in Stillwater, Oklahoma. He consults in applied numeric techniques. He can be reach at 802 South Ridge Drive, Stillwater, OK 74074, or via e-mail at Kbwms@aol.com.