Module:JI ratios: Difference between revisions
m some bugfixes, new helper function |
Finalized new subgroup-search algorithm; to be implemented into the rest of the module |
||
| Line 164: | Line 164: | ||
-- WORK-IN-PROGRESS!! | -- WORK-IN-PROGRESS!! | ||
function p.search_by_subgroup_new(subgroup, equave, fine_search_args) | function p.search_by_subgroup_new(subgroup, equave, fine_search_args) | ||
local subgroup = {rat.new(2), rat.new(5), rat.new( | local subgroup = {rat.new(2), rat.new(5), rat.new(17,14), rat.new(28,19)} | ||
local equave = rat.new(2,1) | local equave = rat.new(2,1) | ||
local fine_search_args = p.preprocess_fine_search_args(fine_search_args) | local fine_search_args = p.preprocess_fine_search_args(fine_search_args) | ||
-- Fine search params for ease of access | -- Fine search params for ease of access | ||
local int_limit = fine_search_args["Int Limit"] | local int_limit = 200000 --fine_search_args["Int Limit"] | ||
local tenney_height = fine_search_args["Tenney Height"] | local tenney_height = fine_search_args["Tenney Height"] | ||
local comps_only = fine_search_args["Complements Only"] | local comps_only = fine_search_args["Complements Only"] | ||
local products = | -- Search for ratios within int limit within subgroup by multiplication. | ||
local products = p.multiply_ratios_using_bfs(rat.new(1), subgroup, int_limit) | |||
-- | -- Use the products found to find all ratios between 1 and the equave. | ||
-- the int limit. | -- For each ratio found, have it be the denominator and have the numerator | ||
local | -- be all successive ratios after it. For each new ratio found this way, add | ||
-- it to the table of ratios, excluding ratios that exceed the equave or int | |||
local | -- limit, and excluding duplicates. This is way faster than performing BFS | ||
-- on each ratio and yields the same results. | |||
p.merge_ratio_tables_without_duplicates( | local ratios = {} | ||
for i = 1, #products do | |||
local new_ratios = {} | |||
for j = i, #products do | |||
local ratio = rat.div(products[j], products[i]) | |||
if rat.as_float(ratio) > rat.as_float(equave) then break end | |||
if not p.find_ratio_in_table(new_ratios, ratio) and rat.int_limit(ratio) <= int_limit then | |||
table.insert(new_ratios, ratio) | |||
end | |||
end | |||
p.merge_ratio_tables_without_duplicates(ratios, new_ratios) | |||
end | end | ||
-- Use the products found to find all ratios between 1 and the equave | -- Use the products found to find all ratios between 1 and the equave | ||
local | -- Implementation 2; slower!! | ||
--[[local subgroup_inv = {} | |||
for i = 1, #subgroup do | |||
table.insert(subgroup_inv, rat.inv(subgroup[i])) | |||
end | |||
local ratios = {} | |||
for i = 1, #products do | for i = 1, #products do | ||
local new_ratios = p.multiply_ratios_using_bfs(products[i], subgroup_inv, int_limit) | |||
local new_ratios_filtered = {} | |||
end | for j = 1, #new_ratios do | ||
if rat.as_float(new_ratios[j]) <= rat.as_float(equave) and rat.as_float(new_ratios[j]) >= 1 then | |||
table.insert(new_ratios_filtered, new_ratios[j]) | |||
end | |||
end | |||
p.merge_ratio_tables_without_duplicates(ratios, new_ratios_filtered) | |||
end]]-- | |||
-- Sort | |||
table.sort(ratios, rat.lt) | |||
-- Return as a string for testing purposes | -- Return as a string for testing purposes | ||
return p.ratios_as_string( | return p.ratios_as_string(ratios) | ||
end | end | ||
function p. | -- BFS search, implemented as a helper function | ||
local | function p.multiply_ratios_using_bfs(init_ratio, subgroup, int_limit) | ||
local ratios = { init_ratio } | |||
local | local i = 1 | ||
while i <= #ratios do | |||
local new_ratios = p.multiply_ratio_by_subgroup_elements(ratios[i], subgroup, int_limit) | |||
p.merge_ratio_tables_without_duplicates(ratios, new_ratios) | |||
i = i + 1 | |||
end | end | ||
return | table.sort(ratios, rat.lt) | ||
return ratios | |||
end | end | ||
function p. | -- BFS helper function; returns { ratio } X subgroup | ||
local | function p.multiply_ratio_by_subgroup_elements(ratio, subgroup, int_limit) | ||
local ratios = {} | |||
for i = 1, #subgroup do | for i = 1, #subgroup do | ||
local | local new_ratio = rat.mul(ratio, subgroup[i]) | ||
if rat.int_limit( | if rat.int_limit(new_ratio) <= int_limit and not p.find_ratio_in_table(ratios, new_ratio) then | ||
table.insert( | table.insert(ratios, new_ratio) | ||
end | end | ||
end | end | ||
return | return ratios | ||
end | end | ||