|
|
| Line 1: |
Line 1: |
| bit32 = require( 'bit32' ) | | bit32 = require ('bit32') |
| | utils = require ('Module:Utils') |
|
| |
|
| local p = {} | | local p = {} |
|
| |
|
| local PRIME_LIST = {2, 3, 5, 7, 11, 13, 17, 19} | | local PRIME_LIST = {2, 3, 5, 7, 11, 13, 17, 19, 23} |
| | |
| local function get_monzo_list (limit)
| |
| local monzo_list = {}
| |
| if limit >= 3 then
| |
| table.insert (monzo_list, {-1, 1, 0, 0, 0, 0, 0, 0})
| |
| end if limit >= 5 then
| |
| table.insert (monzo_list, {-2, 0, 1, 0, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {0, -1, 1, 0, 0, 0, 0, 0})
| |
| end if limit >= 7 then
| |
| table.insert (monzo_list, {-2, 0, 0, 1, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {-1, -1, 0, 1, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {0, 0, -1, 1, 0, 0, 0, 0})
| |
| end if limit >= 9 then
| |
| table.insert (monzo_list, {-3, 2, 0, 0, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {0, 2, -1, 0, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {0, 2, 0, -1, 0, 0, 0, 0})
| |
| end if limit >= 11 then
| |
| table.insert (monzo_list, {-3, 0, 0, 0, 1, 0, 0, 0})
| |
| table.insert (monzo_list, {-1, -1, 0, 0, 1, 0, 0, 0})
| |
| table.insert (monzo_list, {0, -2, 0, 0, 1, 0, 0, 0})
| |
| table.insert (monzo_list, {-1, 0, -1, 0, 1, 0, 0, 0})
| |
| table.insert (monzo_list, {0, 0, 0, -1, 1, 0, 0, 0})
| |
| end if limit >= 13 then
| |
| table.insert (monzo_list, {-3, 0, 0, 0, 0, 1, 0, 0})
| |
| table.insert (monzo_list, {-2, -1, 0, 0, 0, 1, 0, 0})
| |
| table.insert (monzo_list, {0, -2, 0, 0, 0, 1, 0, 0})
| |
| table.insert (monzo_list, {-1, 0, -1, 0, 0, 1, 0, 0})
| |
| table.insert (monzo_list, {0, 0, 0, -1, 0, 1, 0, 0})
| |
| table.insert (monzo_list, {0, 0, 0, 0, -1, 1, 0, 0})
| |
| end if limit >= 15 then
| |
| table.insert (monzo_list, {-3, 1, 1, 0, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {-1, 1, 1, -1, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {0, 1, 1, 0, -1, 0, 0, 0})
| |
| table.insert (monzo_list, {0, 1, 1, 0, 0, -1, 0, 0})
| |
| end if limit >= 17 then
| |
| table.insert (monzo_list, {-4, 0, 0, 0, 0, 0, 1, 0})
| |
| table.insert (monzo_list, {-2, -1, 0, 0, 0, 0, 1, 0})
| |
| table.insert (monzo_list, {0, -2, 0, 0, 0, 0, 1, 0})
| |
| table.insert (monzo_list, {-1, 0, -1, 0, 0, 0, 1, 0})
| |
| table.insert (monzo_list, {-1, 0, 0, -1, 0, 0, 1, 0})
| |
| table.insert (monzo_list, {0, 0, 0, 0, -1, 0, 1, 0})
| |
| table.insert (monzo_list, {0, 0, 0, 0, 0, -1, 1, 0})
| |
| table.insert (monzo_list, {0, -1, -1, 0, 0, 0, 1, 0})
| |
| end if limit >= 19 then
| |
| table.insert (monzo_list, {-4, 0, 0, 0, 0, 0, 0, 1})
| |
| table.insert (monzo_list, {-2, -1, 0, 0, 0, 0, 0, 1})
| |
| table.insert (monzo_list, {-1, -2, 0, 0, 0, 0, 0, 1})
| |
| table.insert (monzo_list, {-1, 0, -1, 0, 0, 0, 0, 1})
| |
| table.insert (monzo_list, {-1, 0, 0, -1, 0, 0, 0, 1})
| |
| table.insert (monzo_list, {0, 0, 0, 0, -1, 0, 0, 1})
| |
| table.insert (monzo_list, {0, 0, 0, 0, 0, -1, 0, 1})
| |
| table.insert (monzo_list, {0, 0, 0, 0, 0, 0, -1, 1})
| |
| table.insert (monzo_list, {0, -1, -1, 0, 0, 0, 1, 0})
| |
| end if limit >= 21 then
| |
| table.insert (monzo_list, {-4, 1, 0, 1, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {-2, 1, -1, 1, 0, 0, 0, 0})
| |
| table.insert (monzo_list, {0, 1, 0, 1, -1, 0, 0, 0})
| |
| table.insert (monzo_list, {0, 1, 0, 1, 0, -1, 0, 0})
| |
| table.insert (monzo_list, {0, 1, 0, 1, 0, 0, -1, 0})
| |
| table.insert (monzo_list, {0, 1, 0, 1, 0, 0, 0, -1})
| |
| end
| |
| return monzo_list
| |
| end
| |
| | |
| local function round (n)
| |
| return math.floor (n + 0.5)
| |
| end
| |
|
| |
|
| local function is_in (v, t) | | local function is_in (v, t) |
| Line 88: |
Line 22: |
| end | | end |
| return t | | return t |
| | end |
| | |
| | local function gcd (a, b) |
| | if b ~= 0 then |
| | return gcd (b, a % b) |
| | else |
| | return math.abs (a) |
| | end |
| end | | end |
|
| |
|
| Line 109: |
Line 51: |
| end | | end |
| return {num = num, den = den} | | return {num = num, den = den} |
| | end |
| | |
| | local function ratio2monzo (ratio, subgroup) |
| | local monzo = {} |
| | for i = 1, #subgroup do |
| | monzo[i] = 0 |
| | while ratio.num % subgroup[i] == 0 do |
| | monzo[i] = monzo[i] + 1 |
| | ratio.num = ratio.num / subgroup[i] |
| | end while ratio.den % subgroup[i] == 0 do |
| | monzo[i] = monzo[i] - 1 |
| | ratio.den = ratio.den / subgroup[i] |
| | end |
| | end |
| | return monzo |
| end | | end |
|
| |
|
| Line 114: |
Line 71: |
| local jip = {} | | local jip = {} |
| for i = 1, #subgroup do | | for i = 1, #subgroup do |
| jip[i] = 1200*math.log (subgroup[i]) / math.log (2) | | jip[i] = 1200*utils._log (subgroup[i], 2) |
| end | | end |
| return inner_product (jip, monzo) | | return inner_product (jip, monzo) |
| | end |
| | |
| | local function ratio_8ve_reduction (ratio) |
| | local oct = math.floor (utils._log (ratio.num/ratio.den, 2)) |
| | if oct > 0 then |
| | ratio.den = ratio.den * 2^oct |
| | elseif oct < 0 then |
| | ratio.num = ratio.num * 2^(-oct) |
| | end |
| | return ratio |
| | end |
| | |
| | local function odd_limit_monzo_list_gen (limit) |
| | local monzo_list = {} |
| | local subgroup = table_filter (PRIME_LIST, limit) |
| | for num = 1, limit, 2 do |
| | for den = 1, num, 2 do |
| | if gcd (num, den) == 1 then |
| | ratio = ratio_8ve_reduction ({num = num, den = den}) |
| | table.insert (monzo_list, ratio2monzo (ratio, subgroup)) |
| | end |
| | end |
| | end |
| | return monzo_list |
| end | | end |
|
| |
|
| Line 147: |
Line 128: |
| local val = {} | | local val = {} |
| for i = 1, #subgroup do | | for i = 1, #subgroup do |
| val[i] = round (steps*math.log (subgroup[i])/math.log (2)) | | val[i] = utils._round_dec (steps*utils._log (subgroup[i], 2)) |
| end | | end |
| error_list = find_error (val, subgroup, monzo_list) | | error_list = find_error (val, subgroup, monzo_list) |
| Line 189: |
Line 170: |
| end | | end |
| local subgroup = table_filter (PRIME_LIST, limit) | | local subgroup = table_filter (PRIME_LIST, limit) |
| local monzo_list = get_monzo_list (limit) | | local monzo_list = odd_limit_monzo_list_gen (limit) |
|
| |
|
| return approx (steps, subgroup, monzo_list, title) | | return approx (steps, subgroup, monzo_list, title) |