public RationalNumber Determinant()
    {
        int            D      = Dimension;
        RationalNumber result = 0;
        RationalMatrix A      = Clone();

        for (int i = 0; i < D; i++)
        {
            RationalNumber pivot = A[i, i];
            for (int j = 0; j < D; j++)
            {
                if (i != j)
                {
                    for (int k = i + 1; k < D; k++)
                    {
                        RationalNumber divider = i == 0 ? 1 : A[i - 1, i - 1];
                        RationalNumber a       = pivot * A[j, k];
                        RationalNumber b       = A[j, i] * A[i, k];
                        RationalNumber ab      = a - b;
                        ab      = ab / divider;
                        A[j, k] = ab;
                    }
                }
            }
        }

        return(A[D - 1, D - 1]);
    }
    public static RationalMatrix From(double[,] a)
    {
        RationalMatrix M = new RationalMatrix(a.GetLength(0));

        M = a;
        return(M);
    }
    public static RationalMatrix IdentityMatrix(int D)
    {
        RationalMatrix I = new RationalMatrix(D);

        for (int i = 0; i < D; i++)
        {
            I[i, i] = 1;
        }
        return(I);
    }
    public static RationalMatrix operator /(RationalMatrix a, RationalNumber b)
    {
        RationalMatrix M = new RationalMatrix(a.Dimension);

        for (int r = 0; r < M.Dimension; r++)
        {
            for (int c = 0; c < M.Dimension; c++)
            {
                M[r, c] = a[r, c] / b;
            }
        }
        return(M);
    }
    public static RationalMatrix operator *(RationalNumber a, RationalMatrix b)
    {
        RationalMatrix M = new RationalMatrix(b.Dimension);

        for (int r = 0; r < M.Dimension; r++)
        {
            for (int c = 0; c < M.Dimension; c++)
            {
                M[r, c] = a * b[r, c];
            }
        }
        return(M);
    }
    public RationalMatrix Clone()
    {
        int            D = Dimension;
        RationalMatrix M = new RationalMatrix(D);

        for (int r = 0; r < D; r++)
        {
            for (int c = 0; c < D; c++)
            {
                M[r, c] = this[r, c];
            }
        }
        return(M);
    }
    public RationalMatrix TransposeMatrix()
    {
        int            D = Dimension;
        RationalMatrix T = new RationalMatrix(D);

        for (int r = 0; r < D; r++)
        {
            for (int c = 0; c < D; c++)
            {
                T[c, r] = this[r, c];
            }
        }
        return(T);
    }
    public static RationalMatrix operator ^(RationalMatrix a, int exponent)
    {
        if (exponent < 0)
        {
            throw new System.NotSupportedException();
        }
        RationalMatrix R = a.IdentityMatrix();

        while (exponent > 0)
        {
            R *= a;
            exponent--;
        }
        return(R);
    }
    public static RationalMatrix operator -(RationalMatrix a, RationalMatrix b)
    {
        if (a.Dimension != b.Dimension)
        {
            throw new System.NotSupportedException();
        }
        RationalMatrix M = new RationalMatrix(a.Dimension);

        for (int r = 0; r < M.Dimension; r++)
        {
            for (int c = 0; c < M.Dimension; c++)
            {
                M[r, c] = a[r, c] - b[r, c];
            }
        }
        return(M);
    }
    public static RationalMatrix operator *(RationalMatrix a, RationalMatrix b)
    {
        if (a.Dimension != b.Dimension)
        {
            throw new System.NotSupportedException();
        }
        RationalMatrix M = new RationalMatrix(a.Dimension);

        for (int i = 0; i < a.Dimension; i++)
        {
            for (int j = 0; j < a.Dimension; j++)
            {
                for (int k = 0; k < a.Dimension; k++)
                {
                    M[i, j] += a[i, k] * b[k, j];
                }
            }
        }
        return(M);
    }
    public RationalMatrix CofactorMatrix()
    {
        int            D  = Dimension;
        RationalMatrix CF = new RationalMatrix(D);

        if (D == 1)
        {
            CF[0, 0] = 1;
            return(CF);
        }
        int sign;

        for (int i = 0; i < D; i++)
        {
            for (int j = 0; j < D; j++)
            {
                sign     = ((i + j) % 2 == 0) ? 1 : -1;;
                CF[i, j] = MinorMatrix(i, j).Determinant() * sign;
            }
        }
        return(CF);
    }
    private RationalMatrix MinorMatrix(int row, int col)
    {
        int            D = Dimension;
        RationalMatrix M = new RationalMatrix(D - 1);
        int            i = 0;
        int            j = 0;

        for (int r = 0; r < D; r++)
        {
            for (int c = 0; c < D; c++)
            {
                if (r != row && c != col)
                {
                    M[i, j++] = this[r, c];
                    if (j == D - 1)
                    {
                        j = 0;
                        i++;
                    }
                }
            }
        }
        return(M);
    }
    public static RationalMatrix ZeroMatrix(int D)
    {
        RationalMatrix I = new RationalMatrix(D);

        return(I);
    }