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); }
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]; } } }
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); }