|
|
|
|
/*
|
|
|
|
|
* Work in this file is derived from code originally written by Hans-Peter Moser:
|
|
|
|
|
* http://www.mosismath.com/Basics/Basics.html
|
|
|
|
|
* http://www.mosismath.com/Matrix_Gauss/MatrixGauss.html
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace Connected.Components;
|
|
|
|
|
|
|
|
|
|
// Matrix equation solver using the Gaussian elimination algorithm
|
|
|
|
|
public class MatrixSolver
|
|
|
|
|
{
|
|
|
|
|
public readonly Matrix m;
|
|
|
|
|
public readonly int maxOrder;
|
|
|
|
|
public bool calcError;
|
|
|
|
|
|
|
|
|
|
public MatrixSolver(int size, Matrix mi)
|
|
|
|
|
{
|
|
|
|
|
maxOrder = size;
|
|
|
|
|
m = mi;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SwitchRows(int n)
|
|
|
|
|
{
|
|
|
|
|
double tempD;
|
|
|
|
|
int i, j;
|
|
|
|
|
for (i = n; i <= maxOrder - 2; i++)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j <= maxOrder - 1; j++)
|
|
|
|
|
{
|
|
|
|
|
tempD = m.a[i, j];
|
|
|
|
|
m.a[i, j] = m.a[i + 1, j];
|
|
|
|
|
m.a[i + 1, j] = tempD;
|
|
|
|
|
}
|
|
|
|
|
tempD = m.y[i];
|
|
|
|
|
m.y[i] = m.y[i + 1];
|
|
|
|
|
m.y[i + 1] = tempD;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Eliminate()
|
|
|
|
|
{
|
|
|
|
|
int i, k, l;
|
|
|
|
|
calcError = false;
|
|
|
|
|
for (k = 0; k <= maxOrder - 2; k++)
|
|
|
|
|
{
|
|
|
|
|
for (i = k; i <= maxOrder - 2; i++)
|
|
|
|
|
{
|
|
|
|
|
if (Math.Abs(m.a[i + 1, i]) < 1e-8)
|
|
|
|
|
{
|
|
|
|
|
SwitchRows(i + 1);
|
|
|
|
|
}
|
|
|
|
|
if (m.a[i + 1, k] != 0.0)
|
|
|
|
|
{
|
|
|
|
|
for (l = k + 1; l <= maxOrder - 1; l++)
|
|
|
|
|
{
|
|
|
|
|
if (!calcError)
|
|
|
|
|
{
|
|
|
|
|
m.a[i + 1, l] = m.a[i + 1, l] * m.a[k, k] - m.a[k, l] * m.a[i + 1, k];
|
|
|
|
|
if (m.a[i + 1, l] > 10E260)
|
|
|
|
|
{
|
|
|
|
|
m.a[i + 1, k] = 0;
|
|
|
|
|
calcError = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m.y[i + 1] = m.y[i + 1] * m.a[k, k] - m.y[k] * m.a[i + 1, k];
|
|
|
|
|
m.a[i + 1, k] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return !calcError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Solve()
|
|
|
|
|
{
|
|
|
|
|
int k, l;
|
|
|
|
|
for (k = maxOrder - 1; k >= 0; k--)
|
|
|
|
|
{
|
|
|
|
|
for (l = maxOrder - 1; l >= k; l--)
|
|
|
|
|
{
|
|
|
|
|
m.y[k] = m.y[k] - m.x[l] * m.a[k, l];
|
|
|
|
|
}
|
|
|
|
|
if (m.a[k, k] != 0)
|
|
|
|
|
m.x[k] = m.y[k] / m.a[k, k];
|
|
|
|
|
else
|
|
|
|
|
m.x[k] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|