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); }
private static BigInteger Parse(Stack <TOKEN> stack, Priority priority, bool endbracket) { if (stack.Count == 0) { throw new Exception("Expression Parsing Error."); } int minus = 1; BigInteger v = 0; TOKEN t = stack.Pop(); //get -, +, integer or bracket if (t.ttype == TOKEN.Ttype.MINUS) { minus = -1; t = stack.Pop(); //get integer or bracket } else if (t.ttype == TOKEN.Ttype.PLUS) { minus = 1; t = stack.Pop(); //get integer or bracket } if (t.ttype == TOKEN.Ttype.INTEGER) { v = minus * t.integer; } else if (t.ttype == TOKEN.Ttype.BRACKETOPEN) { v = minus * Parse(stack, Priority.ALL, true); stack.Pop(); //pop the closing bracket } while (stack.Count != 0) { switch (stack.Peek().ttype) //next operator { case TOKEN.Ttype.PLUS: if (priority == Priority.MULTDIV || priority == Priority.POW) { return(v); } stack.Pop(); v = v + Parse(stack, Priority.ADDSUB, endbracket); break; case TOKEN.Ttype.MINUS: if (priority == Priority.MULTDIV || priority == Priority.POW) { return(v); } stack.Pop(); v = v - Parse(stack, Priority.ADDSUB, endbracket); break; case TOKEN.Ttype.MULTIPLY: if (priority == Priority.POW) { return(v); } stack.Pop(); v = v * Parse(stack, Priority.MULTDIV, endbracket); break; case TOKEN.Ttype.DIVIDE: if (priority == Priority.POW) { return(v); } stack.Pop(); v = v / Parse(stack, Priority.MULTDIV, endbracket); break; case TOKEN.Ttype.POW: stack.Pop(); v = BigIntegerHelper.Pow(v, Parse(stack, Priority.POW, endbracket)); break; case TOKEN.Ttype.BRACKETCLOSE: if (endbracket) { return(v); } else { throw new Exception("Expression Parsing Error (closing bracket misplaced)."); } default: throw new Exception("Expression Parsing Error."); } } if (endbracket) { throw new Exception("Expression Parsing Error (closing bracket missing)."); } return(v); }