User:Eliora/Worst EDOs
import numpy as np
import matplotlib.pyplot as plt
phi = (1 + np.sqrt(5)) / 2
tau = 1 / phi**2
alpha = 2 * phi
beta = 1
x = np.linspace(0, 0.5, 1000)
y = x**alpha * (0.5 - x)**beta
y /= y.max()
plt.figure(figsize=(8,4))
plt.plot(x, y, lw=2)
plt.axvline(tau, color='red', ls='--', label=r'$\tau=1/\varphi^2$')
plt.xlabel("Error")
plt.ylabel("Score")
plt.title("Golden-ratio Beta-style bump")
plt.grid(True)
plt.legend()
plt.show()
import numpy as np
import matplotlib.pyplot as plt
N = 10000 # Search EDOs from 1 to N
num_primes = 25 # Number of prime harmonics
phi = (1 + np.sqrt(5)) / 2
tau = 1 / phi**2
alpha = 2 * phi
beta = 1
def beta_bump(x):
y = x**alpha * (0.5 - x)**beta
peak = tau**alpha * (0.5 - tau)**beta
return y / peak
def first_primes(n):
primes = []
k = 2
while len(primes) < n:
is_prime = True
for p in primes:
if p * p > k:
break
if k % p == 0:
is_prime = False
break
if is_prime:
primes.append(k)
k += 1
return np.array(primes)
primes = first_primes(num_primes + 1)[1:]
weights = 2.0 ** (-np.arange(1, num_primes + 1))
weights /= weights.sum()
scores = []
for edo in range(1, N + 1):
logs = edo * np.log2(primes)
# distance to nearest integer, in EDO steps
errors = np.abs(logs - np.round(logs))
# normalize to [0,0.5]
errors = np.minimum(errors, 1 - errors)
score = np.sum(weights * beta_bump(errors))
scores.append(score)
scores = np.array(scores)
ranking = np.argsort(scores)[::-1]
print("Worst EDOs according to golden-error score:\n")
for rank, idx in enumerate(ranking[:30], start=1):
edo = idx + 1
score = scores[idx]
print(f"{rank:2d}. {edo:4d}-EDO score = {score:.8f} distance from ideal = {1-score:.8f}")
plt.figure(figsize=(10,5))
plt.plot(np.arange(1, N+1), scores)
plt.xlabel("EDO")
plt.ylabel("Golden badness score")
plt.grid(True)
plt.show()
Recordholders
Record-holder progression:
1-EDO score = 0.79348366 distance from ideal = 0.20651634 8-EDO score = 0.83520073 distance from ideal = 0.16479927 54-EDO score = 0.89628624 distance from ideal = 0.10371376 175-EDO score = 0.93106554 distance from ideal = 0.06893446 225-EDO score = 0.94135007 distance from ideal = 0.05864993
1514-EDO score = 0.95731194 distance from ideal = 0.04268806 9709-EDO score = 0.95906127 distance from ideal = 0.04093873
Interestingly, this:
# ---------- 1/p^2 weighting ----------
- Assumes beta_bump(), first_primes(), N and num_primes already exist.
- Odd primes only
primes = first_primes(num_primes + 1)[1:]
- Normalize weights
weights = 1.0 / primes**2
weights /= weights.sum()
scores_p2 = []
for edo in range(1, N + 1):
logs = edo * np.log2(primes)
# Distance to nearest integer
errors = np.abs(logs - np.round(logs))
errors = np.minimum(errors, 1 - errors)
score = np.sum(weights * beta_bump(errors))
scores_p2.append(score)
scores_p2 = np.array(scores_p2)
- ---------- Record holders ----------
best_score = -1
print("Record-holder progression (1/p² weighting):\n")
for edo, score in enumerate(scores_p2, start=1):
if score > best_score:
best_score = score
print(f"{edo:5d}-EDO score = {score:.8f} distance = {1-score:.8f}")
Produces the same sequence:
Record-holder progression (1/p² weighting):
1-EDO score = 0.79730468 distance = 0.20269532 8-EDO score = 0.81988848 distance = 0.18011152 54-EDO score = 0.89675569 distance = 0.10324431 175-EDO score = 0.92591451 distance = 0.07408549 225-EDO score = 0.92620065 distance = 0.07379935 1514-EDO score = 0.94713238 distance = 0.05286762
This indicates that: