Работа с матрицами на C#. Продолжение.

07.01.2019 at 12:08

Единичная матрица

Единичная матрица — это квадратная матрица, на главной диагонали которой все элементы равны 1, а все остальные элементы равны 0.

Для создания такой матрицы добавим статический метод

public static Matrix CreateIdentityMatrix(int n)
{
    var result = new Matrix(n, n);
    for (var i = 0; i < n; i++)
    {
        result[i, i] = 1;
    }
    return result;
}

По хорошему бы конечно использовать для таких целей именованный конструктор. Но, к сожалению, в C# нет именованных конструкторов.

Сложение матриц на C#

Складывать можно только матрицы одинакового размера. Для удобства реализуем сложение в виде перегруженного оператора

public static Matrix operator +(Matrix matrix, Matrix matrix2)
{
    if (matrix.M != matrix2.M || matrix.N != matrix2.N)
    {
        throw new ArgumentException(
            "matrixes dimensions should be equal");
    }
    var result = new Matrix(matrix.M, matrix.N);
    result.ProcessFunctionOverData((i, j) => 
        result[i, j] = matrix[i, j] + matrix2[i, j]);
    return result;
}

С помощью умножения и сложения сделаем вычитание матриц

public static Matrix operator -(Matrix matrix, Matrix matrix2)
{
    return matrix + (matrix2 * -1);
}

Транспонирование матрицы

Транспонированная матрица — это перевернутая по диагонали матрица. Например если B — это транспонированная матрица A, то A[i,j] = B[j,i].

public Matrix CreateTransposeMatrix()
{
    var result = new Matrix(this.N, this.M);
    result.ProcessFunctionOverData((i, j) => result[i, j] = this[j, i]);
    return result;
}

Сравнение чисел с плавающей точкой на C#

Для проекта с матрицами тесты написаны на xUnit. К сожалению у него нет возможности корректно сравнивать числа с плавающей точкой, поэтому я реализовал такой вспомогательный метод

public static void AssertDoubleEqual(double expected, double actual)
{
    try
    {
        Assert.InRange(expected - actual, 
            -Constants.DoubleComparisonDelta, 
            Constants.DoubleComparisonDelta);
    }
    catch (InRangeException)
    {
        throw new EqualException(expected, actual);
    }
}

который сравнивает числа правильно, и если они не равны — бросает понятное исключение. Константа для сравнения у меня объявлена так:

public static class Constants
{
    public const double DoubleComparisonDelta = 0.0000001;
}

Рабочий код лежит на гитхабе

Tags: