public MatrixGF2 Subset(int startR, int startC, int numR, int numC)
        {
            if (startR < 0 || mRow <= startR)
            {
                throw new ArgumentOutOfRangeException("startR");
            }
            if (startC < 0 || mCol <= startC)
            {
                throw new ArgumentOutOfRangeException("startC");
            }
            if (numR < 0 || mRow < startR + numR)
            {
                throw new ArgumentOutOfRangeException("numR");
            }
            if (numC < 0 || mCol < startC + numC)
            {
                throw new ArgumentOutOfRangeException("numC");
            }

            var rv = new MatrixGF2(numR, numC);

            for (int r = 0; r < numR; ++r)
            {
                for (int c = 0; c < numC; ++c)
                {
                    rv.Set(r, c, At(startR + r, startC + c));
                }
            }

            return(rv);
        }
        /// <summary>
        /// rv = lhs * rhs
        /// 自分自身(lhs,rhs)を変更しない。
        /// </summary>
        /// <returns>乗算結果。</returns>
        public static MatrixGF2 Mul(MatrixGF2 lhs, MatrixGF2 rhs)
        {
            if (lhs.Column != rhs.Row)
            {
                throw new ArgumentException("lhs.Column != rhs.Row");
            }

            int loopCount = lhs.Column;

            var rv = new MatrixGF2(lhs.Row, rhs.Column);

            Parallel.For(0, rv.Row, r => {
                for (int c = 0; c < rv.Column; ++c)
                {
                    GF2 v = GF2.Zero;
                    for (int i = 0; i < loopCount; ++i)
                    {
                        v = GF2.Add(v, GF2.Mul(lhs.At(r, i), rhs.At(i, c)));
                    }
                    rv.Set(r, c, v);
                }
            });

            return(rv);
        }
        /// <summary>
        /// 転置した行列を戻す。
        /// 自分自身を変更しない。
        /// </summary>
        /// <returns>Transposed Matrix</returns>
        public MatrixGF2 Transpose()
        {
            var rv = new MatrixGF2(mCol, mRow);

            for (int r = 0; r < mRow; ++r)
            {
                for (int c = 0; c < mCol; ++c)
                {
                    rv.Set(c, r, At(r, c));
                }
            }
            return(rv);
        }