Module:Mediants

From Xenharmonic Wiki
Revision as of 00:17, 11 September 2024 by Ganaram inukshuk (talk | contribs) (Comments, testing)
Jump to navigation Jump to search
Module documentation[view] [edit] [history] [purge]
This module primarily serves as a library for other modules and has no corresponding template.

Module:Mediants is used for finding mediants starting from a set of starting ratios (by default, 1/1 and 1/0), either by search depth, integer limit, or by a custom search function.

Introspection summary for Module:Mediants 
Functions provided (5)
Line Function Params
6 find_mediants_by_depth (start_ratio_1, start_ratio_2, depth)
30 int_limit_filter (ratios, ratio_1, ratio_2, int_limit)
44 num_den_sum_filter (ratios, ratio_1, ratio_2, max_sum)
58 find_mediants_by_filter (start_ratio_1, start_ratio_2, filter, filter_arg)
82 tester none
Lua modules required (1)
Variable Module Functions used
mos Module:MOS new
bright_gen_to_cents

No function descriptions were provided. The Lua code may have further information.


local mos = require("Module:MOS")
local p = {}

-- Module for finding mediants, either by search depth or by search function.

function p.find_mediants_by_depth(start_ratio_1, start_ratio_2, depth)
	local start_ratio_1 = start_ratio_1 or {1, 1}
	local start_ratio_2 = start_ratio_2 or {1, 0}
	local depth = depth or 5
	
	local ratios = { start_ratio_1, start_ratio_2 }
	
	for i = 1, depth do
		local new_ratios = {}
		
		for j = 1, #ratios - 1 do
			local ratio_1 = ratios[j]
			local ratio_2 = ratios[j+1]
			local mediant = { ratio_1[1] + ratio_2[1], ratio_1[2] + ratio_2[2] }
			table.insert(new_ratios, ratio_1)
			table.insert(new_ratios, mediant)
		end
		table.insert(new_ratios, ratios[#ratios])
		
		ratios = new_ratios
	end
	return ratios
end

function p.int_limit_filter(ratios, ratio_1, ratio_2, int_limit)
	local mediant = { ratio_1[1] + ratio_2[1], ratio_1[2] + ratio_2[2] }
	local new_ratio_added = false
	
	local int_max = math.max(mediant[1], mediant[2])

	if int_max <= int_limit then
		new_ratio_added = true
		table.insert(ratios, mediant)
	end
	
	return new_ratio_added
end

function p.num_den_sum_filter(ratios, ratio_1, ratio_2, max_sum)
	local mediant = { ratio_1[1] + ratio_2[1], ratio_1[2] + ratio_2[2] }
	local new_ratio_added = false
	
	local num_den_sum = mediant[1] + mediant[2]

	if num_den_sum <= max_sum then
		new_ratio_added = true
		table.insert(ratios, mediant)
	end
	
	return new_ratio_added
end

function p.find_mediants_by_filter(start_ratio_1, start_ratio_2, filter, filter_arg)
	local start_ratio_1 = start_ratio_1 or {1, 1}
	local start_ratio_2 = start_ratio_2 or {1, 0}
	
	local ratios = { start_ratio_1, start_ratio_2 }
	
	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]
			table.insert(new_ratios, ratio_1)
			new_ratios_added = filter(new_ratios, ratio_1, ratio_2, filter_arg)
		end
		
		table.insert(new_ratios, ratios[#ratios])
		ratios = new_ratios
	end
	return ratios
end

function p.tester()
	local func = p.int_limit_filter
	
	local ratios = p.find_mediants_by_filter({1,1}, {1,0}, func, 15)
	local generators = {}
	for i = 1, #ratios do
		local input_mos = mos.new(5,2)
		local gen = mos.bright_gen_to_cents(input_mos, ratios[i])
		local edo = ratios[i][1] * 5 + ratios[i][2] * 2
		local new_string = string.format("%s:%s\t%sedo\t%.3f", ratios[i][1], ratios[i][2], edo, gen)
		table.insert(generators, new_string)
	end
	
	return generators
end

return p