def modular_sqrt(a, p): if legendre_symbol(a, p) != 1: return 0 elif a == 0: return 0 elif p == 2: return p elif p % 4 == 3: return pow(a, (p + 1) / 4, p) b = BigInt.BigInt(2) while (legendre_symbol(b, p) == 1): b += 1 t = p - 1 s = BigInt.BigInt(0) while (t % 2 == 0): t /= 2 s += 1 invArr = Sol_Con.LinCon(a, BigInt.BigInt(1), p) invA = invArr[0] c = pow(b, t, p) r = pow(a, (t + 1) / 2, p) i = BigInt.BigInt(1) while (i < s): e = pow(BigInt.BigInt(2), s - i - 1, p) d = pow(r * r * invA, e, p) if (d == p - 1): r = (r * c) % p c = (c * c) % p i += 1 res = [r, -r] return res
def GCD_ex(a, b): if b == 0: return a, 1, 0 if a == 0: return b, 1, 0 x1 = BigInt.BigInt(0) x2 = BigInt.BigInt(1) y1 = BigInt.BigInt(1) y2 = BigInt.BigInt(0) while b != 0: q = a / b r = a % b a = b b = r xx = x2 - x1 * q yy = y2 - y1 * q x2 = x1 x1 = xx y2 = y1 y1 = yy x = x2 y = y2 return a, x, y
def RhoPollard(alpha, beta, N): n = N - 1 x = BigInt.BigInt(1) a = BigInt.BigInt(0) b = BigInt.BigInt(0) X = x A = a B = b i = BigInt.BigInt(1) while (i < n): x, a, b = new_xab(x, a, b, n, N, alpha, beta) X, A, B = new_xab(X, A, B, n, N, alpha, beta) X, A, B = new_xab(X, A, B, n, N, alpha, beta) i += 1 if (x == X and i > 2): if (B - b) == 0: return None Bb = B - b Aa = A - a if Bb < 0: Bb = b - B if Aa < 0: Aa = a - A res = Sol_Con.LinCon(Bb, Aa, n) if (res == -1): return -1 if (res == -2): return -2 else: return res[0]
def Yakoby(a, p): if (Euclid_simple.GCD(a, p) != 1): return 0 r = BigInt.BigInt(1) if (a < 0): a = -a if (p % 4 == 3): r = -r while (a != 0): t = BigInt.BigInt(0) while (a % 2 == 0): t += 1 a = a / 2 if (t % 2 == 1): if ((p % 8 == 3) or (p % 8 == 5)): r = -r if ((a % 4 == 3) and (p % 4 == 3)): r = -r c = a a = p % c p = c return r
def func(x, y, msg): if y == 0: with self.assertRaises(ZeroDivisionError): BigInt(x) // BigInt(y) else: self.assertEqual(BigInt(x) // BigInt(y), BigInt(x // y), msg=msg)
def __eq__(self, other): if type(self) is not type(other): return False if self.numerator == BigInt(0): return other.numerator == BigInt(0) else: # check signs and cross multiply return self.positive == other.positive and self.numerator * other.denominator == self.denominator * other.numerator
def func(a, b, c, d, msg): if b == 0 or d == 0: pass else: x = Rational(BigInt(a), BigInt(b)) fx = Fraction(a, b) y = Rational(BigInt(c), BigInt(d)) fy = Fraction(c, d) self.assertEqual(x == y, fx == fy, msg=msg)
def func(x, y, msg): if y == 0: pass else: frac = -Fraction(x, y) self.assertEqual(-Rational(BigInt(x), BigInt(y)), Rational(BigInt(frac.numerator), BigInt(frac.denominator)), msg=msg)
def __init__(self,m): self.modulus = biCopy(m) self.k = biHighIndex(self.modulus) + 1 b2k = BigInt(False) b2k.digits[2 * self.k] = 1 # // b2k = b^(2k) #print "b2k= ",b2k.digits,"modulus= ",self.modulus.digits self.mu = biDivide(b2k, self.modulus) #--Error--# self.bkplus1 = BigInt(False) self.bkplus1.digits[self.k + 1] = 1 # // bkplus1 = b^(k+1)
def simplify(self): if self.numerator == BigInt(0): return Rational(BigInt(0), BigInt(1)) else: gcd = self.numerator.gcd(self.denominator) numerator = self.numerator // gcd denominator = self.denominator // gcd ans = Rational(numerator, denominator) ans.positive = self.positive return ans
def func(a, b, c, d, msg): if b == 0 or d == 0: pass else: x = Rational(BigInt(a), BigInt(b)) y = Rational(BigInt(c), BigInt(d)) x2, y2 = x.lcd(y) self.assertEqual(x, x2, msg=msg) self.assertEqual(y, y2, msg=msg) self.assertEqual(x2.denominator, y2.denominator, msg=msg)
def func(x, y, msg): old = Rational(BigInt(x), BigInt(y)) a = old.simplify() self.assertEqual(old.positive, a.positive) self.assertEqual(a.numerator, BigInt(Fraction(x, y).numerator), msg=msg) self.assertEqual(a.denominator, BigInt(Fraction(x, y).denominator), msg=msg)
def test_int_init(self): n = BigInt(1234) self.assertEqual(n.digits, (1, 2, 3, 4)) self.assertTrue(n.positive) n = BigInt(-1234) self.assertEqual(n.digits, (1, 2, 3, 4)) self.assertFalse(n.positive) n = BigInt(-0) self.assertEqual(n.digits, (0, )) self.assertTrue(n.positive)
def test_length(self): a = BigInt(123) b = BigInt(-123300) c = BigInt(0) d = BigInt(1) e = BigInt(-12) self.assertEqual(a.length(), BigInt(3)) self.assertEqual(b.length(), BigInt(6)) self.assertEqual(c.length(), BigInt(1)) self.assertEqual(d.length(), BigInt(1)) self.assertEqual(e.length(), BigInt(2))
def ChinRemTheorem(R, A): M = BigInt.BigInt(1) for Ai in A: M *= Ai x = BigInt.BigInt(0) for i in range(len(A)): Mi = M / A[i] invArr = LinCon(Mi, BigInt.BigInt(1), A[i]) MiInv = invArr[0] x = (x + R[i] * Mi * MiInv) % M return x, M
def __init__(self, numerator, denominator=BigInt(1)): if type(numerator) is not type( BigInt(0)) or type(denominator) is not type(BigInt(0)): raise TypeError('{0}, {1}'.format(type(numerator), type(denominator))) if denominator == BigInt(0): raise ZeroDivisionError('Rational({0}, {1})'.format( numerator, denominator)) else: self.numerator = abs(numerator) self.denominator = abs(denominator) self.positive = numerator.positive == denominator.positive if numerator == BigInt(0): self.positive = True
def func(a, b, c, d, msg): if b == 0 or d == 0: pass else: x = Rational(BigInt(a), BigInt(b)) fx = Fraction(a, b) y = Rational(BigInt(c), BigInt(d)) fy = Fraction(c, d) self.assertEqual(x < y, fx < fy, msg=msg + "|| x={0}, y={1}".format(*x.lcd(y))) self.assertEqual(x <= y, fx <= fy, msg=msg + "|| x={0}, y={1}".format(*x.lcd(y)))
def __neg__(self): if self.numerator == BigInt(0): return self else: ans = Rational(self.numerator, self.denominator) ans.positive = not self.positive return ans
def __add__(self, other): if type(self) is not type(other): raise TypeError('{0} {1}'.format(type(self), type(other))) if self.numerator == BigInt(0): return other elif other.numerator == BigInt(0): return self elif self.positive == other.positive: s, o = self.lcd(other) numerator = s.numerator + o.numerator denominator = s.denominator ans = Rational(numerator, denominator) ans.positive = s.positive return ans else: return self - -other
def func(x, y, msg): if y == 0: with self.assertRaises(ZeroDivisionError): Rational(BigInt(x), BigInt(y)) else: a = Rational(BigInt(x), BigInt(y)) if x == 0: self.assertEqual(a.numerator, BigInt(0), msg=msg) self.assertEqual(a.denominator, abs(BigInt(y)), msg=msg) self.assertTrue(a.positive, msg=msg) else: self.assertEqual(a.numerator, abs(BigInt(x)), msg=msg) self.assertEqual(a.denominator, abs(BigInt(y)), msg=msg) if BigInt(x).positive == BigInt(y).positive: self.assertTrue(a.positive, msg=msg) else: self.assertFalse(a.positive, msg=msg)
def pow(a, b, m): a %= m res = BigInt.BigInt(1) while (b > 0): b -= 1 res = (res * a) % m return res
def __mul__(self, other): if type(self) is not type(other): raise TypeError('{0} {1}'.format(type(self), type(other))) ans = Rational(self.numerator * other.numerator, self.denominator * other.denominator) ans.positive = self.positive == other.positive if ans.numerator == BigInt(0): ans.positive = True return ans
def func(a, b, c, d, msg): if b == 0 or d != 1: pass elif a == 0 and c < 0: with self.assertRaises(ZeroDivisionError): ans = Rational(BigInt(a), BigInt(b))**BigInt(c) else: ans = Rational(BigInt(a), BigInt(b))**BigInt(c) frac = Fraction(a, b)**c fracans = Rational(BigInt(frac.numerator), BigInt(frac.denominator)) self.assertEqual(ans, fracans, msg=msg)
def test_list_init(self): n = BigInt([1, 2, 3, 4]) self.assertEqual(n.digits, (1, 2, 3, 4)) self.assertTrue(n.positive) # negative n = BigInt([1, 2, 3, 4], False) self.assertEqual(n.digits, (1, 2, 3, 4)) self.assertFalse(n.positive) # non-int in list with self.assertRaisesRegex( ValueError, "list must contain only ints: '2' is not an int"): BigInt([1, "2", 3, 4]) # negative in list with self.assertRaisesRegex(ValueError, "digits must be non-negative: -1"): BigInt([-1, 2, 3, 4]) # leading zeroes n = BigInt([0, 1, 2, 0, 0], True) self.assertEqual(n.digits, (1, 2, 0, 0)) self.assertTrue(n.positive) n = BigInt([0], True) self.assertEqual(n.digits, (0, )) self.assertTrue(n.positive) n = BigInt([0, 0], True) self.assertEqual(n.digits, (0, )) self.assertTrue(n.positive) # -0 is 0 n = BigInt([0], False) self.assertEqual(n.digits, (0, )) self.assertTrue(n.positive) n = BigInt([0, 0], False) self.assertEqual(n.digits, (0, )) self.assertTrue(n.positive) # empty with self.assertRaisesRegex(ValueError, "\[\]"): BigInt([], True)
def Garners_Alg(R, A): # inverses, inverses[j,i] = aj^(-1) mod ai inverses = [] for i in range(len(A)): inverses.append([BigInt.BigInt(0)] * len(A)) for i in range(len(A)): for j in range(i): invArr = Sol_Con.LinCon(A[j], BigInt.BigInt(1), A[i]) inverses[j][i] = invArr[0] x = [BigInt.BigInt(0)] * len(A) for i in range(len(A)): x[i] = R[i] for j in range(i): x[i] = inverses[j][i] * (x[i] - x[j]) x[i] = x[i] % A[i] if (x[i] < 0): x[i] += A[i] return x
def test_compare(self): def func(x, y, msg): self.assertEqual(x > y, BigInt(x) > BigInt(y), msg=msg) self.assertEqual(x >= y, BigInt(x) >= BigInt(y), msg=msg) self.assertEqual(x < y, BigInt(x) < BigInt(y), msg=msg) self.assertEqual(x <= y, BigInt(x) <= BigInt(y), msg=msg) return x > y == BigInt(x) < BigInt(y) and x >= y == BigInt( x) >= BigInt(y) and x < y == BigInt(x) < BigInt( y) and x <= y == BigInt(x) <= BigInt(y) self.test_2(func) with self.assertRaises(TypeError): BigInt(123) < 124
def powMod(self, x, y): result = BigInt(False) result.digits[0] = 1 a = x k = y while (1): if ((k.digits[0] & 1) != 0): result = self.multiplyMod(result, a) #print "result = ",result.digits k = biShiftRight(k, 1) #print "test" if (k.digits[0] == 0 and biHighIndex(k) == 0): break a = self.multiplyMod(a, a) #print "k.digits[0]=",k.digits[0],"biHighIndex(k)=",biHighIndex(k) return result
def func(a, b, c, d, msg): if b == 0 or d == 0: pass else: x = Rational(BigInt(a), BigInt(b)) y = Rational(BigInt(c), BigInt(d)) diff = x * y f = Fraction(a, b) * Fraction(c, d) self.assertEqual(diff, Rational(BigInt(f.numerator), BigInt(f.denominator)), msg=msg)
def GCD_bin(a, b): if (a < b): return GCD_bin(b, a) if(b == 0): return a g = BigInt.BigInt(1) while(a % 2 == 0) and (b % 2 == 0): a /= 2 b /= 2 g *= 2 while(a != 0): while(a % 2 == 0): a /= 2 while(b % 2 == 0): b /= 2 if(a >= b): a -= b else: b -= a d = g * b return d
def func(a, b, c, d, msg): if b == 0 or d == 0: pass else: x = Rational(BigInt(a), BigInt(b)) y = Rational(BigInt(c), BigInt(d)) if c == 0: with self.assertRaises(ZeroDivisionError): diff = x / y else: diff = x / y f = Fraction(a, b) / Fraction(c, d) self.assertEqual(diff, Rational(BigInt(f.numerator), BigInt(f.denominator)), msg=msg)