示例#1
0
        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);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <summary>
        /// 他の行列aと同じかどうか。
        /// </summary>
        /// <returns>同じなら0。異なるときは0以外。</returns>
        public int CompareTo(MatrixGF2 a)
        {
            if (mRow != a.mRow || mCol != a.mCol)
            {
                // 異なる。
                return(1);
            }

            int acc = 0;

            for (int r = 0; r < mRow; ++r)
            {
                for (int c = 0; c < mCol; ++c)
                {
                    acc += At(r, c).Add(a.At(r, c)).Val;
                }
            }

            return(acc);
        }
示例#5
0
        /// <summary>
        /// 自分自身を変更しない
        /// </summary>
        /// <returns>逆行列</returns>
        public MatrixGF2 Inverse()
        {
            if (mRow != mCol)
            {
                throw new NotImplementedException();
            }
            int n = mRow;

            // org := this
            var org = new MatrixGF2(n, n, m);

            // inv := 単位行列
            var inv = new MatrixGF2(n, n);

            inv.SetIdentity();

            // ピボットの候補
            var pivotList = new List <int>();

            for (int i = 0; i < n; ++i)
            {
                pivotList.Add(i);
            }

            for (int c = 0; c < n; ++c)
            {
                // c列の値が1の行を1つだけにする。

                // c列が値1の行を探す。
                int pivRow = -1;
                foreach (var r in pivotList)
                {
                    if (GF2.One == org.At(r, c))
                    {
                        pivRow = r;
                        break;
                    }
                }
                if (pivRow < 0)
                {
                    // 逆行列が存在しない。
                    return(null);
                }
                pivotList.Remove(pivRow);

                // pivot以外の行のc列の値を0にする。
                for (int r = 0; r < n; ++r)
                {
                    if (r == pivRow)
                    {
                        continue;
                    }

                    if (org.At(r, c) == GF2.One)
                    {
                        org.AddRow(pivRow, r);
                        inv.AddRow(pivRow, r);
                    }
                }
            }

            // 各々の列は値1が1度だけ現れる。

            // sが正方行列になるように行を入れ替える。
            for (int c = 0; c < n; ++c)
            {
                // c列の値が1の行を探す。
                int oneRow = -1;
                for (int r = 0; r < n; ++r)
                {
                    if (org.At(r, c) == GF2.One)
                    {
                        oneRow = r;
                        break;
                    }
                }

                if (oneRow == c)
                {
                    // 既にc列c行が1である。
                    continue;
                }

                // c行とoneRow行を入れ替えてc列c行を1にする。
                org.SwapRow(oneRow, c);
                inv.SwapRow(oneRow, c);
            }

            return(inv);
        }
示例#6
0
 /// <summary>
 /// rv := this * a
 /// 自分自身を変更しない。
 /// </summary>
 /// <returns>乗算結果。</returns>
 public MatrixGF2 Mul(MatrixGF2 a)
 {
     return(Mul(this, a));
 }