Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/python/bench/src/nt.py
1067 views
1
# mypy
2
# A little pure python number theory library, which is useful
3
# as a foundation for some microbenchmarks
4
5
from math import sqrt
6
from typing import Tuple
7
8
9
def gcd(a: int, b: int) -> int:
10
while b:
11
c = a % b
12
a = b
13
b = c
14
return a
15
16
17
def xgcd(a: int, b: int) -> Tuple[int, int, int]:
18
prevx, x = 1, 0
19
prevy, y = 0, 1
20
while b:
21
q, r = divmod(a, b)
22
x, prevx = prevx - q * x, x
23
y, prevy = prevy - q * y, y
24
a, b = b, r
25
return a, prevx, prevy
26
27
28
def inverse_mod(a: int, N: int) -> int:
29
"""
30
Compute multiplicative inverse of a modulo N.
31
"""
32
if a == 1 or N <= 1: # common special cases
33
return a % N
34
[g, s, _] = xgcd(a, N)
35
if g != 1:
36
raise ZeroDivisionError
37
b = s % N
38
if b < 0:
39
b += N
40
return b
41
42
43
def trial_division(N: int, bound: int = 0, start: int = 2) -> int:
44
if N <= 1:
45
return N
46
m = 7
47
i = 1
48
dif = [6, 4, 2, 4, 2, 4, 6, 2]
49
if start > 7:
50
m = start % 30
51
if m <= 1:
52
i = 0
53
m = start + (1 - m)
54
elif m <= 7:
55
i = 1
56
m = start + (7 - m)
57
elif m <= 11:
58
i = 2
59
m = start + (11 - m)
60
elif m <= 13:
61
i = 3
62
m = start + (13 - m)
63
elif m <= 17:
64
i = 4
65
m = start + (17 - m)
66
elif m <= 19:
67
i = 5
68
m = start + (19 - m)
69
elif m <= 23:
70
i = 6
71
m = start + (23 - m)
72
elif m <= 29:
73
i = 7
74
m = start + (29 - m)
75
if start <= 2 and N % 2 == 0:
76
return 2
77
if start <= 3 and N % 3 == 0:
78
return 3
79
if start <= 5 and N % 5 == 0:
80
return 5
81
limit = round(sqrt(N))
82
if bound != 0 and bound < limit:
83
limit = bound
84
while m <= limit:
85
if N % m == 0:
86
return m
87
m += dif[i % 8]
88
i += 1
89
90
return N
91
92
93
def is_prime(N: int) -> bool:
94
return N > 1 and trial_division(N) == N
95
96
97
def pi(n: int = 100000) -> int:
98
s = 0
99
for i in range(1, n + 1):
100
if is_prime(i):
101
s += 1
102
return s
103
104