int mat_add(T,X,Y,m,n)
double *T,*X,*Y;
int m,n;
computes T=X+Y, where X and Y are m*n matrices.
int mat_sub(T,X,Y,m,n)
double *T,*X,*Y;
int m,n;
computes T=X-Y, where X and Y are m*n matrices.
int mat_mlt(T,X,Y,m,n,r)
double *T,*X,*Y;
int m,n,r;
computes T=X*Y, where X is an m*n and Y is an n*r matrix.
int mat_inv(T,X,n,pdet)
double *T,*X;
int n;
double *pdet;
computes matrix T as the inverse matrix of an n*n matrix X by the
Gauss-Jordan elimination method. As a by-product, determinant of X will
be *pdet. If any of the pivot elements are less than 1e-15, X is
considered singular and no T is computed; -i will then be returned where
i is the current row index of the pivot element (i=0,1,...,n-1). In
non-singular cases, 1 is returned. Warning: The matrix X to be inverted
is not preserved during the mat_inv call.
int mat_transp(T,X,m,n)
double *T,*X;
int m,n;
transposes an m*n matrix X to an n*m matrix T.
int mat_mtm(T,X,m,n)
double *T,*X;
int m,n;
computes T=X'X, where X is an m*n matrix.
int mat_mmt(T,X,m,n)
double *T,*X;
int m,n;
computes T=XX', where X is an m*n matrix.
int mat_2mtm(T,X,Y,m,n,r)
double *T,*X,*Y;
int m,n,r;
computes T=X'Y, where X is an m*n matrix and Y is an m*r matrix.
int mat_2mmt(T,X,Y,m,n,r)
double *T,*X,*Y;
int m,n,r;
computes T=XY' where X is an m*n matrix and Y is an r*n matrix.
int mat_dmlt(T,X,Y,m,n)
double *T,*X,*Y;
int m,n;
computes T=X*Y, where X is an m*m diagonal matrix and Y is an m*n matrix.
int mat_mltd(T,X,Y,m,n)
double *T,*X,*Y;
int m,n;
computes T=X*Y, where X is an m*n matrix and Y is an n*n diagonal matrix.
int mat_center(T,X,m,n)
double *T,*X;
int m,n;
centers an m*n matrix X by computing the means of the X columns as an
n element T vector and subtracting them from the corresponding columns.
int mat_nrm(T,X,m,n)
double *T,*X;
int m,n;
normalizes the columns of an m*n matrix X to length 1. The original
column lengths (square root of sum of squares) will be stored as an
n element vector T. Columns of length=0 are not changed.
int mat_sum(T,X,m,n)
double *T,*X;
int m,n;
computes the column sums of an m*n matrix X as an n element vector T.
int mat_p(X,n,k)
double *X;
int n,k;
transforms the n*n matrix X by the pivotal operation by using
the diagonal element k (k=0,1,...,n-1) as the pivot.
int mat_chol(T,X,n)
double *T,*X;
int n;
performs the Cholesky decomposition of an n*n positive definite matrix
X. Hence an n*n lower triangular matrix T satisfying X=TT' will be
computed. If X is not positive definite, mat_chol returns -i, where i 
(i=0,1,...,n-1) represents the column index where this assumption fails.
If decomposition is successful, 1 is returned.
int mat_cholinv(A,n)
double *A;
int n;
inverts an n*n positive definite matrix A by the Cholesky method and
writes the inverted matrix B partially on A according to the following
scheme:
Before mat_cholinv: (Here n=5 assumed)
     0   1   2       n-1   n
0    a00 a01 a02 a03 a04   *
1    a10 a11 a12 a13 a14   *
2    a20 a21 a22 a23 a24   *
     a30 a31 a32 a33 a34   *
n-1  a40 a41 a42 a43 a44   *
After mat_cholinv:
     0   1   2       n-1 n
0    a00 b00 b01 b02 b03 b04
1    a10 a11 b11 b12 b13 b14
2    a20 a21 a22 b22 b23 b24
     a30 a31 a32 a33 b33 b34
n-1  a40 a41 a42 a43 a44 b44
Please note that the elements are assumed to be saved columnwise.
To have enough space for B, at least n*(n+1) elements (of type double)
must have been allocated for A before the mat_cholinv call.
If A is not positive definite, -i (where i is the first column dependent
on previous ones) is returned. In a successful case 1 is returned.
To overwrite A by its inverse completely, use mat_cholmove(A,n) after
mat_cholinv(A,n) to obtain
     0   1   2       n-1 n
0    b00 b01 b02 b03 b04 b04
1    b10 b11 b12 b13 b14 b14
2    b20 b21 b22 b23 b24 b24
     b30 b31 b32 b33 b34 b34
