Module:Temperament data: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
CompactStar (talk | contribs)
No edit summary
CompactStar (talk | contribs)
No edit summary
Line 1: Line 1:
local rat = require('Module:Rational')
local rat = require('Module:Rational')
local p = {}
local p = {}
-- Utility / matrix functions
 
local function gcd(a,b)
local function gcd(a,b)
   if type(a) == "number" and type(b) == "number" and  
   if type(a) == "number" and type(b) == "number" and  
Line 66: Line 66:


local function matinv(a)
local function matinv(a)
dbl_identity = {}
local dbl_identity = {}
for i = 1, #a do
for i = 1, #a do
dbl_identity[i] = {}
dbl_identity[i] = {}
Line 78: Line 78:
end
end


xn = scalarmatmul(a, 0.000001)
local xn = scalarmatmul(a, 0.000001)
for i = 1, 30 do
for i = 1, 30 do
Line 96: Line 96:
return result
return result
end
end
local function antitranspose(a)
local result = {}
for i = 1, #a[1] do
result[i] = {}
for j = 1, #a do
result[i][j] = a[#a - j + 1][#a[1] - i + 1]
end
end
return result
end


local function pseudoinv(a)
local function pseudoinv(a)
Line 101: Line 113:
end
end


local function nullspace(mapping)
local identity = {}
for i = 1, #mapping[1] do
identity[i] = {}
for j = 1, #mapping[1] do
if i == j then
identity[i][j] = 1
else
identity[i][j] = 0
end
end
end
-- local w = {{0},{1},{0}}
-- for i = 1, #mapping[1] do
-- w[i] = {10}
-- end


-- Actual temperament-related functions start here
return matsub(identity, matmul(pseudoinv(mapping), mapping))
-- Generator list (e.g. 2/1, 3/2 for meantone) is needed so you can input irregular mappings like {{5,8,12},{7,11,16}} for meantone
end
-- and still have the outputted generators be ~2/1 and ~3/2
-- (this will be important later so people using the template can just input an ET list instead of having to figure out the mapping)
-- Generators are passed as monzos in the specified subgroup here


function p.get_te_generator(subgroup, mapping, gens)
local function mapping_from_basis(comma_basis)
return antitranspose(nullspace(antitranspose(comma_basis)))
end
 
local function get_te_tuning_mpa(subgroup, mapping, preimage)
local w = {}
local w = {}
for i = 1, #subgroup do
for i = 1, #subgroup do
Line 127: Line 157:
local vw = matmul(mapping, w)
local vw = matmul(mapping, w)
local g = matmul(jw, pseudoinv(vw))
local g = matmul(jw, pseudoinv(vw))
local result = {}
local mapping_cols = #mapping[1]
return g
local tempered_subgroup = {}
for i = 1, #subgroup do
tempered_subgroup[i] = 0
for j = 1, #mapping do
tempered_subgroup[i] = tempered_subgroup[i] + g[1][j] * mapping[j][i]
end
end
return tempered_subgroup
end
end






return p
return p

Revision as of 02:21, 8 February 2024

Module documentation[view] [edit] [history] [purge]
This module should not be invoked directly; use its corresponding template instead: Template:Temperament data.
Module:Temperament data is a draft module. It is incomplete and may not be in active development. If possible, editors are encouraged to help with its development. In the meantime, editors should avoid using this module across the Xenharmonic Wiki, except for testing.
Introspection summary for Module:Temperament data 
Functions provided (0)
Line Function Params
Lua modules required (1)
Variable Module Functions used
rat Module:Rational dependency not used

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


local rat = require('Module:Rational')
local p = {}

local function gcd(a,b)
  if type(a) == "number" and type(b) == "number" and 
        a == math.floor(a) and b == math.floor(b) then
    if b == 0 then
      return a
    else
      return gcd(b, a % b) -- tail recursion
    end
  else
    error("Invalid argument to gcd (" .. tostring(a) .. "," .. 
          tostring(b) .. ")", 2)
  end
end


local function matadd(a, b)
	local result = {}
	for i = 1, #a  do
		result[i] = {}
		for j = 1, #(b[1]) do
			result[i][j] = a[i][j] + b[i][j]
		end
	end
	return result
end

local function matsub(a, b)
	local result = {}
	for i = 1, #a  do
		result[i] = {}
		for j = 1, #(b[1]) do
			result[i][j] = a[i][j] - b[i][j]
		end
	end
	return result
end

local function matmul(a, b)
	local result = {}
	for i = 1, #a  do
		result[i] = {}
		for j = 1, #(b[1]) do
			result[i][j] = 0
			for k = 1, #(a[1]) do
				result[i][j] = result[i][j] + (a[i][k] * b[k][j])
			end
		end
	end
	return result
end


local function scalarmatmul(a, b)
	local result = {}
	for i = 1, #a  do
		result[i] = {}
		for j = 1, #(a[1]) do
			result[i][j] = a[i][j] * b
		end
	end
	return result
end

local function matinv(a)
	local dbl_identity = {}
	for i = 1, #a do
		dbl_identity[i] = {}
		for j = 1, #a do
			if i == j then
				dbl_identity[i][j] = 2
			else
				dbl_identity[i][j] = 0
			end
		end
	end

	local xn = scalarmatmul(a, 0.000001)
	
	for i = 1, 30 do
		xn = matmul(xn, matsub(dbl_identity, matmul(a, xn)))
	end
	return xn
end

local function transpose(a)
	local result = {}
	for i = 1, #a[1] do
		result[i] = {}
		for j = 1, #a do
			result[i][j] = a[j][i]
		end
	end
	return result
end

local function antitranspose(a)
	local result = {}
	for i = 1, #a[1] do
		result[i] = {}
		for j = 1, #a do
			result[i][j] = a[#a - j + 1][#a[1] - i + 1]
		end
	end
	return result
end


local function pseudoinv(a)
	return matmul(transpose(a), matinv(matmul(a, transpose(a))))
end

local function nullspace(mapping)
	local identity = {}
	for i = 1, #mapping[1] do
		identity[i] = {}
		for j = 1, #mapping[1] do
			if i == j then
				identity[i][j] = 1
			else
				identity[i][j] = 0
			end
		end
	end

	-- local w = {{0},{1},{0}}
	-- for i = 1, #mapping[1] do
	-- 	w[i] = {10}
	-- end

	return matsub(identity, matmul(pseudoinv(mapping), mapping))
end

local function mapping_from_basis(comma_basis)
	return antitranspose(nullspace(antitranspose(comma_basis)))
end

local function get_te_tuning_mpa(subgroup, mapping, preimage)
	local w = {}
	for i = 1, #subgroup do
		w[i] = {}
		for j = 1, #subgroup do
			if i == j then
				w[i][j] = math.log(2)/math.log(subgroup[i])
			else
				w[i][j] = 0
			end
		end
	end
	
	local jw = {{}}
	for i = 1, #subgroup do
		jw[1][i] = 1
	end
	local vw = matmul(mapping, w)
	local g = matmul(jw, pseudoinv(vw))
	local result = {}
	
	return g
end



return p