I'm working on a system of overdetermined linear equations at work, fitting a series of tables to the product of 2 polynomial equations.
I happened across a nice piece of software from Lutz Roeder called Mapack. Mapack is a simple matrix package that exists in both a .Net version and native mode COM module. I've found the package to be suprisingly quick with good numerical stability when the determinant of the solution matrix nears singularity.
Mapack uses a jagged array to store the matrix. This can be a little inconvenient when dealing with CLS compliant arrays, so I added a new constructor that takes a CLS compliant array and converts it to a jagged array for use with Mapack. (Jagged arrays are specified as double[][] value, while CLS compliant arrays are specified as double[,] value.) I also added a third constructor to take a one dimensional CLS compliant array and convert it to a two dimensional jagged array. I'll discuss some specific methods I've employed using this package to solve overdetermined systems in a later post.
/// <summary>Constructs a matrix from the given CLS compliant array.</summary>
/// <param name="value">The CLS compliant array the matrix gets constructed from.</param>
/// <remarks>Converts a two dimensional array double[n,m] to a
/// two dimensional jagged array of the form double[n][m]</remarks>
public Matrix(double[,] value)
{
this.rows = (int)value.GetLongLength(0);
this.columns = (int)value.GetLongLength(1);
this.data = new double[rows][];
for (int i = 0; i < rows; i++)
{
this.data[i] = new double[columns];
for (int j = 0; j < columns; j++)
{
this.data[i][j] = value[i, j];
}
}
}
/// <summary>Constructs a two dimension matrix from
/// the one dimension CLS compliant array.</summary>
/// <param name="value">The one dimension CLS compliant array
/// the matrix gets constructed from.</param>
/// <remarks>Converts the one dimensional array double[n] to a
/// two dimensional jagged array of the form double[n][0]</remarks>
[CLSCompliant(false)]
public Matrix(double[] value)
{
this.rows = (int)value.GetLongLength(0);
this.columns = 1;
this.data = new double[rows][];
for (int i = 0; i < rows; i++)
{
this.data[i] = new double[1];
this.data[i][0] = value[i];
}
}