<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://ja.xen.wiki/index.php?action=history&amp;feed=atom&amp;title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%3AMediants</id>
	<title>モジュール:Mediants - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://ja.xen.wiki/index.php?action=history&amp;feed=atom&amp;title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%3AMediants"/>
	<link rel="alternate" type="text/html" href="https://ja.xen.wiki/index.php?title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB:Mediants&amp;action=history"/>
	<updated>2026-07-09T23:20:22Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://ja.xen.wiki/index.php?title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB:Mediants&amp;diff=1365&amp;oldid=prev</id>
		<title>Furcht968: ページの作成:「-- This module follows User:Ganaram inukshuk/Provisional style guide for Lua local rat   = require(&quot;Module:Rational&quot;) local utils = require(&quot;Module:Utils&quot;)  local p = {}  -- Mediants consists of code used to find a tree of mediants, starting from a -- set of starting ratios (default 1/1 and 1/0). Search can be by int limit, -- depth, or a custom search function. -- Ratios produced this way are a table consisting of the numerator and -- denominator, which allows…」</title>
		<link rel="alternate" type="text/html" href="https://ja.xen.wiki/index.php?title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB:Mediants&amp;diff=1365&amp;oldid=prev"/>
		<updated>2026-04-01T18:30:21Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「-- This module follows &lt;a href=&quot;/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Ganaram_inukshuk/Provisional_style_guide_for_Lua&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;利用者:Ganaram inukshuk/Provisional style guide for Lua (存在しないページ)&quot;&gt;User:Ganaram inukshuk/Provisional style guide for Lua&lt;/a&gt; local rat   = require(&amp;quot;Module:Rational&amp;quot;) local utils = require(&amp;quot;Module:Utils&amp;quot;)  local p = {}  -- Mediants consists of code used to find a tree of mediants, starting from a -- set of starting ratios (default 1/1 and 1/0). Search can be by int limit, -- depth, or a custom search function. -- Ratios produced this way are a table consisting of the numerator and -- denominator, which allows…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- This module follows [[User:Ganaram inukshuk/Provisional style guide for Lua]]&lt;br /&gt;
