Gauss-Jordan matrix inversion: Difference between revisions

Content added Content deleted
(Add Fortran example. Original code.)
(Add C example.)
Line 304: Line 304:
4 1 2 2
4 1 2 2
</pre>
</pre>
=={{header|C}}==
{{trans|Fortran}}
<lang C>/*----------------------------------------------------------------------
gjinv - Invert a matrix, Gauss-Jordan algorithm
A is destroyed. Returns 1 for a singular matrix.

___Name_____Type______In/Out____Description_____________________________
a[n*n] double* In An N by N matrix
n int In Order of matrix
b[n*n] double* Out Inverse of A
----------------------------------------------------------------------*/
#include <math.h>
int gjinv (double *a, int n, double *b)
{
int i, j, k, p;
double f, g, tol;
if (n < 1) return -1; /* Function Body */
f = 0.; /* Frobenius norm of a */
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
g = a[j+i*n];
f += g * g;
}
}
f = sqrt(f);
tol = f * 2.2204460492503131e-016;
for (i = 0; i < n; ++i) { /* Set b to identity matrix. */
for (j = 0; j < n; ++j) {
b[j+i*n] = (i == j) ? 1. : 0.;
}
}
for (k = 0; k < n; ++k) { /* Main loop */
f = fabs(a[k+k*n]); /* Find pivot. */
p = k;
for (i = k+1; i < n; ++i) {
g = fabs(a[k+i*n]);
if (g > f) {
f = g;
p = i;
}
}
if (f < tol) return 1; /* Matrix is singular. */
if (p != k) { /* Swap rows. */
for (j = k; j < n; ++j) {
f = a[j+k*n];
a[j+k*n] = a[j+p*n];
a[j+p*n] = f;
}
for (j = 0; j < n; ++j) {
f = b[j+k*n];
b[j+k*n] = b[j+p*n];
b[j+p*n] = f;
}
}
f = 1. / a[k+k*n]; /* Scale row so pivot is 1. */
for (j = k; j < n; ++j) a[j+k*n] *= f;
for (j = 0; j < n; ++j) b[j+k*n] *= f;
for (i = 0; i < n; ++i) { /* Subtract to get zeros. */
if (i == k) continue;
f = a[k+i*n];
for (j = k; j < n; ++j) a[j+i*n] -= a[j+k*n] * f;
for (j = 0; j < n; ++j) b[j+i*n] -= b[j+k*n] * f;
}
}
return 0;
} /* end of gjinv */</lang>
Test program:
<lang C>/* Test matrix inversion */
#include <stdio.h>
int main (void)
{
static double aorig[16] = { -1.,-2.,3.,2.,-4.,
-1.,6.,2.,7.,-8.,9.,1.,1.,-2.,1.,3. };
double a[16], b[16], c[16];
int n = 4;
int i, j, k, ierr;
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
a[j+i*n] = aorig[j+i*n];
}
}
ierr = gjinv (a, n, b);
printf("gjinv returns #%i\n\n", ierr);
printf("matrix:\n");
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
printf("%8.3f", aorig[j+i*n]);
}
printf("\n");
}
printf("\ninverse:\n");
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
printf("%8.3f", b[j+i*n]);
}
printf("\n");
}
for (j = 0; j < n; ++j) {
for (k = 0; k < n; ++k) {
c[k+j*n] = 0.;
for (i = 0; i < n; ++i) {
c[k+j*n] += aorig[i+j*n] * b[k+i*n];
}
}
}
printf("\nmatrix @ inverse:\n");
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
printf("%8.3f", c[j+i*n]);
}
printf("\n");
}
ierr = gjinv (b, n, a);
printf("\ngjinv returns #%i\n", ierr);
printf("\ninverse of inverse:\n");
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
printf("%8.3f", a[j+i*n]);
}
printf("\n");
}
return 0;
} /* end of test program */</lang>
Output is the same as the Fortran example.


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==