Module:JI ratio finder: Difference between revisions
Added NEFTH filtering |
ArrowHead294 (talk | contribs) m Alphabetise dependencies |
||
(6 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
-- | -- local interval = require('Module:Interval') | ||
local rat = require('Module:Rational') | |||
local utils = require('Module:Utils') | |||
-- Finds the Tenney height of a ratio that ignores equave factors. | -- Finds the Tenney height of a ratio that ignores equave factors. | ||
-- If the equave is 2/1, then this is equivalent to no-2's Tenney Height. | -- If the equave is 2/1, then this is equivalent to no-2's Tenney Height. | ||
-- This is an attempt at generalizing no-2's Tenney height for nonoctave | -- This is an attempt at generalizing no-2's Tenney height for nonoctave | ||
-- equaves, such as 3/1 or 3/2. | -- equaves, such as 3/1 or 3/2, which would be no-2's and no-2's-or-3's. | ||
function p.no_equave_factors_tenney_height(ratio, equave) | function p.no_equave_factors_tenney_height(ratio, equave) | ||
local ratio = ratio or rat.new(81, 64) | local ratio = ratio or rat.new(81, 64) | ||
Line 63: | Line 52: | ||
-- Ratios found this way will range from 0 cents to the given cent value. | -- Ratios found this way will range from 0 cents to the given cent value. | ||
-- These ratios should then be filtered as needed. | -- These ratios should then be filtered as needed. | ||
function p. | function p.find_candidate_ratios_within_prime_limit(cents, int_limit, prime_limit) | ||
local cents = cents or 1200 | local cents = cents or 1200 | ||
local | local int_limit = int_limit or 99 | ||
local prime_limit = prime_limit or 97 | local prime_limit = prime_limit or 97 | ||
local candidate_ratios = {} | local candidate_ratios = {} | ||
for i = 1, | for i = 1, int_limit do | ||
for j = i, int_limit do | |||
local numerator = j | |||
local denominator = i | |||
local | |||
local | |||
if | -- Proceed if ratio is simplified | ||
if utils._gcd(numerator, denominator) == 1 then | |||
local current_ratio = rat.new(numerator, denominator) | |||
local is_within_prime_limit = rat.max_prime(current_ratio) <= prime_limit | |||
local is_within_cents = rat.cents(current_ratio) <= cents | |||
if is_within_cents and is_within_prime_limit then | |||
table.insert(candidate_ratios, current_ratio) | |||
end | |||
end | end | ||
end | |||
end | end | ||
Line 94: | Line 82: | ||
-- Finds candidate ratios up to a cent value, up to a denominator limit, and | -- Finds candidate ratios up to a cent value, up to a denominator limit, and | ||
-- | -- with any of the given prime factors | ||
function p.find_candidate_ratios_within_subgroup(cents, int_limit, primes) | |||
function p.find_candidate_ratios_within_subgroup(cents, | |||
local cents = cents or 1200 | local cents = cents or 1200 | ||
local | local int_limit = int_limit or 99 | ||
local | local primes = primes or { 2, 3, 7, 11 } | ||
local candidate_ratios = {} | local candidate_ratios = {} | ||
for i = 1, | for i = 1, int_limit do | ||
for j = i, int_limit do | |||
local numerator = j | |||
local denominator = i | |||
local | |||
local | |||
if | -- Proceed if ratio is simplified | ||
if utils._gcd(numerator, denominator) == 1 then | |||
local current_ratio = rat.new(numerator, denominator) | |||
local is_within_subgroup = p.within_subgroup(current_ratio, primes) | |||
local is_within_cents = rat.cents(current_ratio) <= cents | |||
if is_within_cents and is_within_subgroup then | |||
table.insert(candidate_ratios, current_ratio) | |||
end | |||
end | end | ||
end | |||
end | end | ||
Line 140: | Line 126: | ||
end | end | ||
return filtered_ratios | |||
end | |||
-- Filter ratios based on whether its equave complement exceeds an int limit | |||
function p.filter_ratios_by_equave_complement_int_limit(ratios, int_limit, equave) | |||
local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) } | |||
local int_limit = int_limit or 10 | |||
local equave = equave or rat.new(2) | |||
local filtered_ratios = {} | |||
for i = 1, #ratios do | |||
local complement = p.equave_complement(ratios[i], equave) | |||
local numerator, denominator = rat.as_pair(complement) | |||
if numerator <= int_limit and denominator <= int_limit then | |||
table.insert(filtered_ratios, ratios[i]) | |||
end | |||
end | |||
return filtered_ratios | return filtered_ratios | ||
end | end | ||
Line 199: | Line 202: | ||
function p.filter_ratios_by_subgroup(ratios, subgroup) | function p.filter_ratios_by_subgroup(ratios, subgroup) | ||
local ratios = ratios or { rat.new(1), rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) } | local ratios = ratios or { rat.new(1), rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) } | ||
local subgroup = subgroup or { 2, 3, | local subgroup = subgroup or { 2, 3, 7 } | ||
local candidate_ratios = p.filter_ratios_by_prime_limit(ratios, subgroup[#subgroup]) | local candidate_ratios = p.filter_ratios_by_prime_limit(ratios, subgroup[#subgroup]) | ||
Line 224: | Line 227: | ||
for i = 1, #ratios do | for i = 1, #ratios do | ||
if rat.tenney_height(ratios[i]) <= tenney_height then | if rat.tenney_height(ratios[i]) <= tenney_height then | ||
table.insert(filtered_ratios, ratios[i]) | table.insert(filtered_ratios, ratios[i]) | ||
end | end | ||
Line 253: | Line 236: | ||
-- Filters ratios by no-equave-factors Tenney height | -- Filters ratios by no-equave-factors Tenney height | ||
-- Filters ratios where lg(numerator) + lg(denominator) does not exceed the | -- Filters ratios where lg(numerator) + lg(denominator) does not exceed the | ||
-- given height, where lg is log-base-2 | -- given height, where lg is log-base-2. If the equave is 2/1, this is the same | ||
-- as no-2's tenney height. | |||
-- | -- EG, assuming 2/1 equave, 3/2 and 4/3 have the same tenney height of lg(3). | ||
function p.filter_ratios_by_no_equave_factors_tenney_height(ratios, tenney_height, equave) | function p.filter_ratios_by_no_equave_factors_tenney_height(ratios, tenney_height, equave) | ||
local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) } | local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) } | ||
Line 329: | Line 312: | ||
-- Converts ratios to text, with delimiter | -- Converts ratios to text, with delimiter | ||
-- Default delimiter is a comma followed by a space | -- Default delimiter is a comma followed by a space | ||
function p.ratios_to_text(ratios, delimiter) | function p.ratios_to_text(ratios, delimiter, add_links) | ||
local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) } | local ratios = ratios or { rat.new(5, 4), rat.new(81, 64), rat.new(9, 7) } | ||
local delimiter = delimiter or ", " | local delimiter = delimiter or ", " | ||
local add_links = add_links == true | |||
local text = "" | local text = "" | ||
for i = 1, #ratios do | if add_links then | ||
text = text .. rat.as_ratio(ratios[i]) | for i = 1, #ratios do | ||
text = text .. string.format("[[%s]]", rat.as_ratio(ratios[i])) | |||
if i < #ratios then | |||
text = text .. delimiter | |||
end | |||
end | |||
else | |||
for i = 1, #ratios do | |||
text = text .. rat.as_ratio(ratios[i]) | |||
if i < #ratios then | |||
text = text .. delimiter | |||
end | |||
end | end | ||
end | end |