danbaron
19-07-2010, 05:12
[font=courier new][size=8pt]Here is a Java program which fills an N x N matrix with random doubles, and then, inverts it, using the Gauss-Jordan Method.
It performs the inversion, and then calculates and writes an N-dimensional check vector, to an output file. If the check vector contains values all very close
to 1, then, the inversion is correct.
--------------------------------------
If anyone wants to try the program, then:
1) Make sure Java (>= 1.5) is installed on your computer, and that it's "bin" directory is in your search path.
1) Download the file, and place it in some folder.
2) Change the name of the file to, "matinv.java".
3) Open a command window in the folder.
4) Perform the command, "javac matinv.java".
5) Perform the command, "java matinv". The program will run in the window. When it finishes, it will write the output file to, "matinv.txt" (inside the folder).
--------------------------------------
I ran it three times for a 1000 x 1000 matrix.
The results were (seconds),
24.096
23.977
24.056
:x :P
Dan
//------------------------------------------------------------------------------------------------
import java.lang.System.*;
import java.util.Random;
import java.io.*;
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
public class matinv
{
final static int N = 1000;
final static int first = 0;
final static int last = N - 1;
final static String outfilename = "matinv.txt";
//------------------------------------------------------------------------------------------------
// Matrix to be inverted (filled with random doubles).
static double a0[][] = new double[N][N];
// Copy of matrix to be inverted.
static double am[][] = new double[N][N];
// Calculated inversion of a0.
static double ai[][] = new double[N][N];
// Calculated identity matrix.
static double id[][] = new double[N][N];
// va is multiplied by id, to give the check vector, vb.
static double va[] = new double[N];
// check vector.
static double vb[] = new double[N];
//------------------------------------------------------------------------------------------------
public static void main(String[] args)
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long t0, t1;
double tt;
String s;
System.out.printf("Inverting matrix..\n");
System.out.printf("\n");
t0 = gettime();
// a0 is filled with random doubles.
// am is set equal to a0.
// ai is set to the N x N identity matrix.
// va is set to an N-dimensional vector, of all '1's.
initializeall(a0, am, ai, va);
// am becomes the N x N identity matrix.
// ai becomes the (N x N) inversion of a0.
invert(am, ai);
t1 = gettime();
tt = (t1 - t0) / (double)1000;
System.out.printf("Finished inverting a %d by %d matrix.\n", N, N);
System.out.printf("elapsed time = %6.3f seconds\n", tt);
System.out.printf("\n");
System.out.printf("Calculating check vector..\n");
System.out.printf("\n");
// Multiply the inverted matrix, ai, by the original matrix, a0, to give the calculated identity matrix, id.
matmatmult(a0, ai, id);
// Multiply the N-dimensional vector of all '1's, va, by the calculated N x N identity matrix, id, to give the check vector, vb.
// If the inversion is correct, then, vb, should also be an N-dimensional vector, of all '1's.
// vb, is written to the output file.
matvecmult(id, va, vb);
writeoutfile(tt, vb);
System.out.printf("Finished calculating check vector.\n");
System.out.printf("Output written to file, \"%s\".\n", outfilename);
System.out.printf("\n");
System.out.printf("Press 'Enter' to quit.\n");
try
{
s = br.readLine();
}
catch(IOException e)
{
System.out.println("Input error.");
}
}
//------------------------------------------------------------------------------------------------
static void invert(double original[][], double inversion[][])
// Uses the Gauss-Jordan Method.
{
int pivot, maxrow, row, col;
double max, test, temp, divisor, factor;
maxrow = -1;
//---------------------------------------------
for(pivot = first; pivot <= last; pivot++)
{
//---------------------------------------------
for(row = pivot; row <= last; row++)
{
max = 0;
test = Math.abs(original[row][pivot]);
if( test > max)
{
max = test;
maxrow = row;
}
}
//---------------------------------------------
if(maxrow != pivot)
{
for(col = first; col <= last; col++)
{
temp = original[pivot][col];
original[pivot][col] = original[maxrow][col];
original[maxrow][col] = temp;
temp = inversion[pivot][col];
inversion[pivot][col] = inversion[maxrow][col];
inversion[maxrow][col] = temp;
}
}
//---------------------------------------------
divisor = original[pivot][pivot];
for(col = first; col <= last; col++)
{
original[pivot][col] /= divisor;
inversion[pivot][col] /= divisor;
}
//---------------------------------------------
for(row = first; row <= last; row++)
{
if(row != pivot)
{
factor = -original[row][pivot];
for(col = first; col <= last; col++)
{
original[row][col] += original[pivot][col] * factor;
inversion[row][col] += inversion[pivot][col] * factor;
}
}
}
}
}
//------------------------------------------------------------------------------------------------
static void initializeall(double m1[][], double m2[][], double m3[][], double v1[])
{
Random r = new Random();
for(int i = first; i <= last; i++)
for(int j = first; j <= last; j++)
{
m1[i][j] = r.nextDouble();
m2[i][j] = m1[i][j];
}
for(int i = first; i <= last; i++)
{
v1[i] = 1;
for(int j = first; j <= last; j++) if(i == j) m3[i][j] = 1;
}
}
//------------------------------------------------------------------------------------------------
static void matmatmult(double m1[][], double m2[][], double m3[][])
{
for(int i = 0; i <= last; i++)
{
for(int j = 0; j <= last; j++)
{
m3[i][j] = 0;
for(int k = 0; k <= last; k++) m3[i][j] += m1[i][k] * m2[k][j];
}
}
}
//------------------------------------------------------------------------------------------------
static void matvecmult(double m1[][], double v1[], double v2[])
{
for(int i = 0; i <= last; i++)
{
v2[i] = 0;
for(int j = 0; j <= last; j++) v2[i] += m1[i][j] * v1[j];
}
}
//------------------------------------------------------------------------------------------------
static long gettime()
{
return System.currentTimeMillis();
}
//------------------------------------------------------------------------------------------------
static void writeoutfile(double t, double v1[]) //throws IOException
{
PrintWriter outfile;
try
{
outfile = new PrintWriter(outfilename);
outfile.printf("Inversion of a %d by %d matrix,\n", N, N);
outfile.printf("filled with uniformly distributed random doubles,\n");
outfile.printf("in the range of, (0, 1).\n\n");
outfile.printf("elapsed time = %6.3f seconds\n", t);
outfile.printf("If the inversion was calculated correctly, then every\n");
outfile.printf("value shown below should be very close to 1.\n\n");
for(int i = first; i <= last; i++) outfile.printf("%05d %19.16f\n", i + 1, v1[i]);
outfile.close();
}
catch(IOException e)
{
System.out.println("File Error");
}
}
//-----------------------------------------------------------
}
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
It performs the inversion, and then calculates and writes an N-dimensional check vector, to an output file. If the check vector contains values all very close
to 1, then, the inversion is correct.
--------------------------------------
If anyone wants to try the program, then:
1) Make sure Java (>= 1.5) is installed on your computer, and that it's "bin" directory is in your search path.
1) Download the file, and place it in some folder.
2) Change the name of the file to, "matinv.java".
3) Open a command window in the folder.
4) Perform the command, "javac matinv.java".
5) Perform the command, "java matinv". The program will run in the window. When it finishes, it will write the output file to, "matinv.txt" (inside the folder).
--------------------------------------
I ran it three times for a 1000 x 1000 matrix.
The results were (seconds),
24.096
23.977
24.056
:x :P
Dan
//------------------------------------------------------------------------------------------------
import java.lang.System.*;
import java.util.Random;
import java.io.*;
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
public class matinv
{
final static int N = 1000;
final static int first = 0;
final static int last = N - 1;
final static String outfilename = "matinv.txt";
//------------------------------------------------------------------------------------------------
// Matrix to be inverted (filled with random doubles).
static double a0[][] = new double[N][N];
// Copy of matrix to be inverted.
static double am[][] = new double[N][N];
// Calculated inversion of a0.
static double ai[][] = new double[N][N];
// Calculated identity matrix.
static double id[][] = new double[N][N];
// va is multiplied by id, to give the check vector, vb.
static double va[] = new double[N];
// check vector.
static double vb[] = new double[N];
//------------------------------------------------------------------------------------------------
public static void main(String[] args)
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long t0, t1;
double tt;
String s;
System.out.printf("Inverting matrix..\n");
System.out.printf("\n");
t0 = gettime();
// a0 is filled with random doubles.
// am is set equal to a0.
// ai is set to the N x N identity matrix.
// va is set to an N-dimensional vector, of all '1's.
initializeall(a0, am, ai, va);
// am becomes the N x N identity matrix.
// ai becomes the (N x N) inversion of a0.
invert(am, ai);
t1 = gettime();
tt = (t1 - t0) / (double)1000;
System.out.printf("Finished inverting a %d by %d matrix.\n", N, N);
System.out.printf("elapsed time = %6.3f seconds\n", tt);
System.out.printf("\n");
System.out.printf("Calculating check vector..\n");
System.out.printf("\n");
// Multiply the inverted matrix, ai, by the original matrix, a0, to give the calculated identity matrix, id.
matmatmult(a0, ai, id);
// Multiply the N-dimensional vector of all '1's, va, by the calculated N x N identity matrix, id, to give the check vector, vb.
// If the inversion is correct, then, vb, should also be an N-dimensional vector, of all '1's.
// vb, is written to the output file.
matvecmult(id, va, vb);
writeoutfile(tt, vb);
System.out.printf("Finished calculating check vector.\n");
System.out.printf("Output written to file, \"%s\".\n", outfilename);
System.out.printf("\n");
System.out.printf("Press 'Enter' to quit.\n");
try
{
s = br.readLine();
}
catch(IOException e)
{
System.out.println("Input error.");
}
}
//------------------------------------------------------------------------------------------------
static void invert(double original[][], double inversion[][])
// Uses the Gauss-Jordan Method.
{
int pivot, maxrow, row, col;
double max, test, temp, divisor, factor;
maxrow = -1;
//---------------------------------------------
for(pivot = first; pivot <= last; pivot++)
{
//---------------------------------------------
for(row = pivot; row <= last; row++)
{
max = 0;
test = Math.abs(original[row][pivot]);
if( test > max)
{
max = test;
maxrow = row;
}
}
//---------------------------------------------
if(maxrow != pivot)
{
for(col = first; col <= last; col++)
{
temp = original[pivot][col];
original[pivot][col] = original[maxrow][col];
original[maxrow][col] = temp;
temp = inversion[pivot][col];
inversion[pivot][col] = inversion[maxrow][col];
inversion[maxrow][col] = temp;
}
}
//---------------------------------------------
divisor = original[pivot][pivot];
for(col = first; col <= last; col++)
{
original[pivot][col] /= divisor;
inversion[pivot][col] /= divisor;
}
//---------------------------------------------
for(row = first; row <= last; row++)
{
if(row != pivot)
{
factor = -original[row][pivot];
for(col = first; col <= last; col++)
{
original[row][col] += original[pivot][col] * factor;
inversion[row][col] += inversion[pivot][col] * factor;
}
}
}
}
}
//------------------------------------------------------------------------------------------------
static void initializeall(double m1[][], double m2[][], double m3[][], double v1[])
{
Random r = new Random();
for(int i = first; i <= last; i++)
for(int j = first; j <= last; j++)
{
m1[i][j] = r.nextDouble();
m2[i][j] = m1[i][j];
}
for(int i = first; i <= last; i++)
{
v1[i] = 1;
for(int j = first; j <= last; j++) if(i == j) m3[i][j] = 1;
}
}
//------------------------------------------------------------------------------------------------
static void matmatmult(double m1[][], double m2[][], double m3[][])
{
for(int i = 0; i <= last; i++)
{
for(int j = 0; j <= last; j++)
{
m3[i][j] = 0;
for(int k = 0; k <= last; k++) m3[i][j] += m1[i][k] * m2[k][j];
}
}
}
//------------------------------------------------------------------------------------------------
static void matvecmult(double m1[][], double v1[], double v2[])
{
for(int i = 0; i <= last; i++)
{
v2[i] = 0;
for(int j = 0; j <= last; j++) v2[i] += m1[i][j] * v1[j];
}
}
//------------------------------------------------------------------------------------------------
static long gettime()
{
return System.currentTimeMillis();
}
//------------------------------------------------------------------------------------------------
static void writeoutfile(double t, double v1[]) //throws IOException
{
PrintWriter outfile;
try
{
outfile = new PrintWriter(outfilename);
outfile.printf("Inversion of a %d by %d matrix,\n", N, N);
outfile.printf("filled with uniformly distributed random doubles,\n");
outfile.printf("in the range of, (0, 1).\n\n");
outfile.printf("elapsed time = %6.3f seconds\n", t);
outfile.printf("If the inversion was calculated correctly, then every\n");
outfile.printf("value shown below should be very close to 1.\n\n");
for(int i = first; i <= last; i++) outfile.printf("%05d %19.16f\n", i + 1, v1[i]);
outfile.close();
}
catch(IOException e)
{
System.out.println("File Error");
}
}
//-----------------------------------------------------------
}
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------