
Covariant type conformance is used in member functions.  This is
indicated with the "current" type which is the type of the
overriding class.  Note that current might not be exactly the same
type.  It might be a implementation of a diagonal matrix corresponding
to current, for example.

Matrix multiplication is a bit of a mess because of the way the different
types of matrices get involved.  Say G=general, S=symmetric, and D=diagonal,
then we get the following possible mxm accumulation routines: G+=G*G, G+=S*S,
D+=D*D, G+=D*D, G+=G*S, G+=S*G, G+=G*D, G+=D*G, G+=S*D, G+=D*S, and S+=Sa*Sb
if [Sa,Sb] = 0  (I use accumulation routines so storage isn't allocated
unnecessarily where it isn't needed).  Not all of these will be implemented
in a given matrix implementation, so, unfortunately, there can be runtime
type errors.

The various accumulation routines are G+=G, G+=S, G+=D, S+=S, S+=D, and D+=D.

Generic operations on matrices are done with the following:
A->element_op(op)
  For all elements in A do op.

A->matrix_op(B,op)
  For all elements in A
   For all elements in B
     do op.

A->matrix_pair_op(B,C,D,op)
  For all elements in (A,B)
   For all elements in (C,D)
     do op.
(A and B must have exactly the same dimensions as well as C and D.)

// Abstract class
SCDimension
  Specifies storage information for a dimension.  Each matrix implementation
  has a corresponding SCDimension implementation.

  // abstract
  virtual int dim()
    The integer dimension is returned.
  virtual corresponding_matrix_type create_matrix(SCDimension a)
    A matrix is created with this as the rowdim and a as the coldim.
  virtual corresponding_matrix_type create_symmmatrix()
    A symmetric matrix is created with this as rowdim and coldim.
  virtual corresponding_matrix_type create_diagmatrix()
    A diagonal matrix is created with this as rowdim and coldim.
  virtual corresponding_vector_type create_vector()
    A diagonal matrix is created with this as dim.

// Abstract class
SCMatrix

  // concrete:
  CTOR()
  current i()
    Returns the inverse of this.
  current t()
    Returns the transpose of this.
  current operator*(current a)
    Returns this * a.
  current operator+(current a)
    Returns this + a.
  current operator-(current a)
    Returns this - a.
  int nrow()
    The number of rows in the matrix.
  int ncol()
    The number of columns in the matrix.
  current clone()
    Returns an identical matrix with uninitialized elements.
  void scale(double a)
    Scales all of the elements in this by a.
  current assign(double a)
    Assigns all of the elements to a;
  void copy(current a)
    Copy a to this.  The dimensions must be the same.  This is not
    operator=(current), because operator=(current) has a different
    meaning in the reference counting classes.
  SCdouble operator()(int,int)
    This lets users do things like a(1,1) = x; x = a(1,1);.  Note that
    printf("%f",(something of type SCdouble)) won't work, because
    SCdouble can't be passed though '...'.

  // abstract:
  SCDimension rowdim()
    The row dimension of the matrix.
  SCDimension coldim()
    The column dimension of the matrix.
  double get_element(int,int)
    Get the value of a matrix element.
  void set_element(int,int,double)
    Set the value of a matrix element.
  current multiply_and_accumulate(current a, current b)
    Performs the operation this += a * b.  Returns this.
  void accumulate(current a)
    Performs this += a.
  current transpose_this()
    Transposes and returns this.
  current invert_this()
    Inverts and returns this.
  void element_op(RefSCElementOp)
    Performs some operation on each element of the matrix.
    The member functions for all SCMatrixElementOp's must be available
    on the node programs in a parallel environment.
  void resize(SCDimension,SCDimension)
    Resize this.

// These are abstract classes which inherits virtually from SCMatrix.
// Specializations of SCMatrix which are diagonal or symmetric should
// inherit form the appropiate class.  The inheritance hierarchy could
// take on one of the following forms:
// Single inheritance:
//     SCMatrix
//        |    \
//        |     SymmSCMatrix
//   SpecSCMatrix   |       \
//                  |        DiagSCMatrix
//            SpecSymmSCMatrix    |
//                                |
//                          SpecDiagSCMatrix
// Multiple inheritance:
//     SCMatrix
//        |    \
//        |     SymmSCMatrix
//   SpecSCMatrix   |       \
//            |     |        DiagSCMatrix
//            SpecSymmSCMatrix    |
//                          |     |
//                          SpecDiagSCMatrix
//

// Abstract class
SymmSCMatrix: virtual SCMatrix
  // concrete
  CTOR()
  implementations of rowdim and coldim
  implement rowcol_clone(DimSpec rowdim,current colmatrix,DimSpec coldim)
  override t(), i(), etc

  // abstract
  int ndim()
    returns the integer dimension
  SCDimension dim()
    returns the dimension

// Abstract class
DiagSCMatrix: virtual SymmSCMatrix

// Concrete class
LocalSCMatrix: SCMatrix
  // concrete:
  CTOR(int,int)
  implementations of all of SCMatrix's abstract functions

// Concrete class
LocalSymmSCMatrix: SymmSCMatrix
  // concrete:
  CTOR(int,int)
  implementations of all of SCMatrix's abstract functions

// Concrete class
LocalDiagSCMatrix: DiagSCMatrix
  // concrete:
  CTOR(int,int)
  implementations of all of SCMatrix's abstract functions

// Concrete class
DistSCMatrix: SCMatrix
  // concrete:
  CTOR(DistMap,DistMap)
  implementations of all of SCMatrix's abstract functions

// Concrete class
DistSymmSCMatrix: SymmSCMatrix
  // concrete:
  CTOR(DistMap,DistMap)
  implementations of all of SCMatrix's abstract functions

// Concrete class
DistDiagSCMatrix: DiagSCMatrix
  // concrete:
  CTOR(DistMap,DistMap)
  implementations of all of SCMatrix's abstract functions

