/**
         * 实现矩阵的乘法
         *
         * @param other - 与指定矩阵相乘的矩阵
         * @return Matrix型,指定矩阵与other相乘之积
         * @如果矩阵的行/列数不匹配,则会抛出异常
         */
        public Matrix Multiply(Matrix other)
        {
            // 首先检查行列数是否符合要求
            if (numColumns != other.GetNumRows())
            {
                throw new Exception("矩阵的行/列数不匹配。");
            }

            // ruct the object we are going to return
            Matrix result = new Matrix(numRows, other.GetNumColumns());

            // 矩阵乘法,即
            //
            // [A][B][C]   [G][H]     [A*G + B*I + C*K][A*H + B*J + C*L]
            // [D][E][F] * [I][J] =   [D*G + E*I + F*K][D*H + E*J + F*L]
            //             [K][L]
            //
            double value;

            for (int i = 0; i < result.GetNumRows(); ++i)
            {
                for (int j = 0; j < other.GetNumColumns(); ++j)
                {
                    value = 0.0;
                    for (int k = 0; k < numColumns; ++k)
                    {
                        value += GetElement(i, k) * other.GetElement(k, j);
                    }

                    result.SetElement(i, j, value);
                }
            }

            return(result);
        }
        /**
         * 矩阵的转置
         *
         * @return Matrix型,指定矩阵转置矩阵
         */
        public Matrix Transpose()
        {
            // 构造目标矩阵
            Matrix Trans = new Matrix(numColumns, numRows);

            // 转置各元素
            for (int i = 0; i < numRows; ++i)
            {
                for (int j = 0; j < numColumns; ++j)
                {
                    Trans.SetElement(j, i, GetElement(i, j));
                }
            }

            return(Trans);
        }
        /**
         * 实现矩阵的数乘
         *
         * @param value - 与指定矩阵相乘的实数
         * @return Matrix型,指定矩阵与value相乘之积
         */
        public Matrix Multiply(double value)
        {
            // 构造目标矩阵
            Matrix result = new Matrix(this);           // copy ourselves

            // 进行数乘
            for (int i = 0; i < numRows; ++i)
            {
                for (int j = 0; j < numColumns; ++j)
                {
                    result.SetElement(i, j, result.GetElement(i, j) * value);
                }
            }

            return(result);
        }
        /**
         * 实现矩阵的减法
         *
         * @param other - 与指定矩阵相减的矩阵
         * @return Matrix型,指定矩阵与other相减之差
         * @如果矩阵的行/列数不匹配,则会抛出异常
         */
        public Matrix Subtract(Matrix other)
        {
            if (numColumns != other.GetNumColumns() ||
                numRows != other.GetNumRows())
            {
                throw new Exception("矩阵的行/列数不匹配。");
            }

            // 构造结果矩阵
            Matrix result = new Matrix(this);           // 拷贝构造

            // 进行减法操作
            for (int i = 0; i < numRows; ++i)
            {
                for (int j = 0; j < numColumns; ++j)
                {
                    result.SetElement(i, j, result.GetElement(i, j) - other.GetElement(i, j));
                }
            }

            return(result);
        }
        /**
         * 实现矩阵的加法
         *
         * @param other - 与指定矩阵相加的矩阵
         * @return Matrix型,指定矩阵与other相加之和
         * @如果矩阵的行/列数不匹配,则会抛出异常
         */
        public Matrix Add(Matrix other)
        {
            // 首先检查行列数是否相等
            if (numColumns != other.GetNumColumns() ||
                numRows != other.GetNumRows())
            {
                throw new Exception("矩阵的行/列数不匹配。");
            }

            // 构造结果矩阵
            Matrix result = new Matrix(this);           // 拷贝构造

            // 矩阵加法
            for (int i = 0; i < numRows; ++i)
            {
                for (int j = 0; j < numColumns; ++j)
                {
                    result.SetElement(i, j, result.GetElement(i, j) + other.GetElement(i, j));
                }
            }

            return(result);
        }
        /**
         * 实矩阵求逆的全选主元高斯-约当法
         *
         * @return bool型,求逆是否成功
         */
        public Matrix InvertGaussJordan()
        {
            // 构造目标矩阵
            Matrix invert = new Matrix(numColumns, numRows);
            Matrix keep   = new Matrix(numColumns, numRows);

            // 保持各元素
            for (int i1 = 0; i1 < numRows; ++i1)
            {
                for (int j1 = 0; j1 < numColumns; ++j1)
                {
                    keep.SetElement(i1, j1, GetElement(i1, j1));
                }
            }

            int    i, j, k, l, u, v;
            double d = 0, p = 0;

            // 分配内存
            int[] pnRow = new int[numColumns];
            int[] pnCol = new int[numColumns];

            // 消元
            for (k = 0; k <= numColumns - 1; k++)
            {
                d = 0.0;
                for (i = k; i <= numColumns - 1; i++)
                {
                    for (j = k; j <= numColumns - 1; j++)
                    {
                        l = i * numColumns + j; p = Math.Abs(elements[l]);
                        if (p > d)
                        {
                            d        = p;
                            pnRow[k] = i;
                            pnCol[k] = j;
                        }
                    }
                }

                // 失败
                if (d == 0.0)
                {
                    throw new Exception("求逆失败!矩阵行列式为零!");
                }

                if (pnRow[k] != k)
                {
                    for (j = 0; j <= numColumns - 1; j++)
                    {
                        u           = k * numColumns + j;
                        v           = pnRow[k] * numColumns + j;
                        p           = elements[u];
                        elements[u] = elements[v];
                        elements[v] = p;
                    }
                }

                if (pnCol[k] != k)
                {
                    for (i = 0; i <= numColumns - 1; i++)
                    {
                        u           = i * numColumns + k;
                        v           = i * numColumns + pnCol[k];
                        p           = elements[u];
                        elements[u] = elements[v];
                        elements[v] = p;
                    }
                }

                l           = k * numColumns + k;
                elements[l] = 1.0 / elements[l];
                for (j = 0; j <= numColumns - 1; j++)
                {
                    if (j != k)
                    {
                        u           = k * numColumns + j;
                        elements[u] = elements[u] * elements[l];
                    }
                }

                for (i = 0; i <= numColumns - 1; i++)
                {
                    if (i != k)
                    {
                        for (j = 0; j <= numColumns - 1; j++)
                        {
                            if (j != k)
                            {
                                u           = i * numColumns + j;
                                elements[u] = elements[u] - elements[i * numColumns + k] * elements[k * numColumns + j];
                            }
                        }
                    }
                }

                for (i = 0; i <= numColumns - 1; i++)
                {
                    if (i != k)
                    {
                        u           = i * numColumns + k;
                        elements[u] = -elements[u] * elements[l];
                    }
                }
            }

            // 调整恢复行列次序
            for (k = numColumns - 1; k >= 0; k--)
            {
                if (pnCol[k] != k)
                {
                    for (j = 0; j <= numColumns - 1; j++)
                    {
                        u           = k * numColumns + j;
                        v           = pnCol[k] * numColumns + j;
                        p           = elements[u];
                        elements[u] = elements[v];
                        elements[v] = p;
                    }
                }

                if (pnRow[k] != k)
                {
                    for (i = 0; i <= numColumns - 1; i++)
                    {
                        u           = i * numColumns + k;
                        v           = i * numColumns + pnRow[k];
                        p           = elements[u];
                        elements[u] = elements[v];
                        elements[v] = p;
                    }
                }
            }
            invert.SetData(elements); //存储求逆后的矩阵
            this.SetData(keep);       //保持原矩阵不变
            //Console.WriteLine(invert);
            //Console.WriteLine(keep);
            //Console.WriteLine(this);
            //Console.ReadLine();
            // 成功返回
            return(invert);
        }