Module:JI ratios: Difference between revisions
some bugfixes and testing |
Created new prime-limit search function; some cleanup with int-limit search |
||
| Line 32: | Line 32: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
----------------------------- HELPER FUNCTIONS -------- ------------------------ | ------------------------------ HELPER FUNCTIONS -------------------------------- | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Does not return anything; entries in source are added to destination. | |||
function p.merge_ratio_tables_without_duplicates(dest_table, source_table) | |||
for i = 1, #source_table do | |||
if not p.find_ratio_in_table(dest_table, source_table[i]) then | |||
table.insert(dest_table, source_table[i]) | |||
end | |||
end | |||
end | |||
-- Checks whether a ratio was already in a table | |||
function p.find_ratio_in_table(table_, ratio) | |||
local found = false | |||
for i = 1, #table_ do | |||
if rat.as_float(table_[i]) == rat.as_float(ratio) then | |||
found = true | |||
break | |||
end | |||
end | |||
return found | |||
end | |||
-- Preprocess fine-search args | -- Preprocess fine-search args | ||
| Line 72: | Line 93: | ||
end | end | ||
-- Remove ratios whose complements exceed the int limit | -------------------------------------------------------------------------------- | ||
-- | ------------------------------- FILTER FUNCTIONS ------------------------------- | ||
-- | -------------------------------------------------------------------------------- | ||
function p. | -- Remove ratios whose complements exceed the int limit and Tenney height. | ||
-- If filtering based on Tenney height is not needed, then Tenney height is set | |||
-- to infinity instead, which should be done by the calling function. | |||
function p.filter_ratios_by_complements(ratios, equave, fine_search_args) | |||
if fine_search_args["Complements Only"] then | if fine_search_args["Complements Only"] then | ||
local filtered_ratios = {} | local filtered_ratios = {} | ||
for i = 1, #ratios do | for i = 1, #ratios do | ||
local complement = rat.mul(rat.inv(ratios[i]), equave) | local complement = rat.mul(rat.inv(ratios[i]), equave) | ||
if rat.int_limit(complement) <= fine_search_args["Int Limit"] and rat.tenney_height(complement) <= fine_search_args["Tenney Height"] then | |||
table.insert(filtered_ratios, ratios[i]) | |||
if | end | ||
end | |||
return filtered_ratios | |||
else | |||
return ratios | |||
end | |||
end | |||
-- Remove ratios that exceed the Tenney height. This is skipped if the Tenney | |||
-- height is infinity. | |||
function p.filter_ratios_by_tenney_height(ratios, equave, fine_search_args) | |||
if not fine_search_args["Tenney Height"] == 1/0 then | |||
local filtered_ratios = {} | |||
for i = 1, #ratios do | |||
if rat.tenney_height(ratios[i]) <= fine_search_args["Tenney Height"] then | |||
table.insert(filtered_ratios, ratios[i]) | table.insert(filtered_ratios, ratios[i]) | ||
end | end | ||
| Line 99: | Line 136: | ||
-- Int-limit-based search; finds ratios between 1/1 and an equave, within an int | -- Int-limit-based search; finds ratios between 1/1 and an equave, within an int | ||
-- limit | -- limit. | ||
function p.search_within_equave(equave, fine_search_args) | function p.search_within_equave(equave, fine_search_args) | ||
local equave = equave or rat.new(2,1) -- Defualt equave is 2/1. | local equave = equave or rat.new(2,1) -- Defualt equave is 2/1. | ||
| Line 107: | Line 142: | ||
local init_ratios = {{1,1}, {1,0}} | local init_ratios = {{1,1}, {1,0}} | ||
local | local ratios = med.find_only_mediants_by_int_limit(init_ratios, fine_search_args["Int Limit"]) | ||
-- Convert to ratios that Module:Rational can work with | -- Convert to ratios that Module:Rational can work with | ||
| Line 122: | Line 150: | ||
-- Remove ratios that exceed the equave. | -- Remove ratios that exceed the equave. | ||
-- Note that mediant search | -- Note that mediant search returns sorted ratios, so remove them from the | ||
-- | -- end until there's no more to remove. | ||
while rat.gt(ratios[#ratios], equave) do | while rat.gt(ratios[#ratios], equave) do | ||
table.remove(ratios, #ratios) | table.remove(ratios, #ratios) | ||
end | end | ||
-- Filter out ratios | -- Filter out ratios that exceed the int limit. | ||
ratios = p. | ratios = p.filter_ratios_by_tenney_height(ratios, equave, fine_search_args) | ||
-- Filter out ratios if their equave complement would be filtered out. | |||
ratios = p.filter_ratios_by_complements(ratios, equave, fine_search_args) | |||
return ratios | return ratios | ||
end | end | ||
| Line 161: | Line 168: | ||
---------------- WORK-IN-PROGERSS SUBGROUP-BASED SEARCH FUNCTION --------------- | ---------------- WORK-IN-PROGERSS SUBGROUP-BASED SEARCH FUNCTION --------------- | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
function p.search_by_prime_limit_new(prime_limit, equave, fine_search_args) | |||
local prime_limit = prime_limit or 5 | |||
local equave = equave or rat.new(2,1) | |||
local fine_search_args = p.preprocess_fine_search_args(fine_search_args) | |||
-- Find all primes up to the prime limit. | |||
local primes = {} | |||
for i = 2, prime_limit do | |||
local is_prime = true | |||
for j = 2, math.floor(math.sqrt(i)) do | |||
if i % j == 0 then | |||
is_prime = false | |||
break | |||
end | |||
end | |||
if is_prime then | |||
table.insert(primes, rat.new(i)) | |||
end | |||
end | |||
-- Perform subgroup search on the primes found, as subgroup-search code can | |||
-- be reused for prime-limit search. | |||
return p.search_by_subgroup_new(primes, equave, fine_search_args) | |||
end | |||
-- 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 = subgroup or {rat.new(2), rat.new( | local subgroup = subgroup or {rat.new(2), rat.new(3), rat.new(7)} | ||
local equave = equave or rat.new(2,1) | local equave = equave or 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 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 int_limit = fine_search_args["Int Limit"] | |||
-- Search for ratios within int limit within subgroup by multiplication. | -- Search for ratios within int limit within subgroup by multiplication. | ||
| Line 195: | Line 227: | ||
p.merge_ratio_tables_without_duplicates(ratios, new_ratios) | p.merge_ratio_tables_without_duplicates(ratios, new_ratios) | ||
end | end | ||
-- Sort | -- Sort | ||
| Line 234: | Line 248: | ||
end | end | ||
-- BFS | -- Helper function for BFS search; returns { ratio } X subgroup | ||
function p.multiply_ratio_by_subgroup_elements(ratio, subgroup, int_limit) | function p.multiply_ratio_by_subgroup_elements(ratio, subgroup, int_limit) | ||
local ratios = {} | local ratios = {} | ||
| Line 244: | Line 258: | ||
end | end | ||
return ratios | return ratios | ||
end | end | ||
| Line 281: | Line 274: | ||
function p.search_by_subgroup_within_equave(subgroup, equave, fine_search_args) | function p.search_by_subgroup_within_equave(subgroup, equave, fine_search_args) | ||
local subgroup = subgroup or { 2, 3, 7 } | local subgroup = subgroup or { 2, 3, 7 } | ||
local equave = equave or rat.new(2,1) -- Defualt equave is 2/1 | local equave = equave or rat.new(2,1) -- Defualt equave is 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) | ||
| Line 364: | Line 357: | ||
-- Filter out ratios whose complements exceed the int limit | -- Filter out ratios whose complements exceed the int limit | ||
ratios = p. | ratios = p.filter_ratios_by_complements(ratios, equave, fine_search_args) | ||
return ratios | return ratios | ||
| Line 559: | Line 552: | ||
local equave = rat.new(2,1) | local equave = rat.new(2,1) | ||
local fine_search_args = p.parse_search_args("Subgroup: 2.5.9.21 | local fine_search_args = p.parse_search_args("Subgroup: 2.5.9.21; Complements Only: 1; Tenney Height: 100000000") | ||
local subgroup = { rat.new(2), rat.new(3), rat.new( | local subgroup = {rat.new(2), rat.new(3), rat.new(5), rat.new(7)} | ||
return p.search_by_subgroup_new(subgroup, equave, fine_search_args) | return p.search_by_subgroup_new(subgroup, equave, 50, fine_search_args) | ||
end | end | ||
return p | return p | ||