Mathematics of MOS: Difference between revisions
ArrowHead294 (talk | contribs) mNo edit summary |
ArrowHead294 (talk | contribs) mNo edit summary |
||
Line 46: | Line 46: | ||
Another common way to view the tones of an MOS scale is as points in logarithmic pitch space, with larger gaps between points representing larger intervals and smaller gaps between points representing smaller intervals. Then we see that our scale has large steps and small steps and intervals that are composed of some stackings of large and small steps. It is not obvious, looking at the generator chain or looking at the tones in pitch space, what the relationship is. Indeed, it is different for different MOS scales—an "L" will not always represent the same number of generators up or down when we move to a different scale. | Another common way to view the tones of an MOS scale is as points in logarithmic pitch space, with larger gaps between points representing larger intervals and smaller gaps between points representing smaller intervals. Then we see that our scale has large steps and small steps and intervals that are composed of some stackings of large and small steps. It is not obvious, looking at the generator chain or looking at the tones in pitch space, what the relationship is. Indeed, it is different for different MOS scales—an "L" will not always represent the same number of generators up or down when we move to a different scale. | ||
Since the generator chain and logarithmic pitch space are both 1-dimensional, it may be helpful to graph them together in 2 dimensions. Here is a diagram for sensi[8], an octatonic [[3L 5s]] MOS scale with a generator of between 442 and 445{{ | Since the generator chain and logarithmic pitch space are both 1-dimensional, it may be helpful to graph them together in 2 dimensions. Here is a diagram for sensi[8], an octatonic [[3L 5s]] MOS scale with a generator of between 442 and 445{{c}}. The x-axis shows the generator chain and the y-axis shows the nine tones (eight plus octave) in logarithmic pitch space. You can see that the vertical lines are evenly-spaced (since every generator is the same), while the horizontal lines have large and small gaps, representing the large and small steps of sensi[8]. | ||
[[File:map_of_sensi-8-.png|alt=Map of Sensi[8].png]] | [[File:map_of_sensi-8-.png|alt=Map of Sensi[8].png]] | ||
Line 56: | Line 56: | ||
** an equal scale (when {{nowrap|L:s {{=}} 2:1}}). | ** an equal scale (when {{nowrap|L:s {{=}} 2:1}}). | ||
Below is a diagram showing four MOS scales in logarithmic pitch space generated by 7\[[37edo]] (approx. | Below is a diagram showing four MOS scales in logarithmic pitch space generated by 7\[[37edo]] (approx. 227{{c}}). Each contains the ones above it and is contained by the ones below it. There are additional MOS scales that would appear above the first line with 1, 2, 3, 4, and 5 tones, but they have been omitted. The bottom line is a case where {{nowrap|L:s {{=}} 2:1}}, which means that there are no more MOS scales to be had—the next stopping point is at a complete chromatic scale of [[37edo]]. | ||
[[File:37edo_mos_07.png]] | [[File:37edo_mos_07.png]] | ||
Line 85: | Line 85: | ||
== Algorithms == | == Algorithms == | ||
Below is some Maple code for various mathematical routines having to do with MOS. If you have access to Maple, you can of course copy and run these programs. Even if you do not, Maple code makes better pseudocode than most languages or computer algebra packages afford, so it can be used as pseudocode. For that purpose, it will be helpful to know that <code>modp(x, n)</code> means reducing ''x'' mod the integer ''n'' to 0, 1, …, {{nowrap|''n'' − 1}} not only when ''x'' is an integer, but also when it is a rational number with denominator prime to ''n''. In that case, {{nowrap|{{frac|''p''|''q''}} (mod ''n'') {{=}} ''r''}} means {{nowrap|''p'' {{=}} ''qr'' (mod ''n'')}}. | Below is some Maple code for various mathematical routines having to do with MOS. If you have access to Maple, you can of course copy and run these programs. Even if you do not, Maple code makes better pseudocode than most languages or computer algebra packages afford, so it can be used as pseudocode. For that purpose, it will be helpful to know that <code>modp(x, n)</code> means reducing ''x'' mod the integer ''n'' to 0, 1, …, {{nowrap|''n'' − 1}} not only when ''x'' is an integer, but also when it is a rational number with denominator prime to ''n''. In that case, {{nowrap|{{frac|''p''|''q''}} (mod ''n'') {{=}} ''r''}} means {{nowrap|''p'' {{=}} ''qr'' (mod ''n'')}}. | ||
Note that some procedures below depend on others. | Note that some procedures below depend on others. Special procedure names (i.e. not built into Maple) are shown in <code>'''bold type'''</code>. | ||
<pre<includeonly />> | <pre<includeonly />> | ||
'''log2''' := proc(x) | '''log2''' := proc(x) | ||
# logarithm base 2 | <nowiki /># logarithm base 2 | ||
evalf(ln(x)/ln(2)) end: | evalf(ln(x)/ln(2)) end: | ||
'''nextfarey''' := proc(q, n) | '''nextfarey''' := proc(q, n) | ||
# next in row n of Farey sequence from q, 0 <= q <= 1 | <nowiki /># next in row n of Farey sequence from q, 0 <= q <= 1 | ||
local a, b, r, s; | local a, b, r, s; | ||
if q >= (n-1)/n then RETURN(1) fi; | if q >= (n-1)/n then RETURN(1) fi; | ||
Line 105: | Line 105: | ||
'''prevfarey''' := proc(q, n) | '''prevfarey''' := proc(q, n) | ||
# previous in row n of Farey sequence from q, 0 <= q <= 1 | <nowiki /># previous in row n of Farey sequence from q, 0 <= q <= 1 | ||
local a, b, r, s; | local a, b, r, s; | ||
if q=0 then RETURN(0) fi; | if q=0 then RETURN(0) fi; | ||
Line 116: | Line 116: | ||
'''fareypair''' := proc(q) | '''fareypair''' := proc(q) | ||
# Farey pair with q as its mediant | <nowiki /># Farey pair with q as its mediant | ||
local n; | local n; | ||
n := denom(q); | n := denom(q); | ||
Line 122: | Line 122: | ||
'''mediant''' := proc(u, v) | '''mediant''' := proc(u, v) | ||
# mediant of two rational numbers u and v | <nowiki /># mediant of two rational numbers u and v | ||
(numer(u) + numer(v))/(denom(u) + denom(v)) end: | (numer(u) + numer(v))/(denom(u) + denom(v)) end: | ||
'''convergents''' := proc(z) | '''convergents''' := proc(z) | ||
# convergent list for z | <nowiki /># convergent list for z | ||
local q; | local q; | ||
convert(z,confrac,'q'); | convert(z,confrac,'q'); | ||
Line 132: | Line 132: | ||
'''exlist''' := proc(l) | '''exlist''' := proc(l) | ||
# expansion of a convergent list to semiconvergents | <nowiki /># expansion of a convergent list to semiconvergents | ||
local i, j, s, d; | local i, j, s, d; | ||
if nops(l)<3 then RETURN(l) fi; | if nops(l)<3 then RETURN(l) fi; | ||
Line 146: | Line 146: | ||
'''semiconvergents''' := proc(z) | '''semiconvergents''' := proc(z) | ||
# semiconvergent list for z | <nowiki /># semiconvergent list for z | ||
'''exlist'''('''convergents'''(z)) end: | '''exlist'''('''convergents'''(z)) end: | ||
'''penult''' := proc(q) | '''penult''' := proc(q) | ||
# penultimate convergent to q | <nowiki /># penultimate convergent to q | ||
local i, u; | local i, u; | ||
u := '''convergents'''(q); | u := '''convergents'''(q); | ||
Line 159: | Line 159: | ||
'''Ls''' := proc(q) | '''Ls''' := proc(q) | ||
# large-small steps from mediant q | <nowiki /># large-small steps from mediant q | ||
local u; | local u; | ||
u := '''fareypair'''(q); | u := '''fareypair'''(q); | ||
Line 165: | Line 165: | ||
'''medi''' := proc(u) | '''medi''' := proc(u) | ||
# mediant from Large-small steps | <nowiki /># mediant from Large-small steps | ||
local q, r; | local q, r; | ||
if u[2]=1 then RETURN(1/(u[1]+1)) fi; | if u[2]=1 then RETURN(1/(u[1]+1)) fi; | ||
Line 175: | Line 175: | ||
'''Lsgen''' := proc(g, n) | '''Lsgen''' := proc(g, n) | ||
# given generator g and scale size n determines large-small steps | <nowiki /># given generator g and scale size n determines large-small steps | ||
local q, u, w; | local q, u, w; | ||
q := round(n*g)/n; | q := round(n*g)/n; | ||
Line 185: | Line 185: | ||
'''revlist''' := proc(l) | '''revlist''' := proc(l) | ||
# reverse of list | <nowiki /># reverse of list | ||
local i, v, e; | local i, v, e; | ||
e := nops(l); | e := nops(l); | ||
Line 193: | Line 193: | ||
'''invcon''' := proc(l) | '''invcon''' := proc(l) | ||
# inverse continued fraction | <nowiki /># inverse continued fraction | ||
local d, i, h, k; | local d, i, h, k; | ||
h[-2] := 0; | h[-2] := 0; | ||
Line 206: | Line 206: | ||
'''quest''' := proc(x) | '''quest''' := proc(x) | ||
# Minkowski ? function | <nowiki /># Minkowski ? function | ||
local i, j, d, l, s, t; | local i, j, d, l, s, t; | ||
l := convert(x, confrac); | l := convert(x, confrac); | ||
Line 220: | Line 220: | ||
'''Box''' := proc(x) | '''Box''' := proc(x) | ||
# inverse ? function | <nowiki /># inverse ? function | ||
local d, e, i, n, w, y; | local d, e, i, n, w, y; | ||
if type(x, integer) then RETURN(x) fi; | if type(x, integer) then RETURN(x) fi; | ||
Line 245: | Line 245: | ||
w := n[nops(n)]; | w := n[nops(n)]; | ||
if type(x, rational) and modp(denom(x), 2)=0 then RETURN(w) fi; | if type(x, rational) and modp(denom(x), 2)=0 then RETURN(w) fi; | ||
evalf(w) end:</pre> | evalf(w) end: | ||
</pre> | |||
== Proofs == | == Proofs == |