Module:Harmonics in edo: Difference between revisions
Jump to navigation
Jump to search
consistent "[n]edo" convention |
compute the fifth span for diatonic edos |
||
Line 3: | Line 3: | ||
local function edoprox(edo, odds, title, prec) | local function edoprox(edo, odds, title, prec) | ||
local f = 1/edo | local f = 1/edo | ||
local eps = .0001 | |||
local todd = {'! colspan="2" | Odd harmonic '} | local todd = {'! colspan="2" | Odd harmonic '} | ||
local tapprox = {'! colspan="2" | Approximation '} | local tapprox = {'! colspan="2" | Approximation '} | ||
Line 8: | Line 9: | ||
local trel = {'! [[Relative error|relative]] (%) '} | local trel = {'! [[Relative error|relative]] (%) '} | ||
local tdeg = {'! colspan="2" | Steps ([[octave reduction|reduced]])'} | local tdeg = {'! colspan="2" | Steps ([[octave reduction|reduced]])'} | ||
local tfs = {'! colspan="2" | [[Fifthspan]]'} | |||
local fmt_approx = string.format(' %%.%df', prec) | local fmt_approx = string.format(' %%.%df', prec) | ||
local fmt_abs = string.format(' %%+.%df', prec) | local fmt_abs = string.format(' %%+.%df', prec) | ||
Line 15: | Line 17: | ||
v = s*edo | v = s*edo | ||
ev = math.floor(v + .5) | ev = math.floor(v + .5) | ||
m = math.floor(math.log(3/2)/math.log(2)*edo + .5) | |||
table.insert(todd, ' ' .. p ) | table.insert(todd, ' ' .. p ) | ||
table.insert(tapprox, string.format(fmt_approx, 1200*(ev % edo)/edo) ) | table.insert(tapprox, string.format(fmt_approx, 1200*(ev % edo)/edo) ) | ||
Line 20: | Line 23: | ||
table.insert(trel, string.format(fmt_rel, 100 * (ev - v))) | table.insert(trel, string.format(fmt_rel, 100 * (ev - v))) | ||
table.insert(tdeg, ' ' .. ev .. ' ('.. ev % edo .. ')') | table.insert(tdeg, ' ' .. ev .. ' ('.. ev % edo .. ')') | ||
diatonic_edo = m/edo > 4/7 and m/edo < 3/5 and gcd(m, edo) == 1 | |||
if(diatonic_edo) then -- if the best fifth = m\edo is diatonic AND gcd(m, edo) == 1 | |||
fs = 0 | |||
position = 0 | |||
while position ~= ev do | |||
fs = fs + 1 | |||
position = (position + m) % edo | |||
end | |||
if (fs > edo/2) then | |||
fs = fs - edo | |||
end | |||
table.insert(tfs, ' ' .. fs ) | |||
end | |||
end | end | ||
local titleMarkup = '' | local titleMarkup = '' | ||
Line 26: | Line 42: | ||
end | end | ||
noFifthSpan = '{| class="wikitable center-all"\n' .. | |||
titleMarkup .. | titleMarkup .. | ||
'|-\n' .. | '|-\n' .. | ||
Line 37: | Line 53: | ||
table.concat(tdeg, '\n|') .. '\n' .. | table.concat(tdeg, '\n|') .. '\n' .. | ||
'|}' | '|}' | ||
if (diatonic_edo) then | |||
return noFifthSpan .. | |||
table.concat(tfs, '\n|') .. '\n' .. | |||
'|}' | |||
else | |||
return noFifthspan | |||
end | |||
end | end | ||
local odds = { 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43 } | local odds = { 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43 } | ||
function gcd(a, b) | |||
if (b ~= 0) then | |||
return a | |||
else | |||
return gcd(y, x%y) | |||
end | |||
end | |||
function p.harmonics_in_edo (frame) | function p.harmonics_in_edo (frame) |
Revision as of 03:10, 29 July 2021
![]() |
This page is deprecated. It is being kept for posterity and for reference, but is no longer being actively maintained.
If you have contributions to add to this page, it would be advisable to add them to a different, related page instead. When writing other pages, avoid including links to this page. |
Used in Template:Odd harmonics in edo.
local p = {}
local function edoprox(edo, odds, title, prec)
local f = 1/edo
local eps = .0001
local todd = {'! colspan="2" | Odd harmonic '}
local tapprox = {'! colspan="2" | Approximation '}
local tabs = {'! rowspan="2" | Error \n! absolute ([[cent|¢]]) '}
local trel = {'! [[Relative error|relative]] (%) '}
local tdeg = {'! colspan="2" | Steps ([[octave reduction|reduced]])'}
local tfs = {'! colspan="2" | [[Fifthspan]]'}
local fmt_approx = string.format(' %%.%df', prec)
local fmt_abs = string.format(' %%+.%df', prec)
local fmt_rel = ' %+.0f'
for _, p in pairs(odds) do
s = math.log(p) / math.log(2)
v = s*edo
ev = math.floor(v + .5)
m = math.floor(math.log(3/2)/math.log(2)*edo + .5)
table.insert(todd, ' ' .. p )
table.insert(tapprox, string.format(fmt_approx, 1200*(ev % edo)/edo) )
table.insert(tabs, string.format(fmt_abs, 1200 * (ev - v ) / edo))
table.insert(trel, string.format(fmt_rel, 100 * (ev - v)))
table.insert(tdeg, ' ' .. ev .. ' ('.. ev % edo .. ')')
diatonic_edo = m/edo > 4/7 and m/edo < 3/5 and gcd(m, edo) == 1
if(diatonic_edo) then -- if the best fifth = m\edo is diatonic AND gcd(m, edo) == 1
fs = 0
position = 0
while position ~= ev do
fs = fs + 1
position = (position + m) % edo
end
if (fs > edo/2) then
fs = fs - edo
end
table.insert(tfs, ' ' .. fs )
end
end
local titleMarkup = ''
if title then
titleMarkup = '|-\n|+ ' .. title .. '\n'
end
noFifthSpan = '{| class="wikitable center-all"\n' ..
titleMarkup ..
'|-\n' ..
table.concat(todd, '\n!') .. '\n' ..
'|-\n' ..
table.concat(tabs, '\n|') .. '\n' ..
'|-\n' ..
table.concat(trel, '\n|') .. '\n' ..
'|-\n' ..
table.concat(tdeg, '\n|') .. '\n' ..
'|}'
if (diatonic_edo) then
return noFifthSpan ..
table.concat(tfs, '\n|') .. '\n' ..
'|}'
else
return noFifthspan
end
end
local odds = { 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43 }
function gcd(a, b)
if (b ~= 0) then
return a
else
return gcd(y, x%y)
end
end
function p.harmonics_in_edo (frame)
local edo = frame.args[1] or frame.args['edo'] or 12 -- edo (default=12)
local columns = frame.args['columns'] or 15 -- number of columns (default = 15, harmonics 3 to 31)
local start = frame.args['start'] or 1 -- start column, default: start with harmonic 3
local title = frame.args['title'] or 'Approximation of odd harmonics in ' .. edo .. 'edo'
local prec = frame.args['prec'] or 1 -- for now only variable precision for abs error
return edoprox( edo, {unpack(odds, start, start+columns-1)}, title, prec)
end
return p;