Module:JI ratios: Difference between revisions

Ganaram inukshuk (talk | contribs)
No edit summary
Ganaram inukshuk (talk | contribs)
Decided that initial search by int limit may be a bit more intuitive
Line 13: Line 13:
-- 400 -> ~24000 ratios
-- 400 -> ~24000 ratios
-- 300 -> ~14000 ratios
-- 300 -> ~14000 ratios
-- 250 -> ~9500 ratios
-- 200 -> ~6000 ratios
-- 200 -> ~6000 ratios
-- 150 -> ~3400 ratios
-- 150 -> ~3400 ratios
-- 128 -> ~2500 ratios
-- 128 -> ~2500 ratios
-- 100 -> ~1500 ratios
-- 100 -> ~1500 ratios
local INT_LIMIT_MAX = 150
local INT_LIMIT_MAX = 200
local DEFAULT_INT_LIMIT = 50
local DEFAULT_INT_LIMIT = 50
-- TENNEY_HEIGHT_MAX is hardcoded to limit size of output.
local TENNEY_HEIGHT_MAX = 16
local DEFAULT_TENNEY_HEIGHT = 10


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Line 53: Line 50:
table.insert(new_ratios, ratios[i])
table.insert(new_ratios, ratios[i])
if INT_LIMIT_MAX <= integer_limit then
if INT_LIMIT_MAX <= integer_limit then
new_ratios_added = true
table.insert(new_ratios, mediant)
end
end
table.insert(new_ratios, ratios[#ratios])
ratios = new_ratios
end
-- If the max cents is greater than the octave, duplicate all existing
-- ratios and raise them by the required number of octaves.
if max_cents > 1200 then
local new_ratios = {}
local num_octaves_up = math.ceil(max_cents / 1200)
for j = 1, num_octaves_up do
for i = 2, #ratios do
local num = ratios[i][1] * math.pow(2, j)
local den = ratios[i][2]
local gcd = utils._gcd(num, den)
num = num / gcd
den = den / gcd
if math.max(num, den) <= integer_limit then
table.insert(new_ratios, {num, den})
end
end
end
for i = 1, #new_ratios do
table.insert(ratios, new_ratios[i])
end
end
-- Remove any ratios that exceed the max cents
-- Convert to ratios that Module:Rational can work with
for i = 1, #ratios do
ratios[i] = rat.new(ratios[i][1], ratios[i][2])
end
return ratios
end
-- Find JI ratios up to a max Tenney height within the octave by finding mediants.
-- A cent value can be passed in to either exclude ratios that are above an
-- interval below the octave or include ratios above the octave.
function p.search_by_tenney_height(tenney_height, max_cents)
local max_cents = max_cents or 1200
local tenney_height = tenney_height or DEFAULT_TENNEY_HEIGHT
tenney_height = math.max(0, math.min(TENNEY_HEIGHT_MAX, tenney_height))
local ratios = {{1,1}, {2,1}}
-- Find ratios by finding the mediants between existing ratios, only adding
-- those that do not exceed the integer limit.
local new_ratios_added = true
while new_ratios_added do
new_ratios_added = false
local new_ratios = {}
for i = 1, #ratios-1 do
local ratio_1 = ratios[i]
local ratio_2 = ratios[i+1]
local mediant = {ratio_1[1]+ratio_2[1], ratio_1[2]+ratio_2[2]}
local curr_height = utils.log2(mediant[1]*mediant[2])
table.insert(new_ratios, ratios[i])
if curr_height <= tenney_height then
new_ratios_added = true
new_ratios_added = true
table.insert(new_ratios, mediant)
table.insert(new_ratios, mediant)
Line 190: Line 118:
local parsed = tip.parse_kv_pairs(search_params)
local parsed = tip.parse_kv_pairs(search_params)
if parsed["Tenney Height"] ~= nil then
if parsed["Int Limit"] ~= nil then
parsed["Tenney Height"] = tonumber(parsed["Tenney Height"])
parsed["Int Limit"] = tonumber(parsed["Int Limit"])
end
end
Line 211: Line 139:
-- Filter ratios by Tenney height.
-- Filter ratios by Tenney height.
function p.filter_by_tenney_height(ratios, tenney_height)
function p.filter_by_tenney_height(ratios, tenney_height)
local tenney_height = tenney_height or 8
local tenney_height = tenney_height or 10
local filtered_ratios = {}
local filtered_ratios = {}
Line 320: Line 248:
--return p.ratios_as_texts(ratios)
--return p.ratios_as_texts(ratios)
local ratios = p.search_by_tenney_height(15)
local ratios = p.search_by_int_limit(250)
--local ratios = p.search_by_int_limit(150)
return p.ratios_as_text(ratios) .. " " .. #ratios
return #ratios
end
end


return p
return p