예제 #1
0
 def te_s_t(a, b):
     g, s, t = gmpy.gcdext(a, b)
     if abs(a) == abs(b):
         test_s = s == 0
     elif b == 0 or abs(b) == 2 * g:
         test_s = s == bool(a > 0) - bool(a < 0)  # sign of a
     else:
         test_s = abs(s) < abs(b) / (2 * g)
     if abs(a) == abs(b) or a == 0 or abs(a) == 2 * g:
         test_t = t == bool(b > 0) - bool(b < 0)  # sign of b
     else:
         test_t = abs(t) < abs(a) / (2 * g)
     return g == a * s + b * t and test_s and test_t
예제 #2
0
    def operation2(cls, f, /):  # Cohen: Algorithm 5.4.8 (NUDUPL)
        a, b, c = f
        d1, u, _ = gcdext(b, a)
        assert d1 == 1  # because -discriminant is prime
        A = a // d1
        B = b // d1
        C = (-c * u) % A
        C1 = A - C
        if C1 < C:
            C = -C1

        d, v3 = A, C
        v2, v = 1, 0
        z = 0
        L = iroot(-cls.discriminant // 4, 4)[0]
        while abs(v3) > L:  # partial Euclid
            d, (q, v3) = v3, divmod(d, v3)
            v, v2, = v2, v - q * v2
            z += 1
        if z % 2:
            v2, v3 = -v2, -v3

        if z == 0:
            g = (B * v3 + c) // d
            a2 = d**2
            b2 = b + 2 * d * v3
            c2 = v3**2 + g * d1
        else:
            e = (c * v + B * d) // A
            h = e * v2
            g = (h - B) // v
            a2 = d**2 + d1 * e * v
            b2 = d1 * (h + v * g) + 2 * d * v3
            c2 = v3**2 + d1 * g * v2
        f2 = int(a2), int(b2), int(
            c2)  # NB: convert from gmpy2.mpz, if gmpy2 is used for gcdext()
        return cls(cls._reduce(f2), check=False)
예제 #3
0
파일: fingroups.py 프로젝트: lschoe/mpyc
    def operation(cls, f1, f2):  # Cohen: Algorithm 5.4.9 (NUCOMP)
        if f1[0] < f2[0]:
            f1, f2 = f2, f1
        a1, b1, c1 = f1
        a2, b2, c2 = f2
        s = (b1 + b2) // 2
        n = b2 - s

        d, u, v = gcdext(a2, a1)
        if d == 1:
            A = -u * n
            d1 = d
        elif s % d == 0:
            A = -u * n
            d1 = d
            a1 //= d1
            a2 //= d1
            s //= d1
        else:
            d1, u1, _ = gcdext(s, d)
            if d1 > 1:
                a1 //= d1
                a2 //= d1
                s //= d1
                d //= d1
            l = (-u1 * (u * (c1 % d) + v * (c2 % d))) % d
            A = -u * (n // d) + l * (a1 // d)
        A = A % a1
        A1 = a1 - A
        if A1 < A:
            A = - A1

        d, v3 = a1, A
        v2, v = 1, 0
        z = 0
        L = iroot(-cls.discriminant//4, 4)[0]
        while abs(v3) > L:  # partial Euclid
            d, (q, v3) = v3, divmod(d, v3)
            v, v2, = v2, v - q * v2
            z += 1
        if z%2:
            v2, v3 = -v2, -v3

        if z == 0:
            Q1 = a2 * v3
            f = (Q1 + n) // d
            g = (v3 * s + c2) // d
            a3 = d * a2
            b3 = 2*Q1 + b2
            c3 = v3 * f + g * d1  # erratum Cohen (step 6)
        else:
            b = (a2 * d + n * v) // a1
            Q1 = b * v3
            Q2 = Q1 + n
            f = Q2 // d
            e = (s * d + c2 * v) // a1
            Q3 = e * v2
            Q4 = Q3 - s
            g = Q4 // v
            a3 = d * b + d1 * e * v
            b3 = Q1 + Q2 + d1 * (Q3 + Q4)
            c3 = v3 * f + d1 * g * v2
        f3 = int(a3), int(b3), int(c3)  # NB: convert from gmpy2.mpz, if gmpy2 is used for gcdext()
        return cls(cls._reduce(f3), check=False)
예제 #4
0
    def test_basic(self):
        self.assertFalse(gmpy.is_prime(1))
        self.assertTrue(gmpy.is_prime(2))
        self.assertTrue(gmpy.is_prime(101))
        self.assertFalse(gmpy.is_prime(561))
        self.assertTrue(gmpy.is_prime(2**16 + 1))
        self.assertFalse(gmpy.is_prime(41041))

        self.assertEqual(gmpy.next_prime(1), 2)
        self.assertEqual(gmpy.next_prime(2), 3)
        self.assertEqual(gmpy.next_prime(256), 257)

        self.assertEqual(gmpy.powmod(3, 256, 257), 1)

        self.assertEqual(gmpy.gcdext(3, 257), (1, 86, -1))
        self.assertEqual(gmpy.gcdext(1234, 257), (1, -126, 605))
        self.assertEqual(gmpy.gcdext(-1234 * 3, -257 * 3), (3, 126, -605))

        def te_s_t(a, b):
            g, s, t = gmpy.gcdext(a, b)
            if abs(a) == abs(b):
                test_s = s == 0
            elif b == 0 or abs(b) == 2 * g:
                test_s = s == bool(a > 0) - bool(a < 0)  # sign of a
            else:
                test_s = abs(s) < abs(b) / (2 * g)
            if abs(a) == abs(b) or a == 0 or abs(a) == 2 * g:
                test_t = t == bool(b > 0) - bool(b < 0)  # sign of b
            else:
                test_t = abs(t) < abs(a) / (2 * g)
            return g == a * s + b * t and test_s and test_t

        self.assertTrue(
            all((te_s_t(0, 0), te_s_t(0, -1), te_s_t(1, 0), te_s_t(-1, 1))))
        self.assertTrue(te_s_t(-1234, 257))
        self.assertTrue(te_s_t(-12537, -257))
        self.assertTrue(te_s_t(-11 * 1234, -11 * 2567))
        self.assertTrue(te_s_t(1234, -2 * 1234))
        self.assertTrue(te_s_t(-2 * 12364, 12364))

        # self.assertEqual(gmpy.invert(3, -1), 0)  # pending gmpy2 issue if modulus is 1 or -1
        self.assertEqual(gmpy.invert(3, 257), 86)
        self.assertRaises(ZeroDivisionError, gmpy.invert, 2, 0)
        self.assertRaises(ZeroDivisionError, gmpy.invert, 2, 4)

        self.assertEqual(gmpy.legendre(0, 101), 0)
        self.assertEqual(gmpy.legendre(42, 101), -1)
        self.assertEqual(gmpy.legendre(54, 101), 1)
        self.assertRaises(ValueError, gmpy.legendre, 1, 2)
        self.assertEqual(gmpy.jacobi(9, 99), 0)
        self.assertEqual(gmpy.jacobi(43, 99), -1)
        self.assertEqual(gmpy.jacobi(53, 99), 1)
        self.assertRaises(ValueError, gmpy.jacobi, 1, 20)
        self.assertEqual(gmpy.kronecker(0, 0), 0)
        self.assertEqual(gmpy.kronecker(-1, 0), 1)
        self.assertEqual(gmpy.kronecker(43, -98), -1)
        self.assertEqual(gmpy.kronecker(-53, -98), 1)
        self.assertEqual(gmpy.kronecker(-54, -98), 0)

        self.assertTrue(gmpy.is_square(625))
        self.assertFalse(gmpy.is_square(652))

        self.assertEqual(gmpy.isqrt(0), 0)
        self.assertEqual(gmpy.isqrt(1225), 35)

        self.assertTrue(gmpy.iroot(0, 10)[1])
        self.assertFalse(gmpy.iroot(1226, 2)[1])
        self.assertEqual(gmpy.iroot(1226, 2)[0], 35)
        self.assertEqual(gmpy.iroot(3**10 + 42, 10)[0], 3)