A common matrix task is the solution of a set of simultaneous
linear equations, since this can be conveniently expressed as
GaussElimCL
solves the system above using Gaussian elimination with pivoting, while
DecomposeCL and
SolveCL respectively decompose a matrix into a more useful
form and use the resulting decomposition to solve the equation. The
DecomposeCL/SolveCL approach is preferable when you want to solve the
equation above for several different DecomposeCL does
not involve SolveCL is very quick.
Two special cases are where the matrix
is tridiagonal
TridiagCL
is better suited, or banded such as
BandCL. The routine
InvertCL inverts a matrix.
Another common problem is the determination of eigenvalues and
eigenvectors. CCATSL has three routines for this:
EigenMaxCL
finds an eigenvalue of greatest modulus and an eigenvector
with this eigenvalue, EigenValCL takes a
parameter
and finds an eigenvalue
minimising
together with a corresponding eigenvector. For
symmetric
, JacobiCL returns all the
eigenvalues and eigenvectors, using the method of Jacobi.
If
is an
by
matrix, a singular value decomposition (i.e.,
a decomposition of the form
where
and
are
orthogonal and
is diagonal) can be found using the routine
SvdCL.
GaussElimCL
| double GaussElimCL ( |
int n, |
| int ncols, |
|
| double *a, |
|
| double *z, |
|
| double *x); |
|
| n |
The order of the matrix |
|
| ncols |
Normally ncols=n. Specifically, ncols is the size of the second dimension in
the declaration of the array a. |
|
| a |
Array holding the matrix |
|
| z |
Array holding the vector |
|
| x |
Array to receive the solution vector |
The return value is the determinant of the matrix
.
A typical use of GaussElimCL might look like
|
/* /examples/chapter2/elim.c */
#include <catam.h>
int MainCL(void)
{
double a[2][2];
double z[2];
double x[2];
double det;
a[0][0]=1; a[0][1]=1;
a[1][0]=0; a[1][1]=1;
z[0]=2;
z[1]=3;
det=GaussElimCL(2,2,a,z,x);
printf("determinant is %lf",det);
return 0;
}
|
A complete example of how to use GaussElimCL can be found in
b09matrx.c.
DecomposeCL
DecomposeCL is designed to be used in combination with
SolveCL to solve a set
of simultaneous linear equations expressed in the form
Once the
matrix
has been decomposed with DecomposeCL, SolveCL can be
called to solve for a given
Since SolveCL is
much faster than GaussElimCL, if the same set of equations is to be
solved for different vectors
, the DecomposeCL/SolveCL
approach is to be preferred to GaussElimCL.
| double DecomposeCL ( |
int n, |
| int ncols, |
|
| double *a); |
|
| n |
The order of the matrix |
|
| ncols |
Normally ncols=n. Specifically, ncols is the size of the second dimension in
the declaration of the array a. |
|
| a |
Array holding the matrix DecomposeCL returns, DecomposeCL. |
The return value is the determinant of the matrix
. See
b09matrx.c for an example of how to use DecomposeCL.
ConditionCL
ConditionCL returns the last condition number of the last matrix decomposition (see DecomposeCL) or
inversion (see InvertCL).
SolveCL
This routine complements DecomposeCL by taking a
matrix in decomposed form and a vector
and solving the system of linear
equations
It is faster than Gaussian elimination
(GaussElimCL) and is thus more efficient for solving
for several different vectors
| void SolveCL ( |
int n, |
| int ncols, |
|
| double *a, |
|
| double *z); |
|
| n |
The order of the matrix |
|
| ncols |
Normally ncols=n. Specifically, ncols is the size of the second dimension in
the declaration of the array a. |
|
| a |
The matrix |
|
| z |
Array to hold the right-hand side SolveCL returns, it will have been overwritten and will hold the
solution vector |
The example program b09matrx.c demonstrates the use of SolveCL.
TridiagCL
This routine solves the linear system
for the special case where
is tridiagonal
| void TridiagCL ( |
int n, |
| double *a, |
|
| double *b, |
|
| double *c, |
|
| double *z, |
|
| double *x); |
|
| n |
The order of the matrix |
|
| a |
Array holding the values of
|
|
| b |
Array holding
|
|
| c |
Array holding
|
|
| z |
Array holding the vector |
|
| x |
Array to hold the solution vector |
A typical use of TridiagCL is the following:
|
/* /example/chapter2/tridiag.c */
#include <catam.h>
int MainCL(void)
{
double a[5],b[5],c[5],z[5],x[5];
c[0]= 1; c[1]= 1; c[2]= 1; c[3]=1;
b[0]=-2; b[1]=-2; b[2]=-2; b[3]=-2; b[4]=-2;
a[1]= 1; a[2]= 1; a[3]= 1; a[4]= 1;
z[0]=0.5; z[1]=0.5; z[2]=0.5; z[3]=0.5; z[4]=0.5;
TridiagCL(5,a,b,c,z,x);
}
|
BandCL
This routine solves the linear system
when
is banded:
if
or
where
The
numbers
and
are called the lower bandwidth and the
upper bandwidth respectively. For example, the matrix
BandCL over a standard Gaussian elimination routine
such as GaussElimCL is that it exploits the sparse
structure to speed up the computation, and that it can handle much
larger matrices, since the full matrix BandCL. The compact form of the matrix above is
BandCL. Note
that if
| double BandCL ( |
int n, |
| int ncols, |
|
| int lbw, |
|
| int ubw, |
|
| double *cpact, |
|
| double *z, |
|
| double *x); |
|
| n |
The order of the matrix |
|
| ncols |
Normally ncols=1+lbw+ubw. Specifically, ncols is the size
of the second dimension in the declaration of the array cpact. |
|
| lbw |
The lower bandwidth of the matrix. | |
| ubw |
The upper bandwidth. | |
| cpact |
Array holding the matrix |
|
| z |
Array holding the vector |
|
| x |
Array to hold the solution vector |
The return value is the determinant of the matrix.
b09matrx.c contains an example of how to use
BandCL.
InvertCL
InvertCL inverts a square matrix and returns its determinant. The inverse overwrites the
original matrix; thus if you want to retain the original matrix you
must make a copy of it prior to calling InvertCL.
| double InvertCL ( |
int n, |
| int ncols, |
|
| void *a); |
|
| n |
The order of the matrix. | |
| ncols |
Normally ncols=n. Specifically, ncols is the size of the second dimension in
the declaration of the array a. |
|
| a |
Array holding the matrix InvertCL returns, it will
have been overwritten with the inverse matrix. |
The return value is the determinant of the matrix
.
b09matrx.c has an example of how to use InvertCL.
SvdCL
The CCATSL routine SvdCL computes a
decomposition of the form
where
and
are
orthogonal and
is diagonal. If
is
by
, then
is
by
,
is
by
and
is
by
, thus
if
, the last
rows of
will be zero
and the last
columns of
will not have any special
significance. Similarly if
, the last
columns of
will be
zero and the last
columns of
are not significant. Since
is diagonal, SvdCL just returns the diagonal elements (the
singular values) of
as a one-dimensional vector.
| int SvdCL ( |
int m, |
| int n, |
|
| int ncols, |
|
| double *a, |
|
| double *u, |
|
| double *v, |
|
| double *w); |
|
| m |
The number of rows in the matrix |
|
| n |
The number of columns in the matrix |
|
| ncols |
Normally ncols=n. Specifically, ncols is the size of the second dimension in
the declaration of the array a. |
|
| a |
Array holding the matrix |
|
| u |
Array to hold the matrix |
|
| v |
Array to hold the matrix |
|
| w |
Array to hold the singular values (a one-dimensional vector). |
The return value is zero if the decomposition was successful. A
non-zero value,
say, indicates that the iteration for the
th
singular value failed. A typical use of SvdCL might look like
|
/* /examples/chapter2/svd.c */
#include <catam.h>
int MainCL(void)
{
double a[2][3];
double u[2][2];
double v[3][3];
double w[3];
int ok;
a[0][0]=1; a[0][1]=1; a[0][2]=2;
a[1][0]=0; a[1][1]=2; a[1][2]=2;
ok=SvdCL(2,3,3,a,u,v,w);
return 0;
}
|
EigenMaxCL
EigenMaxCL finds an eigenvalue of largest modulus of a matrix
,
together with a corresponding eigenvector.
| double EigenMaxCL ( |
int n, |
| int ncols, |
|
| double acc, |
|
| double *a, |
|
| double *evec); |
|
| n |
The order of the matrix. | |
| ncols |
Normally ncols=n. Specifically, ncols is the size of the second dimension in
the declaration of the array a. |
|
| acc |
The absolute accuracy required. | |
| Ap |
Array holding the matrix |
|
| evec |
Array holding an initial `guess' EigenMaxCL will fall over (by
setting
ErrorFlagCD=true and terminating).
Assuming this does not happen, when EigenMaxCL returns, it will hold
a genuine eigenvector. |
The return value is an eigenvalue of largest modulus
A typical use of EigenMaxCL might look like
|
/* /examples/chapter2/power.c */
#include <catam.h>
int MainCL(void)
{
double a[2][2];
double evect[2];
double eval;
a[0][0]=1; a[0][1]=1;
a[1][0]=1; a[1][1]=0;
evect[0]=1;
evect[1]=1;
eval=EigenMaxCL(2,2,0.00001,a,evect);
return 0;
}
|
EigenValCL
The drawback of EigenMaxCL is that it can only give an
eigenvector corresponding to an eigenvalue of largest modulus.
EigenValCL takes a parameter
and returns an
eigenvalue
and a corresponding eigenvector minimising
for a given matrix
.
| double EigenValCL ( |
int n, |
| int ncols, |
|
| double acc, |
|
| double *a, |
|
| double *evec, |
|
| double theta); |
|
| n |
The order of the matrix |
|
| ncols |
Normally ncols=n. Specifically, ncols is the size of the second dimension in
the declaration of the array a. |
|
| acc |
The absolute accuracy required. | |
| a |
Array holding the matrix |
|
| evec |
Array holding an initial `guess' |
|
| theta |
The parameter EigenValCL encounters a problem (as it will, for example, if
and terminate. |
See EigenMaxCL for an illustration of how to use a very
similar function. The return value is the desired eigenvalue,
.
JacobiCL
The Jacobi method is a powerful technique for finding the eigenvalues and eigenvectors
of a real symmetric matrix
.
| void JacobiCL ( |
int n, |
| int ncols, |
|
| double *a, |
|
| double *evals); |
|
| n |
The order of the matrix |
|
| ncols |
Normally ncols=n. Specifically, ncols is the size of the second dimension in
the declaration of the array a. |
|
| a |
Array holding the matrix JacobiCL. The eigenvectors will be returned as the rows
of the array a. |
|
| evals |
Array to hold the eigenvalues. |
An example of how to use JacobiCL is shown below:
|
/* /examples/chapter2/jacobi.c */
#include <catam.h>
int MainCL(void)
{
double a[2][2];
double evals[2];
a[0][0]=1; a[0][1]=-1;
a[1][0]=1; a[1][1]= 1;
JacobiCL(2,2,false,a,evals);
return 0;
}
|