General size matrices and vectors

General size square matrices are handled in a subtly different way
to their fixed-size equivalents. For fixed size symmetric and triangular
matrices, there are specific functions dealing with each type of square
matrix, currently the two types, symmetric and lower triangular.
A fixed size square matrix does not ``know'' what type of matrix it is.
The `type` field in this case is an inessential field of the matrix,
and is indeed `#ifdef`'d out when Gandalf is compiled with `NDEBUG`
set. The only reason for using the same structure for both symmetric
and lower triangular matrices is to allow the in-place operations that convert
a symmetric matrix to a triangular matrix or vice versa. This arrangement
is optimal for speed, because no type checking needs to be done at
run time.

In contrast, the general size square matrix structure has a `type` field
that is meaningful as the current matrix type. Many Gandalf functions are
written for general square matrices. This simplifies the programming interface,
in that one function can be used to implement an operation (e.g. square
matrix add) for every type of square matrix, at the expense of some loss
of speed, since the general function has to call different subroutines
depending on the type of matrix. The overhead in implementing this
arrangement is reduced to the minimum by including the routines to
implement each operation for a given matrix type in the matrix structure
itself. This object-oriented design feature is hidden from the
programmer through the use of macros, so the package appears to the
programmer as a normal set of functions.

Another difference between fixed and general vectors and matrices is that
whereas in general fixed size vectors & matrices should be declared as
structures, avoiding the need for dynamic allocation,
general size vectors & matrices require dynamic allocation of their
internal data. There is still an advantage in declaring structures rather
than structure pointers, in that with pointer variables you require a
call to `malloc()` to create the structure they point to.
Gandalf lets the programmer decide which style to use. In the following
description examples of both styles are presented.

Once again, both double precision and single precision routines are available, and once again a parallel set of header files, structures and functions is provided. We shall concentrate on the double precision package, and the equivalent structure and function name conversions for single precision are given in Section 3.2.3.

Most of the routines return a pointer to the matrix/vector result structure.
`NULL` is returned on failure, and the Gandalf error handler is invoked.
This is reiterated in the text below, and exceptions are noted.

- General size vectors
- Creating and freeing general size vectors
- Adjusting the size of a general size vector
- Filling a general size vector with values
- Accessing the elements of a general size vector
- Copying a general size vector
- General size vector addition
- General size vector subtraction
- Rescaling a general size vector

- General size matrices
- Creating and freeing general size matrices
- Adjusting the size of a general size matrix
- Filling a general size matrix with values
- Accessing the elements of a general size matrix
- Copying a general size matrix
- Transposing a general size matrix
- General size matrix addition
- General size matrix subtraction
- Rescaling a general size matrix
- General size matrix/vector multiplication
- General size matrix/matrix multiplication
- Inverting a general size matrix
- Cholesky factorising a general size symmetric matrix
- Symmetric matrix eigendecomposition
- Accumulated symmetric matrix eigendecomposition

- Single precision general size matrices & vectors