Arithmetic Friend Functions

Addition, subtraction, unary minus, elementwise multiplication, elementwise division, and matrix multiplication is supported through friend functions. The functions allow scalar arguments as left or right operands. The only unusual feature of these operators is the elementwise multiplication is called using the '%' (ampersand) operator. They all return VMatrix references. See Shildt[#!sh:c++!#] for an explanation of how and why friend functions are needed to overload these functions.

In general, these functions follow the same precedence as the standard functions on doubles. They also produce intermediate values on the stack. The code for addition is given by

VMatrix& operator+ (VMatrix &LOp, VMatrix &ROp)
  {
    LOp.Garbage("operator +");
    ROp.Garbage("operator +");
    if (LOp.r==ROp.r && LOp.c==ROp.c) {
      VMatrix *temp = new VMatrix("(", LOp.r, ROp.c);
      for (int i=1; i<=LOp.r; ++i) {
          for (int j=1; j<=ROp.c; ++j) {
              temp->M(i,j) = LOp.m(i,j) + ROp.m(i,j);
          }
      }
      temp->name = temp->name+LOp.name+"+"+ROp.name+")";
      Dispatch->Push(*temp);
      delete temp;
    }
  else ROp.Nrerror("Mismatched Matrix sizes in addition function\n");
  return Dispatch->ReturnMat();
  }
The function first checks the validity of its operands. It also checks that the matrices are conformable. If they are, a new matrix is put on the heap. The matrices are summed. Note the use of the little m(i,j) on the right side of the sum, and the M(i,j) on the left. The name is created. The matrix is pushed onto the stack, then deleted.

The reference returned is the matrix pointed to by Dispatch->next. The function ReturnMat() passes the matrix reference, and does not change the function nesting level. Basically, the nesting level keeps track of the function depth where addition was called. Also, Cleanstack() uses the nesting level to determine which matrices to strip from the stack. System functions should use ReturnMat() rather than DecReturn(). DecReturn() decrements the nesting level, then returns the correct matrix reference. More about this in the next chapter. The way to tell when to use DecReturn() is if you enter the function and call Inclevel(). Call DecReturn() if you called Inclevel(). Using the stack allows the functions to be recursive.