n-1  b40 b41 b42 b43 b44 b44
int mat_gram_schmidt(S,U,X,m,n,tol)
double *S,*U,*X;
int m,n;
double tol;
computes the Gram-Schmidt decomposition X=S*U for an m*n matrix X 
(with rank(X)=n<=m), where S is an m*n matrix with orthonormal
columns and U is n*n upper triangular.
The accuracy in checking the linear independency of columns is given by
tol. The value tol=1e-15 is recommended.
Return value -i indicates that column i (i=0,1,...,n-1) is linearly dependent on previous ones. After a successful decomposition, 1 is returned.
int mat_svd(X,D,V,m,n,eps,tol)
double *X,*D,*V;
int m,n;
double eps,tol;
makes the singular value decomposition X=U*diag(D)*V' for an m*n 
matrix X with m>=n. After the mat_svd call X will be overwritten by an
m*n matrix U which is columnwise orthogonal. D will be an n element
vector consisting of singular values and V an n*n orthogonal matrix.
eps and tol are tolerance constants (see the source cited below).
Suitable values are eps=1e-16 and tol=(1e-300)/eps.
mat_svd has been written using the ALGOL procedure by G.H.Golub and C.Reinsch as the basis. See Handbook for Automatic Computation, Volume II, edited by J.H.Wilkinson and C.Reinsch, pp. 134-151 (Springer 1971).
int mat_tred2(d,e,A,n,tol)
double *d,*e,*A;
int n;
double tol;
reduces an n*n symmetric matrix A to tridiagonal form using
Householder's reduction. The diagonal of the result is stored as an n 
element vector d and the sub-diagonal as the last n-1 elements of an n 
element vector e. A will be overwritten by the transformation matrices.
tol is an accuracy constant (see mat_svd).
Space for d and e (n elements each of type double) must be allocated
before mat_tred2 is called.
To get the eigenvalues and vectors after mat_tred2(d,e,A,n,tol),
function mat_tql2 has to be called.
mat_tred2 and mat_tql2 have been written using the ALGOL procedures tred2 and tql2 as the basis. See Handbook for Automatic Computation, Volume II, edited by J.H.Wilkinson and C.Reinsch, (Springer 1971).
int mat_tql2(d,e,A,n,eps,maxiter)
double *d,*e,*A;
int n;
double eps;
int maxiter;
finds the eigenvalues and vectors of the n*n tridiagonal matrix A 
obtained by mat_tred2. Matrix A will be overwritten by the eigenvectors
and the eigenvalues will be saved in descending order as an n element
vector d.
eps in an accuracy constant (see mat_svd). Maximum number of iterations
for one eigenvalue is maxiter. maxiter=30 is recommended. In case of no
convergence within maxiter iterations, -1 is returned. If the
eigenvalues and vectors are obtained, 1 is the return value.
mat_tred2 and mat_tql2 have been written using the ALGOL procedures tred2 and tql2 as the basis. See Handbook for Automatic Computation, Volume II, edited by J.H.Wilkinson and C.Reinsch, (Springer 1971).
int solve_upper(X,A,B,m,k,eps)
double *X,*A,*B;
int m,k;
double eps;
solves the system of linear equations AX=B where A is an m*m upper
triangular matrix and B is an m*k matrix. Before calling solve_upper,
space must also be allocated to the m*k solution matrix X.
If any of the pivot elements is smaller than eps, solve_upper returns -i 
where i=0,1,...,m-1 is the current column. After a successful solution,
1 is returned.
solve_lower works as solve_upper but with an m*m lower triangular
matrix A.
solve_diag works as solve_upper but with an m*m diagonal matrix A.
int solve_symm(X,A,B,m,k,eps)
double *X,*A,*B;
int m,k;
double eps;
solves the system of linear equations AX=B where A is an m*m positive
definite matrix and B is an m*k matrix. Before calling solve_symm,
space must also be allocated to the m*k solution matrix X.
If any of the pivot elements is smaller than eps, solve_symm returns -i,
where i=0,1,...,m-1 is the current column. After a successful solution,
1 is returned. If A is not positive definite, solve_symm calls
ortholin1.
solve_symm is based on the ALGOL procedures choldet1 and cholsol1 in Handbook for Automatic Computation, Volume II, edited by J.H.Wilkinson and C.Reinsch, (Springer 1971).
int ortholin1(A,n,m,B,k,eps,X,improvement)
double *A;
int n,m;
double *B;
int k;
double eps;
double *X;
int improvement;
    /* iterative improvement 1=yes 0=no */
gives least squares solutions for AX=B, where A is an n*m matrix, B an
n*k matrix and n>=m.
eps is the maximal relative rounding error (typically eps=1e-15).
ortholin1 is based on the ALGOL procedure ortholin1 in
Handbook for Automatic Computation, Volume II, edited by
J.H.Wilkinson and C.Reinsch, (Springer 1971).
double sis_tulo(a,b,sa,sb,n)
double *a,*b;
int sa,sb,n;
is an assembler routine (written by T.Patovaara) for computation of
the inner product
a[0]*b[0]+a[sa]*b[sb]+a[2*sa]*b[2*sb]+ ... +a[(n-1)*sa]*b[(n-1)*sb]
To speed up computations, many of the SURVOMAT.LIB functions use sis_tulo for scalar products.