User:Akselai/Programs

From Xenharmonic Wiki
Jump to navigation Jump to search

A list of programs that implement technical xenharmonic concepts.

A good algorithm is worth a thousand tables.

Delta-rational chords

def argmin(list1):
    return list1.index(min(list1))

def closest_denom(x, n):
    return round(n/x)

def chord_differential(chord, ji, eps):
    ji = [x + eps for x in ji]
    ji_diff = [abs(ji[i]/ji[0] - chord[i]) for i in range(len(ji))]
    df = max(ji_diff)
    return df

def find_minimum(f, min, max):
    return find_minimum_a(f, min, max, 40)

def find_minimum_a(f, min, max, partitions):
    if max - min < 0.00001:
        return [(min + max) / 2, f((min + max) / 2)]
    values = [float(f(min + (max-min) / partitions * i)) for i in range(0, partitions+1)]
    m = argmin(values)
    return find_minimum_a(f, min + (max-min) / partitions * (m-1), min + (max-min) / partitions * (m+1), 5)

def delta_rational(chord, limit, offset):
    chord = [1] + chord
    smallest = 10
    result = []
    for l in range(1, limit+1):
        ji = [closest_denom(chord[-1]/x, l) for x in chord]
        df = chord_differential(chord, ji, offset)
        if df <= smallest:
            result = [ji, df]
            smallest = df
    return result

def as_plus_notation(chord):
    return ' '.join(['+' + str(chord[i+1] - chord[i]) for i in range(len(chord) - 1)])

# PARAMETERS HERE
edo = 10
limit = 19

def f_t(i, j, t):
    return delta_rational([2^(i/edo), 2^(j/edo)], limit, t)[1]

for i in range(1, edo):
    for j in range(i+1, edo):
        minim = find_minimum(lambda t: f_t(i, j, t), -0.5, 0.5)
        if minim[1] <= 0.01:
            res = delta_rational([2^(i/edo), 2^(j/edo)], limit, minim[0])
            print("chord: 0-" + str(i) + "-" + str(j))
            print(res[0])
            print(as_plus_notation(res[0]), 'offset:', float('%.5g' % minim[0]))
            print('score: %s' % float('%.3g' % res[1]))
            print('-' * 16)