Module:Rational: Difference between revisions
mNo edit summary |
mNo edit summary |
||
Line 658: | Line 658: | ||
end | end | ||
return max_factor | return max_factor | ||
end | |||
-- compute log2 of a rational number | |||
function p.log(a, base) | |||
base = base or 2 | |||
if type(a) == 'number' then | |||
a = p.new(a) | |||
end | |||
if a.inf and a.sign > 0 then | |||
return 1/0 | |||
end | |||
if a.nan or a.inf then | |||
return nil | |||
end | |||
if a.zero then | |||
return -1/0 | |||
end | |||
if a.sign < 0 then | |||
return nil | |||
end | |||
local logarithm = 0 | |||
for factor, power in pairs(a) do | |||
if type(factor) == 'number' then | |||
logarithm = logarithm + power * math.log(factor) / math.log(base) | |||
end | |||
end | |||
return logarithm | |||
end | end | ||
Line 669: | Line 696: | ||
end | end | ||
local b = p.copy(a) | local b = p.copy(a) | ||
-- start with an approximation | |||
local log2 = p.log(b) | |||
b = p.div(b, p.pow(2, math.floor(log2))) | |||
while p.lt(b, 1) do | while p.lt(b, 1) do | ||
b = p.mul(b, 2) | b = p.mul(b, 2) | ||
Line 742: | Line 774: | ||
table.sort(utonal) | table.sort(utonal) | ||
local fifths = b[3] or 0 | local fifths = b[3] or 0 | ||
mw.log(p.as_ratio(b)) | |||
mw.log('fifths=' .. fifths) | |||
local red3 = red(p.pow(3, fifths)) | |||
mw.log('dividing by ' .. p.as_ratio(red3)) | |||
b = p.div(b, red3) | |||
local octaves = b[2] or 0 | |||
mw.log('octaves=' .. octaves) | |||
if math.abs(fifths) >= 12 and math.abs(fifths) % 7 == 5 then | |||
-- still wrong results with 4096/2187: d1 instead of d8 | |||
octaves = octaves - u.signum(fifths) | |||
mw.log('octaves=' .. octaves) | |||
end | |||
-- a terrible hack, I have no idea how/why this is supposed to work | -- a terrible hack, I have no idea how/why this is supposed to work | ||
local octaves = (b[2] or 0) + fifths + 4 * math.floor(fifths / 7) + math.floor((fifths % 7) / 2) | -- local octaves = (b[2] or 0) + fifths + 4 * math.floor(fifths / 7) + math.floor((fifths % 7) / 2) | ||
local noshift = {1, 5, 2, 6, 3, 7, 4} | local noshift = {1, 5, 2, 6, 3, 7, 4} | ||
local num = noshift[1 + (fifths % 7)] + octaves * 7 | local num = noshift[1 + (fifths % 7)] + octaves * 7 | ||
if octaves < 0 then | if octaves < 0 then | ||
mw.log('octaves < 0, inverting') | |||
fifths = -fifths | fifths = -fifths | ||
-- wrong results on 3^53/2^84, which should be AAAAAAA3 but is computed as ddddddd-6 | -- wrong results on 3^53/2^84, which should be AAAAAAA3 but is computed as ddddddd-6 | ||
octaves = -(b[2] or 0) + fifths + 4 * math.floor(fifths / 7) + math.floor((fifths % 7) / 2) | -- octaves = -(b[2] or 0) + fifths + 4 * math.floor(fifths / 7) + math.floor((fifths % 7) / 2) | ||
num = -noshift[1 + (fifths % 7)] - octaves * 7 | -- num = -noshift[1 + (fifths % 7)] - octaves * 7 | ||
if fifths ~= 0 then | |||
num = num - 2 | |||
else | |||
num = num + 5 | |||
end | |||
end | end | ||
Line 786: | Line 832: | ||
FJS = FJS .. '_{' .. table.concat(utonal, ',') .. '}' | FJS = FJS .. '_{' .. table.concat(utonal, ',') .. '}' | ||
end | end | ||
return FJS | return FJS | ||
end | end |