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
| Module:Harmonics in edo is deprecated and has been replaced by Module:Harmonics in equal. Further use of this module is not advised. This module is kept for historical purposes and should not be deleted. |
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;