class Matrix
{
private double[,] data;
private int nRows, nColumns;
public Matrix() { }
public Matrix(int nRows, int nColumns)
{
this.data = new double[nRows, nColumns];
this.nRows = nRows;
this.nColumns = nColumns;
}
public Matrix(double[,] matrix)
{
nRows = matrix.GetLength(0);
nColumns = matrix.GetLength(1);
this.data = new double[nRows, nColumns];
this.data = matrix;
}
public Matrix(Matrix other)
{
nRows = other.GetLength(0);
nColumns = other.GetLength(1);
this.data = new double[nRows, nColumns];
for (int i = 0; i < nRows; ++i)
{
for (int j = 0; j < nColumns; ++j)
{
this.data[i, j] = other[i, j];
}
}
}
public double this[int i, int j]
{
get { return this.data[i, j]; }
set { this.data[i, j] = value; }
}
public static bool operator ==(Matrix first, Matrix second)
{
for (int i = 0; i < first.GetLength(0); ++i)
for (int j = 0; j < first.GetLength(1); ++j)
if (first[i, j] != second[i, j])
return false;
return true;
}
public static bool operator !=(Matrix first, Matrix second)
{
return (first == second) ? false : true;
}
public override bool Equals(object obj)
{
obj = (Matrix)obj;
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override string ToString()
{
string stream = "";
for (int i = 0; i < this.nRows; ++i)
{
for (int j = 0; j < this.nColumns; ++j)
stream += String.Format("{0:f4}\t\t", this[i, j]);
stream += "\n";
}
return stream;
}
public static Matrix operator +(Matrix first, Matrix second)
{
Matrix retValue = new Matrix(first.GetLength(0), first.GetLength(1));
try
{
if (first.GetLength(0) == second.GetLength(0) && first.GetLength(1) == second.GetLength(1))
{
for (int i = 0; i < first.GetLength(0); ++i)
for (int j = 0; j < first.GetLength(1); ++j)
retValue[i, j] = first[i, j] + second[i, j];
}
}
catch (IndexOutOfRangeException err)
{
Console.WriteLine(err.Message);
}
return retValue;
}
public static Matrix operator -(Matrix first, Matrix second)
{
Matrix retValue = new Matrix(first.GetLength(0), first.GetLength(1));
try
{
for (int i = 0; i < first.GetLength(0); ++i)
for (int j = 0; j < first.GetLength(1); ++j)
retValue[i, j] = first[i, j] - second[i, j];
}
catch (IndexOutOfRangeException err)
{
Console.WriteLine(err.Message);
}
return retValue;
}
public static Matrix operator *(Matrix matrix, double coeff)
{
for (int i = 0; i < matrix.GetLength(0); ++i)
for (int j = 0; j < matrix.GetLength(1); ++j)
matrix[i, j] *= coeff;
return matrix;
}
public static Matrix operator *(double coeff, Matrix matrix)
{
for (int i = 0; i < matrix.GetLength(0); ++i)
for (int j = 0; j < matrix.GetLength(1); ++j)
matrix[i, j] *= coeff;
return matrix;
}
public static Matrix operator *(Matrix first, Matrix second)
{
Matrix retValue = new Matrix(first.GetLength(0), second.GetLength(1));
double curVal = 0.0;
try
{
for (int i = 0; i < first.GetLength(0); ++i)
{
for (int j = 0; j < second.GetLength(1); ++j)
{
curVal = 0.0;
for (int k = 0; k < Math.Max(first.GetLength(1), second.GetLength(0)); ++k)
curVal += first[i, k] * second[k, j];
retValue[i, j] = curVal;
}
}
}
catch (IndexOutOfRangeException err)
{
Console.WriteLine(err.Message);
}
return retValue;
}
public int GetLength(int dimension)
{
return (dimension == 0)
? nRows : nColumns;
}
public Matrix GetMainKoeff()
{
Matrix res_matr = new Matrix(data.GetLength(0), data.GetLength(1) - 1);
for (int i = 0; i < res_matr.GetLength(0); ++i)
{
for (int j = 0; j < res_matr.GetLength(1); ++j)
{
res_matr[i, j] = data[i, j];
}
}
return res_matr;
}
public Matrix GetFreeKoeff()
{
Matrix res_matr = new Matrix(data.GetLength(0), 1);
for (int i = 0; i < res_matr.GetLength(0); ++i)
{
res_matr[i, 0] = data[i, this.GetLength(1) - 1];
}
return res_matr;
}
public Matrix GetMinor2(int ind)
{
Matrix retValue = new Matrix(this.nRows - ind, this.nColumns - ind);
for (int i = ind; i < this.GetLength(0); ++i)
{
for (int j = ind; j < this.GetLength(0); ++j)
{
retValue[i - ind, j - ind] = this[i, j];
}
}
return retValue;
}
public Matrix SetMinor2(Matrix minor, int ind)
{
for (int i = ind; i < this.GetLength(0); ++i)
{
for (int j = ind; j < this.GetLength(0); ++j)
{
this[i, j] = minor[i - ind, j - ind];
}
}
return this;
}
public bool isNull()
{
for (int i = 0; i < this.GetLength(0); ++i)
{
if (this[i, 0] != 0)
return false;
}
return true;
}
public Matrix GetColumn(int indColumn, int begin)
{
if (begin >= this.GetLength(0))
return new Matrix(0, 0);
Matrix retValue = new Matrix(this.GetLength(0) - begin, 1);
for (int i = begin; i < this.GetLength(0); ++i)
retValue[i - begin, 0] = this[i, indColumn];
return retValue;
}
public double[] GetColumnArray(int index, int begin)
{
if (begin >= this.GetLength(0))
return new double[0];
double[] retValue = new double[this.GetLength(0) - begin];
for (int i = begin; i < this.GetLength(0); ++i)
retValue[i - begin] = this[i, index];
return retValue;
}
public Matrix MakeIdentity()
{
Matrix retValue = new Matrix(this.nRows, this.nColumns);
for (int i = 0; i < this.nRows; ++i)
retValue[i, i] = 1;
return retValue;
}
public Matrix GetTransposed()
{
Matrix retValue = new Matrix(this.nColumns, this.nRows);
for (int i = 0; i < this.nRows; ++i)
for (int j = 0; j < this.nColumns; ++j)
retValue[j, i] = this[i, j];
return retValue;
}
public double GetSqrLength(int indColumn)
{
double retValue = 0.0;
for (int i = 0; i < this.nRows; ++i)
retValue += this[i, indColumn] * this[i, indColumn];
return retValue;
}
public double GetSqrtLength(int indColumn)
{
return Math.Sqrt(this.GetSqrLength(indColumn));
}
public double GetSummColumn(int indColumn, int start)
{
double retValue = 0.0;
for (int i = start; i < this.nRows; ++i)
retValue += this[i, indColumn] * this[i, indColumn];
return retValue;
}
public void SetRow(List<double> values, int ind)
{
for (int i = 0; i < values.Count; ++i)
{
this[ind, i] = values[i];
}
}
public static Matrix GetNewMinor(Matrix matrix, int r, int c)
{
int n = matrix.GetLength(0),
m = matrix.GetLength(1);
int k = 0;
Matrix retValue = new Matrix(n - 1, m - 1);
for (int i = 0; i < n; ++i)
{
if (i == r)
continue;
List<double> set = new List<double>();
for (int j = 0; j < m; ++j)
{
if (j != c)
set.Add(matrix[i, j]);
}
retValue.SetRow(set, k);
++k;
}
return retValue;
}
public Matrix GetInverse()
{
Matrix retValue = new Matrix(this.nRows, this.nColumns);
bool[] rows = new bool[this.nRows],
columns = new bool[this.nColumns];
for (int i = 0; i < this.nRows; ++i)
{
rows[i] = true;
columns[i] = true;
}
for (int i = 0; i < this.nRows; ++i)
{
for (int j = 0; j < this.nColumns; ++j)
{
retValue[i, j] = GetNewMinor(this, i, j).GetDet();
if ((i + j) % 2 != 0)
retValue[i, j] *= -1;
rows[i] = true;
columns[j] = true;
}
}
retValue = retValue.GetTransposed();
retValue *= 1.0 / GetDet();
return retValue;
}
public double GetDet()
{
bool[] rows = new bool[this.nRows],
columns = new bool[this.nColumns];
for (int i = 0; i < this.nRows; ++i)
{
rows[i] = true;
columns[i] = true;
}
return GetMinor(rows, columns, this.nRows);
}
public double GetMinor(bool[] rows, bool[] columns, int n)
{
double minorValue = 0.0;
int i = 0,
j = 0,
order = 1;
i = (Array.IndexOf(rows, true) != -1) ? Array.IndexOf(rows, true) : 0;
j = (Array.IndexOf(columns, true) != -1) ? Array.IndexOf(columns, true) : 0;
if (n == 1)
{
return this[i, j];
}
else
{
rows[i] = false;
n--;
for (j = 0; j < this.GetLength(0); ++j)
{
if (columns[j])
{
columns[j] = false;
if (this[i, j] != 0)
{
minorValue += order * this[i, j] * GetMinor(rows, columns, n);
}
columns[j] = true;
order = -order;
}
}
rows[i] = true;
return minorValue;
}
}
public double GetNorm()
{
double[] retValue = new double[this.GetLength(0)];
for (int i = 0; i < this.GetLength(0); ++i)
for (int j = 0; j < this.GetLength(1); ++j)
retValue[i] += Math.Abs(this[i, j]);
Array.Sort(retValue);
return retValue[this.GetLength(0) - 1];
}
}