Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
I guess that all depends on what type of matrix you are talking about and how you can store it. Essentially your limits would be available RAM and/or available HDD space
Personally, I haven't tried it so I don't know. But 15 seconds for a general matrix seems really fast.
Why are you inverting matrices anyway? People tend to shy away from that.
I have defined a linear algebra and statistics library in C# and gonna do the same for the rest of mathematics. Then Ill extend those codes to C++. I have developed many inverse algorithms but one problem is that the difficulty increases exponentially when adding one dimension to a matrix. So if we are at 200x200 matrix and have some difficulty n. Once we add the 1 more dimension, (201x201) the difficulty rises to n^3 that is directly translated into the processing time. The fastest algorithm I developed once was only able to calculate the 100x100 matrix inverse in 30 seconds. MATLAB is pretty faster in that but still, the dimension is restricted there also.
Matrix inversion is something that fell out of fashion in the 19th century. I think what you want is to solve
Ax = b
or am I missing something?
static class Lin_Alg
{
public static double[,] Gauss_Jordan(double[,] A)
{
double[,] B = RemoveZeroRows(A);
int m = B.GetLength(0);
int n = B.GetLength(1);
int c = -1; int r = 0;
int t = 0; int k = 0;
double[] R = new double[n];
double[] K = new double[n];
double p = -1; double pp = -1;
while (k < m)
{
//Finding the first non-zero column index*******************************
for (int i = t; i < n; i++)
{
for (int j = k; j < m; j++)
{
if (B[j, i] != 0)
{
c = i;
break;
}
}
if (c == i)
break;
}
//***********************************************************************
//Finding the first non-zero entry in the column "c" to start iterating**
for (int i = k; i < m; i++)
{
if (B[i, c] != 0)
{
r = i;
break;
}
}
//*************************************************************************
//Interchanging rows(if neccessary)to get the first entry of the located...
//...column non-zero*******************************************************
if (r != k)
{
for (int i = 0; i < n; i++)
{
K[i] = B[k, i];
R[i] = B[r, i];
B[k, i] = R[i];
B[r, i] = K[i];
}
}
//****************************************************************************
//Checking for the first first entry from the previous iteration if it is 1...
//...if not divide the rows by the multiplicative inverse of that number******
p = B[k, c];
if (p != 1)
{
for (int i = 0; i < n; i++)
B[k, i] *= Math.Pow(p, -1);
}
//Then multiplying the first number times other non-zero entry rows to get all.
//...numbers equal to 0 below the selected number*********************
for (int i = 0; i < m; i++)
{
if (i == k)
continue;
else
{
if (B[i, c] != 0)
{
pp = B[i, c];
for (int j = 0; j < n; j++)
{
B[i, j] -= pp * B[k, j];
}
}
}
}
//********************************************************************
//Adjusting the indexes for the next iteration************************
t = c + 1; k++;
}
//************************************************************************
//Adding the removed zero rows if there were any**************************
if (GetZeroRows(A) != 0)
{
double[,] G = new double[m + GetZeroRows(A), n];
G = B;
for (int i = m + 1; i <= GetZeroRows(A); i++)
{
for (int j = 0; j < n; j++)
{
G[i, j] = 0;
}
}
return G;
}
else
return B;
}
private static double[,] RemoveZeroRows(double[,] A)
{
int m = A.GetLength(0);
int n = A.GetLength(1);
//int c = 0; int r = 0;
int q = 0;
int[] zeroIndexes = ZeroRowIndexes(A);
bool index = false;
//Remove the zero rows (if any) and free up the matrix with nonzero parameters*****
int w = GetZeroRows(A);
int l = m - w;
if (w != 0)
{
double[,] B = new double[l, n];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < w; j++)
{
if (zeroIndexes[j] != i)
index = true;
else
{
index = false;
break;
}
}
if (index)
{
for (int k = 0; k < n; k++)
B[q, k] = A[i, k];
q++;
}
}
return B;
}
else
return A;
}
private static int[] ZeroRowIndexes(double[,] A)
{
int m = A.GetLength(0);
int n = A.GetLength(1);
int r = GetZeroRows(A);
int[] zeroRowIndexes = new int[r];
int q = 0; bool zero = false;
if (r != 0)
{
for (int i = 0; i < m; i++)
{
if (A[i, 0] == 0)
{
for (int j = 0; j < n; j++)
{
if (A[i, j] == 0)
{
zero = true;
zeroRowIndexes[q] = i;
}
else
{
zero = false;
break;
}
}
if (zero)
q++;
}
}
return zeroRowIndexes;
}
else
{
return null;
}
}
private static int GetZeroRows(double[,] A)
{
int m = A.GetLength(0);
int n = A.GetLength(1);
int r = m; int k = 0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (A[i, j] != 0)
{
k++;
break;
}
}
}
r -= k;
return r;
}
The one thing the professor in numerical analysis nailed in my head is you never use matrix inverse to solve systems of equations b\c it is computationally expensive. Gauss-Jordan elimination is about 3 times slower than LU for solving systems of equations. I do not know other algorithms for matrix inverse.
Try A = LU decomp first (if applicable, even go for Cholesky if possible). Then, (if L and U are invertable), inv(A) = inv(L)*inv(U) and inverting L and U are quick. Well, this works for me, 0.13 sec for 100x100, 18 sec for 500x500, 260 sec for 1000x1000, and my laptop is a dinosaur.
Try A = LU decomp first (if applicable, even go for Cholesky if possible). Then, (if L and U are invertable), inv(A) = inv(LU) = inv(U) * inv(L), and inverting L and U are quick. Well, this works for me, 0.13 sec for 100x100, 18 sec for 500x500, 260 sec for 1000x1000, and my laptop is a dinosaur.
Not sure if it is more efficient than LU. You might find this useful:Is it possible to use QR to find inverse in the same way? QR is more efficient than LU.
it is not only available RAM and/or HDD space, there is something else you should considerI guess that all depends on what type of matrix you are talking about and how you can store it. Essentially your limits would be available RAM and/or available HDD space :D
Interesting approach,. Some issues
1. Choosing the 'stable' L and U; preprocessing might be needed.
2. Increased memory consumption (inv(L) is dense).
3. inv(L) and inv(U) could be done in parallel (e.g. parallel sections).
C# is not the language for doing numerical work.