44except ImportError :
55 import unittest
66import hypothesis .strategies as st
7- from hypothesis import given
7+ from hypothesis import given , settings , example
8+ try :
9+ from hypothesis import HealthCheck
10+ HC_PRESENT = True
11+ except ImportError :
12+ HC_PRESENT = False
813from .numbertheory import (SquareRootError , factorization , gcd , lcm ,
914 jacobi , inverse_mod ,
1015 is_prime , next_prime , smallprimes ,
@@ -79,32 +84,6 @@ def test_numbertheory():
7984 print_ ("Failed to report no root for sqrt( %d ) mod %d." % \
8085 (nonsquare , p ))
8186
82- # Test the jacobi function:
83- for m in range (3 , 400 , 2 ):
84- print_ ("Testing jacobi for modulus m = %d." % m )
85- if is_prime (m ):
86- squares = []
87- for root in range (1 , m ):
88- if jacobi (root * root , m ) != 1 :
89- error_tally = error_tally + 1
90- print_ ("jacobi( %d * %d, %d) != 1" % (root , root , m ))
91- squares .append (root * root % m )
92- for i in range (1 , m ):
93- if i not in squares :
94- if jacobi (i , m ) != - 1 :
95- error_tally = error_tally + 1
96- print_ ("jacobi( %d, %d ) != -1" % (i , m ))
97- else : # m is not prime.
98- f = factorization (m )
99- for a in range (1 , m ):
100- c = 1
101- for i in f :
102- c = c * jacobi (a , i [0 ]) ** i [1 ]
103- if c != jacobi (a , m ):
104- error_tally = error_tally + 1
105- print_ ("%d != jacobi( %d, %d )" % (c , a , m ))
106-
107-
10887 class FailedTest (Exception ):
10988 pass
11089
@@ -123,7 +102,45 @@ def st_two_nums_rel_prime(draw):
123102 return num , mod
124103
125104
105+ HYP_SETTINGS = {}
106+ if HC_PRESENT :
107+ HYP_SETTINGS ['suppress_health_check' ]= [HealthCheck .filter_too_much ,
108+ HealthCheck .too_slow ]
109+ # the factorization() sometimes takes a long time to finish
110+ HYP_SETTINGS ['deadline' ] = 5000
111+
112+
126113class TestNumbertheory (unittest .TestCase ):
114+ @settings (** HYP_SETTINGS )
115+ @given (st .integers (min_value = 1 , max_value = 10 ** 12 ))
116+ @example (265399 * 1526929 )
117+ @example (373297 ** 2 * 553991 )
118+ def test_factorization (self , num ):
119+ factors = factorization (num )
120+ mult = 1
121+ for i in factors :
122+ mult *= i [0 ] ** i [1 ]
123+ assert mult == num
124+
125+ @settings (** HYP_SETTINGS )
126+ @given (st .integers (min_value = 3 , max_value = 1000 ).filter (lambda x : x % 2 ))
127+ def test_jacobi (self , mod ):
128+ if is_prime (mod ):
129+ squares = set ()
130+ for root in range (1 , mod ):
131+ assert jacobi (root * root , mod ) == 1
132+ squares .add (root * root % mod )
133+ for i in range (1 , mod ):
134+ if i not in squares :
135+ assert jacobi (i , mod ) == - 1
136+ else :
137+ factors = factorization (mod )
138+ for a in range (1 , mod ):
139+ c = 1
140+ for i in factors :
141+ c *= jacobi (a , i [0 ]) ** i [1 ]
142+ assert c == jacobi (a , mod )
143+
127144 @given (st_two_nums_rel_prime ())
128145 def test_inverse_mod (self , nums ):
129146 num , mod = nums
0 commit comments