Module:Utils

Revision as of 05:45, 5 October 2022 by FloraC (talk | contribs) (Improve the algorithm of sigfig)
Module documentation[view] [edit] [history] [purge]
This module primarily serves as a library for other modules and has no corresponding template.

This module provides several mathematical functions which are likely to be used frequently on the Xenharmonic Wiki.

Namely, the functions in this module can be called from other modules by using require("Module:Utils") and calling the desired functions.

For pairs of functions with names that differ by a single leading underscore (for example, gcd and _gcd), the function with an underscore is meant to be called by other modules, and the function without an underscore can be used with #invoke.


Introspection summary for Module:Utils 
Functions provided (12)
Line Function Params
5 eval_num_arg (input, def_value)
25 log (invokable) (frame)
30 _log (x, b)
39 round_dec (invokable) (frame)
44 _round_dec (x, places)
53 round (invokable) (frame)
58 _round (x, prec)
73 is_prime (n)
90 prime_factorization_raw (n)
110 prime_factorization (invokable) (frame)
115 _prime_factorization (n)
145 signum (x)
Lua modules required (1)
Variable Module Functions used
getArgs Module:Arguments getArgs

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

Functions

trim(s)
Removes leading and trailing whitespaces (but not interior ones) from a string.
_yesno(frame)
Wrapper function for Module: Yesno, for use with templates. (Module: Yesno does not have a corresponding template.)
_clamp(value, min_value, max_value)
Returns value such that it is between min_value and max_value.
table_contains(tbl, value, compare_func) *
Checks whether table tbl contains value and returns true (if found) or false if not found. Passing compare_func is optional; By default, value is a numeric value or a string; to check for other values, such as ratios defined by Module: Rational, a comparison function compare_func must be passed in.
index_of(array, value, compare_func) *
Returns the first index with the given value (or nil if not found). Passing compare_func is optional. By default, value is a numeric value or a string; to check for other values, such as ratios defined by Module:Rational, a comparison function compare_func must be passed in.
value_provided(s) *
Checks whether s is a non-empty string.
eval_num_arg(input, def_value) *
Evaluates input as a number, fraction notation supported but not other expressions; uses def_value on error.
log(x, b)
Returns the logarithm base b of x. Parameter b defaults to base 2 (octave) if it is omitted.
log2(x)
Returns the base-2 logarithm of x.
gcd(a, b)
Returns the greatest common divisor of a and b.
round_dec(x, places)
Returns x rounded to a precision of places decimal places. Parameter places defaults to 0 if it is omitted.
round(x, prec)
Returns x rounded to a precision of prec significant figures. Parameter prec defaults to 6 if it is omitted.
is_prime(n)*
Returns true if the given integer n is a prime number.
prime_factorization(n)
Returns the prime factorization of the given integer n using the exponential form (in wikitext).
prime_factorization_raw(n) *
Returns a table encoding the prime factorization of n.
signum(x) *
Returns 1 for positive numbers, −1 for negative ones, and 0 for zero and non-integer inputs.
next_young_diagram(d)
Returns the next Young diagram of the same size; the first one is [N], the last one is [1, 1, …, 1]. After the last one, nil is returned. The input table is modified.

* These functions are designed to be used by other modules only; they cannot be called with {{#invoke: }}.



local getArgs = require('Module:Arguments').getArgs
local p = {}

-- evaluate input on error use default; cannot be used with {{#invoke:}}
function p.eval_num_arg(input, def_value)
	local result = input
	if type(input) ~= 'number' then
		result = def_value
		if type(input) == 'string' then
			-- check for fraction notation
			if input:match('/') == '/' then
				local denominator = 1
				input, denominator = input:match("^%s*([0-9]+)[/?]([0-9]+)%s*$")
				result = (tonumber(input) or def_value)/(tonumber(denominator) or 1)
			else
				input = input:match("^%s*(.-)%s*$")
				result = tonumber(input)
			end
		end
	end
	return result
end

-- return logarithm base b of x
function p.log(frame)
	local args = getArgs(frame)
	return p._log(args[1], args[2])
end	

function p._log(x, b)
	-- x defaults to 0
	x = p.eval_num_arg(x, 0)
	-- b defaults to 2 ("octave")
	b = p.eval_num_arg(b, 2)
	return math.log(x)/math.log(b)
end

-- return x rounded to places decimal places
function p.round_dec(frame)
	local args = getArgs(frame)
	return p._round_dec(args[1], args[2])
end

function p._round_dec(x, places)
	-- x defaults to 0
	x = p.eval_num_arg(x, 0)
	-- places defaults to 0
	places = p.eval_num_arg(places, 0)
	return math.floor (x * 10^places + 0.5)/10^places
end

-- return x rounded to a precision of prec significant figures
function p.round(frame)
	local args = getArgs(frame)
	return p._round(args[1], args[2])
end	

function p._round(x, prec)
	-- x defaults to 0
	x = p.eval_num_arg(x, 0)
	-- prec defaults to 6
	prec = p.eval_num_arg(prec, 6)
	return p._round_dec(x, prec - math.floor (p._log (math.abs (x), 10)) - 1)
end

-- cached list of primes for is_prime
local primes = {
	[0] = false,
	[1] = false
}

-- returns true if integer n is prime; cannot be used with {{#invoke:}}
function p.is_prime(n)
	local cached = primes[n]
	if cached ~= nil then
		return cached
	end
	for i = 2, math.sqrt(n) do
		if n % i == 0 then
			primes[n] = false
			return false
		end
	end
	primes[n] = true
	return true 
end

-- returns prime factorization of integer n > 1; cannot be used with {{#invoke:}}
-- note: the order of keys is not specified for Lua tables
function p.prime_factorization_raw(n)
	local factors = {}
	local m = n
	for i = 2, math.sqrt(n) + 1 do
		while m % i == 0 do
			factors[i] = factors[i] or 0
			factors[i] = factors[i] + 1
			m = m / i
		end
		if m == 1 then
			break
		end
	end
	if m > 1 then
		factors[m] = factors[m] or 1
	end
	return factors
end

-- returns prime factorization of integer n > 2 (with wiki markup for exponents)
function p.prime_factorization(frame)
	local args = getArgs(frame)
	return p._prime_factorization(args[1])
end

function p._prime_factorization(n)
	if n <= 1 then
		return tostring(n)
	end
	local factors, powers = {}, {}
	local new_number = p.eval_num_arg(n, 12)
	for i = 2, n do
		if p.is_prime(i) then
			if new_number % i == 0 then
				factors[#factors + 1] = i
				powers[#factors] = 0
				while new_number % i == 0 do 
					powers[#factors] = powers[#factors] + 1
					new_number = new_number / i
				end
				if powers[#factors] > 1 then
					powers[#factors] = factors[#factors] .. "<sup>" .. powers[#factors] .. "</sup>"
				else
					powers[#factors] = factors[#factors]
				end
			end
		end
		if new_number == 1 then
			break
		end
	end
	return table.concat(powers, " × ")
end

-- returns signum(x); cannot be used with {{#invoke:}}
function p.signum(x)
	if type(x) ~= 'number' then
		return 0
	end
	if x > 0 then return 1 end
	if x < 0 then return -1 end
	return 0
end

return p