Module:Harmonic entropy: Difference between revisions
Jump to navigation
Jump to search
Deprecating ET parsing and backslash ratio: those were ET-specific and not interval-specific. Functionality moved into Module:ET |
m harmonic_entropy() implemented |
||
| Line 21: | Line 21: | ||
return u._round(result, prec) | return u._round(result, prec) | ||
end | end | ||
end | |||
-- compute Shannon harmonic entropy for an interval of `c` cents | |||
-- `c`, `deviation`: in cents | |||
-- `ratios`: an array of rational numbers | |||
-- `norm`: a function of rational numbers | |||
function p.harmonic_entropy(c, ratios, deviation, norm) | |||
deviation = deviation or 17 | |||
norm = norm or function(ratio) | |||
return math.sqrt(rat.beneditti_height(ratio)) | |||
end | |||
local function S(x) | |||
return math.exp(-x*x / (2*deviation*deviation)) / (deviation * math.sqrt(2*math.pi)) | |||
end | |||
local function Q(ratio) | |||
return S(rat.cents(ratio) - c) / norm(ratio) | |||
end | |||
local Q_norm = 0 | |||
for i, ratio in ipairs(ratios) do | |||
Q_norm = Q_norm + Q(ratio) | |||
end | |||
local function P(ratio) | |||
return Q(ratio) / Q_norm | |||
end | |||
local entropy = 0 | |||
for i, ratio in ipairs(ratios) do | |||
local P_i = P(ratio) | |||
if P_i > 1e-5 then | |||
entropy = entropy - P_i * math.log(P_i) / math.log(2) | |||
end | |||
end | |||
return entropy | |||
end | end | ||
return p | return p | ||
Revision as of 13:54, 10 October 2022
- This module primarily serves as a library for other modules and has no corresponding template.
This module provides a means to calculate harmonic Shannon entropy of a particular interval.
| Introspection summary for Module:Harmonic entropy | |||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| ||||||||||||||||||||||||||||
local getArgs = require('Module:Arguments').getArgs
local u = require('Module:Utils')
local rat = require('Module:Rational')
local p = {}
-- return measure in cents of an interval ratio, rounded to prec decimal places
function p.to_cents(frame)
local args = getArgs(frame)
return p._to_cents(args[1], args[2])
end
function p._to_cents(ratio, prec)
-- ratio defaults to 1
ratio = u.eval_num_arg(ratio, 1)
-- prec defaults to nil
prec = u.eval_num_arg(prec)
local result = 1200*u._log(ratio), prec
if prec == nil then
return result
else
return u._round(result, prec)
end
end
-- compute Shannon harmonic entropy for an interval of `c` cents
-- `c`, `deviation`: in cents
-- `ratios`: an array of rational numbers
-- `norm`: a function of rational numbers
function p.harmonic_entropy(c, ratios, deviation, norm)
deviation = deviation or 17
norm = norm or function(ratio)
return math.sqrt(rat.beneditti_height(ratio))
end
local function S(x)
return math.exp(-x*x / (2*deviation*deviation)) / (deviation * math.sqrt(2*math.pi))
end
local function Q(ratio)
return S(rat.cents(ratio) - c) / norm(ratio)
end
local Q_norm = 0
for i, ratio in ipairs(ratios) do
Q_norm = Q_norm + Q(ratio)
end
local function P(ratio)
return Q(ratio) / Q_norm
end
local entropy = 0
for i, ratio in ipairs(ratios) do
local P_i = P(ratio)
if P_i > 1e-5 then
entropy = entropy - P_i * math.log(P_i) / math.log(2)
end
end
return entropy
end
return p