예제 #1
0
        public ModMatrix invert()
        {
            ModMatrix mm = new ModMatrix(this);
            ModMatrix mi = new ModMatrix(dimension, modulus);

            BigInteger g = 0, tmp, inv;

            for (int y = 0; y < dimension; y++)
            {
                // find row with invertible leading value
                int yy;
                for (yy = y; yy < dimension; yy++)
                {
                    g = mm[y, yy].GCD(modulus);
                    if (g == 1)
                    {
                        break;
                    }
                }
                if (g != 1)
                {
                    return(null);
                }

                // swap rows y and yy
                for (int x = 0; x < dimension; x++)
                {
                    tmp = mm[x, y]; mm[x, y] = mm[x, yy]; mm[x, yy] = tmp;
                    tmp = mi[x, y]; mi[x, y] = mi[x, yy]; mi[x, yy] = tmp;
                }

                // normalize rows
                inv = BigIntegerHelper.ModInverse(mm[y, y], modulus);
                for (int x = 0; x < dimension; x++)
                {
                    mm[x, y] = (mm[x, y] * inv) % modulus;
                    mi[x, y] = (mi[x, y] * inv) % modulus;
                }

                for (yy = 0; yy < dimension; yy++)
                {
                    if (yy == y)
                    {
                        continue;
                    }
                    tmp = (modulus - mm[y, yy]) % modulus;

                    for (int x = 0; x < dimension; x++)
                    {
                        mm[x, yy] = (mm[x, yy] + tmp * mm[x, y]) % modulus;
                        mi[x, yy] = (mi[x, yy] + tmp * mi[x, y]) % modulus;
                    }
                }
            }

            return(mi);
        }
예제 #2
0
        public ModMatrix(ModMatrix mat)
        {
            dimension = mat.Dimension;
            modulus   = mat.Modulus;
            m         = new BigInteger[dimension, dimension];

            for (int y = 0; y < dimension; y++)
            {
                for (int x = 0; x < dimension; x++)
                {
                    m[x, y] = mat[x, y];
                }
            }
        }
예제 #3
0
        public static ModMatrix operator *(ModMatrix matA, ModMatrix matB)
        {
            ModMatrix result = new ModMatrix(matA.Dimension, matA.Modulus);

            for (int y = 0; y < result.Dimension; y++)
            {
                for (int x = 0; x < result.Dimension; x++)
                {
                    result[x, y] = 0;
                    for (int i = 0; i < result.Dimension; i++)
                    {
                        result[x, y] += matA[i, y] * matB[x, i];
                        result[x, y] %= result.Modulus;
                    }
                }
            }

            return(result);
        }