Mathematics Source Library
C & ASM

 Home Roots of Nonlinear Functions Numerical Integration Differential Equations Matrices and Linear Algebra Function Library Optimization Partial Differential Equations

# Matrices and Linear Algebra

Matrices arise in many, many, many different contexts. Most generally a matrix is simply a rectangular array of entities also called the components of the matrix. Depending on the context in which the matrix comes into existence, the entities themselves may be elements of number field, such as the field of real numbers, complex numbers, or the finite fields or a ring, such as the integers, ring of functions, or polynomials over a field.  When specifying a particular component of a matrix A, one usually specifies the row first then the column, so aij is the component of row i column j, the matrix A then is sometimes denoted (aij).
The C source and NASM source for various matrix functions can be accessed by following the links below:

### Various Collections of Matrix Routines

• General Purpose Matrix Routines
The generic nature of the routines in this collection of matrix routines consists of routines which are applicable to matrices regardless of whether or not the components of the matrix are members of any algebraic object. For instance, it is possible to set the matrix A equal to the matrix B, A = B, as long as A and B have the same dimensions, without regard for the nature of the components, i.e. this operation depends only on the nature of something being a matrix and the nature of the operation =. Although the generic nature of the routines are applicable to matrices in general, all the implementations available at this website are for real matrices whose components are of type double.

• Arithmetic Routines
The routines in this collection of matrix routines consists of those routines for which the components are themselves elements of a ring or in some cases a ring with identity. The algebraic operations of the ring define algebraic operations on matrices, e.g. matrix addition may be defined component-wise using the addition operation of the ring or matrix multiplication may be defined using the addition operation and multiplication operation defined on the ring. In particular, matrix inversion is not included in this collection, but rather in the link below. Again, although the generic nature of the routines are applicable to matrices over a ring (with identity), all the implementations available at this website are for real matrices whose components are of type double.

• Systems of Linear Equations
For matrices defined over a field it is possible to find a solution x to the matrix equation Ax = B for a fixed n×n matrix A and a fixed n×1 matrix B providing that the matrix A is non-singular, x = A-1B. In general, it is better to solve the equation Ax = B directly for x than to find the inverse A-1. Again, although the generic nature of the routines are applicable to matrices over a field, all the implementations available at this website are for real matrices whose components are of type double.

• Normed and Inner Product Spaces
The routines in this collection supplement those of the above collections and are applicable to matrices which arise from linear transformations defined on an inner product space or a normed linear space. Again, although the generic nature of the routines are applicable to matrices over a field, all the implementations available at this website are for real matrices whose components are of type double.

• Eigenvalues and Eigenvectors
The routines in this collection of matrix routines consists of routines which calculate the eigenvalues and eigenvectors of a square matrix. Generally in order to calculate the eigenvalues for square matrix the ground field needs to be closed i.e. the characteristic polynomial splits into linear factors with constants belonging to the field. This means that arbitrary matrices should be defined over the field of complex numbers. Note that real symmetric matrices, however, have real eigenvalues. Again, although the generic nature of the routines are applicable to matrices over a closed field, all the implementations available at this website are for real matrices whose components are of type double. For this reason some of the routines may fail if it is not known apriori that the eigenvalues are real.

### Various Examples of the Birth of Matrices

• Linear Transformations:
Given an n-dimensional real vector space V an m-dimensional real vector space W and a linear transformation L:V→W with domain V and range W, then given basis vectors {v0, . . ., vn-1} of V and basis vectors  {w0, . . ., wm-1} of W, the linear transformation L can be represented as a matrix of real numbers where lij where L(vj) = Σilijwi.  Moveover if W is an inner product space and {w0, . . ., wm-1} is an orthonormal basis then lij = <wi, L(vj)>, where < > denotes the inner product.  Further, the addition of linear transformations corresponds to addition of the corresponding matrices and composition of linear transformations corresponds to multiplication of the corresponding matrices.  If V and W are complex vector spaces, then L can be represented as matrix of complex numbers. In general if V and W are vector spaces over a field F, then the linear transformation L can be represented as a matrix of elements of the field F.

• Bilinear Functions:
Given an n-dimensional real vector space V, an m-dimensional real vector space W and a bilinear function B:V×W→R, then given basis vectors {v0,. . , vn-1} of V and basis vectors {w0, . . , wm-1} of W, the bilinear function B can be represented as a matrix of real numbers where bij = B(vi,wj). If v = Σiaivi and w =Σjcjwj, then B(v,w) = ΣiΣjaibijcj.

• Probability Transition Matrices:
Given a stationary first-order discrete Markov process on states Xi, the probability transition matrix P is a matrix whose components are non-negative real numbers such that the sum of the components along a row equals 1. The component pij is the probability of transition from state Xi to Xj during one unit of time.  For non-stationary first-order discrete Markov processes, the probability transition matrices depend on the time parameter, i.e. at time n, P(n) is a probability transition matrix whose i,j-th component p(n)ij is the probability of transition from state Xi to Xj during the time interval n to n+1.

• Systems of Linear Equations:
Given a system of linear equations  ai,0 x0+ . . . + ai,n-1 xn-1= bi,
for i = 0, . . .,n-1. The coefficients can be represented as the n×n matrix A = (aij), the right-hand side can be written as the n × 1 matrix B = (bi) and the unknown quantities xi as the n × 1 matrix x = (xi). The system of linear equations in matrix form is then Ax = B.

• Graphs and Networks:
In graph theory and network theory many different matrices are defined the most common being the incidence matrix, the circuit matrix, the path matrix, the adjacency matrix, and in switching theory the switching matrix, connection matrix, the transmission matrix etc. Some of these matrices are boolean matrices and some are defined over the ring of boolean polynomials. Currently, at this website, the matrix routines for which the C source code is provided deals only with real-valued matrices in which the components are of type double.

### Machine Storage of Matrices

In C there are two ways to declare a matrix. The first is double A[M][N] which declares A to be a matrix with M rows and N columns and the second is double **A which declares A to be a pointer to an array of pointers. For the second method the user must call malloc() or an equivalent function to dynamically allocate the memory for the arrays. Given a statement involving A[i][j], the way the compiler interprets access to a memory location depends on the way A was declared. If A was declared as double A[M][N]; then the memory location at &A[0][0] + i*N + j is used, (C stores a matrix in consecutive memory locations sequentially by the row of the matrix.) And if A was declared as double **A; then the memory location at *(A+i)+j is used.

All matrices for which the C source code and ASM source code is provided at this website assume that the matrices are stored sequentially as if having been declared in the calling routine as double A[M][N].
For statically defined matrices declared as double A[M][N] the C source code at this website would be called using either the cast (double*) A or as &A[0][0]. Dynamic memory allocation of matrix then can be achieved as follows:
 #include // required for malloc() int i,m,n; double *A; double **pA;    .    .    .    A = (double*) malloc(sizeof(double) * m * n);    pA = (double**) malloc(sizeof(double) * m);    for(i = 1, *pA = A; i < m; i++) *(pA+i) = *(pA + i - 1) + n;
Note that if *(pA+i) is changed for some i, then the matrix A and the matrix pA will no longer agree. The C source code at this website then would be called using A as the matrix argument.