public static MatrixR Minor(MatrixR m, int row, int col)
        {
            MatrixR mm = new MatrixR(m.GetRows() - 1, m.GetCols() - 1);
            int     ii = 0, jj = 0;

            for (int i = 0; i < m.GetRows(); i++)
            {
                if (i == row)
                {
                    continue;
                }
                jj = 0;
                for (int j = 0; j < m.GetCols(); j++)
                {
                    if (j == col)
                    {
                        continue;
                    }
                    mm[ii, jj] = m[i, j];
                    jj++;
                }
                ii++;
            }
            return(mm);
        }
        public static VectorR Transform(VectorR v, MatrixR m)
        {
            VectorR result = new VectorR(v.GetSize());

            if (!m.IsSquared())
            {
                throw new ArgumentOutOfRangeException(
                          "Dimension", m.GetRows(), "The matrix must be squared!");
            }
            if (m.GetRows() != v.GetSize())
            {
                throw new ArgumentOutOfRangeException(
                          "Size", v.GetSize(), "The size of the vector must be equal"
                          + "to the number of rows of the matrix!");
            }
            for (int i = 0; i < m.GetRows(); i++)
            {
                result[i] = 0.0;
                for (int j = 0; j < m.GetCols(); j++)
                {
                    result[i] += v[j] * m[j, i];
                }
            }
            return(result);
        }
        private void LUDecompose(MatrixR m)
        {
            int n = m.GetRows();

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    double d = m[i, j];
                    for (int k = 0; k < Math.Min(i, j); k++)
                    {
                        d -= m[i, k] * m[k, j];
                    }
                    if (j > i)
                    {
                        double dd = m[i, i];
                        if (Math.Abs(d) < epsilon)
                        {
                            throw new ArgumentException("Diagonal element is too small!");
                        }
                        d /= dd;
                    }
                    m[i, j] = d;
                }
            }
        }
        public static MatrixR Adjoint(MatrixR m)
        {
            if (!m.IsSquared())
            {
                throw new ArgumentOutOfRangeException(
                          "Dimension", m.GetRows(), "The matrix must be squared!");
            }
            MatrixR ma = new MatrixR(m.GetRows(), m.GetCols());

            for (int i = 0; i < m.GetRows(); i++)
            {
                for (int j = 0; j < m.GetCols(); j++)
                {
                    ma[i, j] = Math.Pow(-1, i + j) * (Determinant(Minor(m, i, j)));
                }
            }
            return(ma.GetTranspose());
        }
 public static bool CompareDimension(MatrixR m1, MatrixR m2)
 {
     if (m1.GetRows() == m2.GetRows() && m1.GetCols() == m2.GetCols())
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
        public static double Determinant(MatrixR m)
        {
            double result = 0.0;

            if (!m.IsSquared())
            {
                throw new ArgumentOutOfRangeException(
                          "Dimension", m.GetRows(), "The matrix must be squared!");
            }
            if (m.GetRows() == 1)
            {
                result = m[0, 0];
            }
            else
            {
                for (int i = 0; i < m.GetRows(); i++)
                {
                    result += Math.Pow(-1, i) * m[0, i] * Determinant(MatrixR.Minor(m, 0, i));
                }
            }
            return(result);
        }
        public MatrixR LUInverse(MatrixR m)
        {
            int     n = m.GetRows();
            MatrixR u = m.Identity();

            LUDecompose(m);
            VectorR uv = new VectorR(n);

            for (int i = 0; i < n; i++)
            {
                uv = u.GetRowVector(i);
                LUSubstitute(m, uv);
                u.ReplaceRow(uv, i);
            }
            MatrixR inv = u.GetTranspose();

            return(inv);
        }
        private void Triangulate(MatrixR A, VectorR b)
        {
            int     n = A.GetRows();
            VectorR v = new VectorR(n);

            for (int i = 0; i < n - 1; i++)
            {
                //double d = A[i, i];
                double d = pivot(A, b, i);
                if (Math.Abs(d) < epsilon)
                {
                    throw new ArgumentException("Diagonal element is too small!");
                }
                for (int j = i + 1; j < n; j++)
                {
                    double dd = A[j, i] / d;
                    for (int k = i + 1; k < n; k++)
                    {
                        A[j, k] -= dd * A[i, k];
                    }
                    b[j] -= dd * b[i];
                }
            }
        }
 public MatrixR(MatrixR m)
 {
     Rows   = m.GetRows();
     Cols   = m.GetCols();
     matrix = m.matrix;
 }