local rat   = require(&amp;quot;Module:Rational&amp;quot;)&lt;br /&gt;
local utils = require(&amp;quot;Module:Utils&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Mediants consists of code used to find a tree of mediants, starting from a&lt;br /&gt;
-- set of starting ratios (default 1/1 and 1/0). Search can be by int limit,&lt;br /&gt;
-- depth, or a custom search function.&lt;br /&gt;
-- Ratios produced this way are a table consisting of the numerator and&lt;br /&gt;
-- denominator, which allows for non-simplified ratios to be represented.&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
------------------------------ UTILITY FUNCTIONS -------------------------------&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Given a table of depths, return the deepest depth&lt;br /&gt;
function p.deepest_depth(depths)&lt;br /&gt;
	local deepest = nil&lt;br /&gt;
	for _, value in ipairs(depths) do&lt;br /&gt;
		if not deepest or value &amp;gt; deepest then&lt;br /&gt;
			deepest = value&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return deepest&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Given a ratio, return its simplified form.&lt;br /&gt;
function p.simplify_ratio(ratio)&lt;br /&gt;
	local gcd = utils._gcd(ratio[1], ratio[2])&lt;br /&gt;
	return { ratio[1] / gcd, ratio[2] / gcd }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Sort ratios in ascending order. Comparison function is built-in.&lt;br /&gt;
function p.sort_ratios(ratios)&lt;br /&gt;
	table.sort(ratios, function(ratio_1, ratio_2)&lt;br /&gt;
		return ratio_1[1] / ratio_1[2] &amp;lt; ratio_2[1] / ratio_2[2]&lt;br /&gt;
		end&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
----------------------------- CONVERTER FUNCTIONS ------------------------------&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Converts ratios into the form defined by [[Module:Rational]], a table &lt;br /&gt;
-- consisting of its prime factorization.&lt;br /&gt;
&lt;br /&gt;
-- Given a single ratio, as a table of two numbers, convert to rational and&lt;br /&gt;
-- return it.&lt;br /&gt;
function p.to_rational(ratio)&lt;br /&gt;
	return rat.new(ratio[1], ratio[2])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Given a table of ratios, each a table of two numbers, return an array of&lt;br /&gt;
-- ratios in the form as defined by module:Rational.&lt;br /&gt;
function p.to_rationals(ratios)&lt;br /&gt;
	local rats = {}&lt;br /&gt;
	for i = 1, #ratios do&lt;br /&gt;
		table.insert(rats, p.to_rational(ratios[i]))&lt;br /&gt;
	end&lt;br /&gt;
	return rats&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
------------------------------- SEARCH FUNCTIONS -------------------------------&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Search functions determine whether a mediant meets a specific criteria for&lt;br /&gt;
-- being added to a set of mediants, be it based on something about the mediant,&lt;br /&gt;
-- its search depth, the ratios that produced the mediant, or any combination&lt;br /&gt;
-- thereof.&lt;br /&gt;
-- NOTE: some search criteria, such as prime limit, are considered unsuitable,&lt;br /&gt;
-- since mediants not within a prime limit are used to find ratios within a&lt;br /&gt;
-- prime limit, it will likely prevent desired ratios from being found at all.&lt;br /&gt;
-- For this reason, these functions are meant for broad search, and finer&lt;br /&gt;
-- filtering must be done afterwards.&lt;br /&gt;
&lt;br /&gt;
-- A search function has two params: a table containing the mediant and the&lt;br /&gt;
-- depth it was found at, and a search param.&lt;br /&gt;
-- Mediant data is a table that contains the mediant, the search depth it was&lt;br /&gt;
-- found at, and the two ratios that were used to find the mediant.&lt;br /&gt;
-- The search params can be a single numeric value, or a table of values for&lt;br /&gt;
-- finer control.&lt;br /&gt;
&lt;br /&gt;
-- Int limit search determines whether a ratio is within an int limit. Only uses&lt;br /&gt;
-- information about the mediant. Meant for use with searching for JI ratios.&lt;br /&gt;
function p.int_limit_search(mediant_data, int_limit)&lt;br /&gt;
	local mediant = mediant_data[&amp;quot;mediant&amp;quot;]&lt;br /&gt;
	return math.max(mediant[1], mediant[2]) &amp;lt;= int_limit&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Depth search determines whether a ratio is within a target depth. Only uses&lt;br /&gt;
-- the depth it was found at. Meant for use with searching for step ratios.&lt;br /&gt;
function p.depth_search(mediant_data, search_depth)&lt;br /&gt;
	local depth = mediant_data[&amp;quot;depth&amp;quot;]&lt;br /&gt;
	return depth &amp;lt;= search_depth&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
---------------------------- GENERAL SEARCH FUNCTION ---------------------------&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- General search function searches for mediants using a filter function. A&lt;br /&gt;
-- custom filter function can be passed in to &amp;quot;filter&amp;quot; out mediants. Ratios&lt;br /&gt;
-- are added using a while loop, which exits if a loop iteration adds no new&lt;br /&gt;
-- ratios.&lt;br /&gt;
&lt;br /&gt;
-- Find mediants by filter, where the filter function and its args are passed in&lt;br /&gt;
-- as part of the function call.&lt;br /&gt;
function p.find_mediants_by_search_func(init_ratios, search_func, search_args)&lt;br /&gt;
	local init_ratios = init_ratios or {{1,1}, {1,0}}&lt;br /&gt;
	&lt;br /&gt;
	local ratios = {}&lt;br /&gt;
	local depths = {}&lt;br /&gt;
	for i = 1, #init_ratios do&lt;br /&gt;
		table.insert(ratios, init_ratios[i])&lt;br /&gt;
		table.insert(depths, 0)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local new_ratios_added = true&lt;br /&gt;
	while new_ratios_added do&lt;br /&gt;
		new_ratios_added = false&lt;br /&gt;
		local new_ratios = {}&lt;br /&gt;
		local new_depths = {}&lt;br /&gt;
		&lt;br /&gt;
		for i = 1, #ratios-1 do&lt;br /&gt;
			local ratio_1 = ratios[i]&lt;br /&gt;
			local ratio_2 = ratios[i+1]&lt;br /&gt;
			local mediant = { ratio_1[1] + ratio_2[1], ratio_1[2] + ratio_2[2] }&lt;br /&gt;
			table.insert(new_ratios, ratio_1)&lt;br /&gt;
			&lt;br /&gt;
			local depth_1 = depths[i]&lt;br /&gt;
			local depth_2 = depths[i+1]&lt;br /&gt;
			local new_depth = math.max(depth_1, depth_2) + 1&lt;br /&gt;
			table.insert(new_depths, depth_1)&lt;br /&gt;
			&lt;br /&gt;
			local mediant_data = { [&amp;quot;mediant&amp;quot;] = mediant, [&amp;quot;depth&amp;quot;] = new_depth, [&amp;quot;ratio_1&amp;quot;] = ratio_1, [&amp;quot;ratio_2&amp;quot;] = ratio_2 }&lt;br /&gt;
			if search_func(mediant_data, search_args) then&lt;br /&gt;
				table.insert(new_ratios, mediant)&lt;br /&gt;
				table.insert(new_depths, new_depth)&lt;br /&gt;
				new_ratios_added = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(new_ratios, ratios[#ratios])&lt;br /&gt;
		table.insert(new_depths, depths[#depths])&lt;br /&gt;
		&lt;br /&gt;
		ratios = new_ratios&lt;br /&gt;
		depths = new_depths&lt;br /&gt;
	end&lt;br /&gt;
	return ratios, depths&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Find mediants by filter, where the filter function and its args are passed in&lt;br /&gt;
-- as part of the function call. Only returns mediants, not depths.&lt;br /&gt;
function p.find_only_mediants_by_search_func(init_ratios, search_func, search_args)&lt;br /&gt;
	local init_ratios = init_ratios or {{1,1}, {1,0}}&lt;br /&gt;
	&lt;br /&gt;
	local ratios, depths&lt;br /&gt;
	ratios, depths = p.find_mediants_by_search_func(init_ratios, search_func, search_args)&lt;br /&gt;
	return ratios&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
------------------------- DEPTH-BASED SEARCH FUNCTION --------------------------&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Depth-based search finds mediants by building a tree of mediants up to a&lt;br /&gt;
-- specified depth. This is made a standalone function under the reasoning that&lt;br /&gt;
-- it&amp;#039;s a common enough operation.&lt;br /&gt;
&lt;br /&gt;
-- Find mediants by depth of its search tree.&lt;br /&gt;
function p.find_mediants(init_ratios, depth)&lt;br /&gt;
	local init_ratios = init_ratios or {{1,1}, {1,0}}&lt;br /&gt;
	local depth = depth or 5&lt;br /&gt;
&lt;br /&gt;
	local ratios, depths&lt;br /&gt;
	ratios, depths = p.find_mediants_by_search_func(init_ratios, p.depth_search, depth)&lt;br /&gt;
	&lt;br /&gt;
	return ratios, depths&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Find mediants by depth of its search tree. Does not return depths.&lt;br /&gt;
function p.find_only_mediants(init_ratios, depth)&lt;br /&gt;
	local init_ratios = init_ratios or {{1,1}, {1,0}}&lt;br /&gt;
	local depth = depth or 5&lt;br /&gt;
&lt;br /&gt;
	local ratios, depths&lt;br /&gt;
	ratios, depths = p.find_mediants_by_search_func(init_ratios, p.depth_search, depth)&lt;br /&gt;
	&lt;br /&gt;
	return ratios&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
---------------------- INT-LIMIT-BASED SEARCH FUNCTION -------------------------&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Int limit search finds mediants up to an integer limit, not permitting ratios&lt;br /&gt;
-- whose numerator or denominator exceeds the int limit. This is made a stand-&lt;br /&gt;
-- alone function under the reasoning that it&amp;#039;s a common enough operation.&lt;br /&gt;
&lt;br /&gt;
-- Find mediants within an int limit.&lt;br /&gt;
function p.find_mediants_by_int_limit(init_ratios, int_limit)&lt;br /&gt;
	local init_ratios = init_ratios or {{1,1}, {1,0}}&lt;br /&gt;
	local int_limit = int_limit or 50&lt;br /&gt;
	&lt;br /&gt;
	local ratios, depths&lt;br /&gt;
	ratios, depths = p.find_mediants_by_search_func(init_ratios, p.int_limit_search, int_limit)&lt;br /&gt;
	&lt;br /&gt;
	return ratios, depths&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Find mediants within an int limit. Does not return depth.&lt;br /&gt;
function p.find_only_mediants_by_int_limit(init_ratios, int_limit)&lt;br /&gt;
	local init_ratios = init_ratios or {{1,1}, {1,0}}&lt;br /&gt;
	local int_limit = int_limit or 50&lt;br /&gt;
	&lt;br /&gt;
	local ratios, depths&lt;br /&gt;
	ratios, depths = p.find_mediants_by_search_func(init_ratios, p.int_limit_search, int_limit)&lt;br /&gt;
	&lt;br /&gt;
	return ratios&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
----------------------------------- TESTER -------------------------------------&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function p.tester()&lt;br /&gt;
	--return p.find_only_mediants_by_int_limit()&lt;br /&gt;
	local ratios = {{4,3}, {5,1}, {3,2}}&lt;br /&gt;
	p.sort_ratios(ratios)&lt;br /&gt;
	return p.to_rationals(ratios)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Furcht968</name></author>
	</entry>
</feed>