Recurrent sequence scales
Given a recurrent sequence like the Fibonacci sequence
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
pick a start point and end point, say 3 and 34, take the segment between them
3, 5, 8, 13, 21, 34
divide by the smallest term
3/3, 5/3, 8/3, 13/3, 21/3, 34/3
then octave-reduce and sort to give the scale
1/1, 13/12, 4/3, 17/12, 5/3, 7/4
with period 2/1.
As you move along a recurrent sequence, the ratio between successive terms approaches a limit (1.618, or 833ยข, for the Fibonacci sequence). This means that segments far along the sequence approach scales built by stacking a generator. This gives a connection to moments of symmetry.
Further reading
Python code
"""
>>> scale1 = recurrent_sequence_scale((1, 1), (1, 1), 3, 8)
>>> scale2 = recurrent_sequence_scale((1, 1), (1, 1), 6, 11)
>>> scale3 = sorted((i * 833) % 1200 for i in range(6))
>>> print([round(1200 * log2(x)) for x in scale1])
[0, 139, 498, 603, 884, 969]
>>> print([round(1200 * log2(x)) for x in scale2])
[0, 97, 464, 563, 830, 930]
>>> print(scale3)
[0, 99, 466, 565, 833, 932]
"""
from fractions import Fraction
from math import log2, floor
def reduce(x):
return x * Fraction(2) ** (-floor(log2(x)))
def recurrent_sequence_scale(coeffs, seed, start, stop):
"""
>>> recurrent_sequence_scale((1, 1), (1, 1), 3, 8)
[Fraction(1, 1), Fraction(13, 12), Fraction(4, 3), Fraction(17, 12), Fraction(5, 3), Fraction(7, 4)]
"""
seq = list(seed)
while len(seq) <= stop:
seq.append(sum(c * seq[-i] for i, c in enumerate(coeffs, 1)))
segment = seq[start : stop + 1]
return sorted(set(reduce(Fraction(x, segment[0])) for x in segment))
Scales
| File | Call |
|---|---|
| raph | recurrent_sequence_scale((0, 1, 0, 1), (45, 57, 73, 93), 0, 11) |
| xen13-mclaren-recurrence-1 | recurrent_sequence_scale((1, 1), (1, 1), 0, 10) |