模組:Complex Number/Solver
此模块被引用於約12,000個頁面。 為了避免造成大規模的影響,所有對此模块的編輯應先於沙盒或測試樣例上測試。 測試後無誤的版本可以一次性地加入此模块中,但是修改前請務必於討論頁發起討論。 模板引用數量會自動更新。 |
本模組主要為方程式求解器,基於Module:Complex_Number同時也附屬於Module:Complex_Number之下。同時也提供Module:Complex_Number系列模組的部分共用函數。
方程式求解器
- p._solveEQ(a,b,c,...)
- 求解方程式(四次或以下)。傳入方程式的係數返回方程式的根。
- p._cubicRootItem(a,b,c,d,it)
- 三次方程公式解,a,b,c,d為係數、it為第幾個根。
- p._cubicRoot(a,b,c,d)
- 求解三次方程,a,b,c,d為係數。
- p._quarticRootItem(a,b,c,d,e,it)
- 四次方程公式解,a,b,c,d,e為係數、it為第幾個根。
- p._quarticRoot(a,b,c,d,e)
- 求解四次方程,a,b,c,d,e為係數。
- p._quarticEigenRoot(a)
- 4維矩陣特徵多項式公式解。
- p._quarticEigenData(a)
- 求4維矩陣特徵多項式的所有根。
共用函數
- p.getNumber
- 將輸入物件轉換為符合Module:Complex_Number格式的數字,若轉換失敗則為nan。
- p._numberType
- 判斷輸入數字的數字種類,可能是real、complex等Module:Complex_Number定義的種類,若都不是,返回nan。
- p._trunc(x,n)
- 截尾函數的公用定義,用於Module:Complex_Number系列模組。
- p._random(a,b)
- 帶有處理參數為零例外狀況的math.random(亂數發生器)替代之公用定義,用於Module:Complex_Number系列模組。
- p._isNaN(x)
- 判斷一數是否為nan。
可模板呼叫
本節列出可用{{#invoke:}}
調用的函數
- getNumber
- 將輸入參數轉換為符合Module:Complex_Number格式的數字,若轉換失敗則為nan。
- 1號參數:要轉換的數字
- numberType
- 判斷輸入參數所代表之數字的數字種類,可能是real、complex等Module:Complex_Number定義的種類,若都不是,返回nan。
- 1號參數:要判斷的數字
- trunc
- 將輸入參數套用截尾函數。
- 1號參數:要套用截尾函數的數字
- random
- 帶有處理參數為零例外狀況的math.random(亂數發生器)替代函數的invoke版本。參數留空視為未輸入。
- 1號參數:對應math.random(a,b)的a
- 2號參數:對應math.random(a,b)的b
- solveEQ
- 求解方程式(四次或以下)。
- 1、2、3...號參數:多項式係數。
- root參數:要求解第幾個根,若未輸入,則輸出所有根。
- comma參數:輸出多個根時的分隔符號,預設值為半角逗點「
,
」。
- get4x4matrix
- 讀取一個4維方陣,失敗則返回空字串
- 1號參數:要讀取的字串
local p = {}
local getArgs = {}
local comp_lib = {}
local matrix_lib = {}
local cmath = {}
local mmath = {}
local toCnumber = tonumber
local yesno = {}
local function load_comp_lib()
if comp_lib.cmath == nil then
comp_lib = require("Module:Complex_Number")
cmath = comp_lib.cmath.init()
toCnumber = cmath.constructor
end
end
local function load_matrix_lib()
if matrix_lib.mmath == nil then
matrix_lib = require("Module:Complex Number/Matrix")
mmath = matrix_lib.mmath.init()
end
end
local function load_getArgs()
if type(getArgs) ~= type(tonumber) then
getArgs = require('Module:Arguments').getArgs
end
end
function p._trunc(x,n)
local _10_n = math.pow(10,n)
local _10_n_x = _10_n * x
return (x >= 0)and(math.floor(_10_n_x) / _10_n)or(math.ceil(_10_n_x) / _10_n)
end
function p._random(_a, _b)
local a, b = tonumber(_a), tonumber(_b)
if type(_a)==type(nil) and type(_b)==type(nil) then return math.random() end
local str_a = tostring(_a):lower()
local str_b = tostring(_b):lower()
if str_a == "nan" or str_a == "-nan" or
str_b == "nan" or str_b == "-nan" then
return math.random()
end
if type(_b)==type(nil) then
local sign = a < 0 and -1 or 1
if math.abs(a) < 1 then return 0 end
if math.abs(a) >= 1 and math.abs(a) < 2 then return sign * math.random(0,1) end
return sign * math.random(math.abs(a))
end
if math.abs(a - b) < 1 then return a end
return math.random(math.min(a, b), math.max(a, b))
end
function p._numberType(input_num)
if type(input_num) == type(0) then
return "real"
elseif type(input_num) == type({}) then
return input_num.numberType or "nan"
else
return "nan"
end
end
function p._isNaN(x)
return (not (x==x)) and (x~=x)
end
function p._solveEQ(...)
load_comp_lib()
local coeffs = {...}
local a = {}
local zero = toCnumber("0")
local find_leadership = false
for i=1,#coeffs do
local coeff = toCnumber(tostring(coeffs[i]))
if not find_leadership then
if coeff ~= zero then
find_leadership = true
a[#a+1] = coeff
end
else a[#a+1] = coeff end
end
local sol = {}
if #a <= 1 then sol = {}
elseif #a == 2 then sol = {-a[2]/a[1]}
elseif #a == 3 then sol = {
(-a[2] - cmath.sqrt(a[2]*a[2] - 4*a[1]*a[3]))/(2*a[1]),
(-a[2] + cmath.sqrt(a[2]*a[2] - 4*a[1]*a[3]))/(2*a[1])
} elseif #a == 4 then sol = p._cubicRoot(a[1],a[2],a[3],a[4])
elseif #a == 5 then sol = p._quarticRoot(a[1],a[2],a[3],a[4],a[5])
else error("in solveEQ(): Not Implemented Exception : Solving "..tostring((#a)-1).."th-ptic equation not support.") end
local real_id = 1
if #sol > 0 then for i=1,#sol do
local re_scale = cmath.re(cmath.abs(cmath.re(sol[i])))
local im_scale = cmath.re(cmath.abs(cmath.im(sol[i])))
if re_scale < 1e-14 and im_scale < 1e-14 then
real_id = i
if re_scale > 0 or im_scale > 0 then sol[i] = 0 end
elseif im_scale < 1e-14 then
real_id = i
if im_scale > 0 then sol[i] = cmath.re(sol[i]) end
elseif re_scale < 1e-14 then
if re_scale > 0 then sol[i] = toCnumber(tostring(cmath.im(sol[i]))+"i") end
end
end end
local result = {}
local j = real_id
for i=1,#sol do
result[#result+1] = sol[((real_id-1)+(i-1))%(#sol)+1]
end
return result
end
function p._cubicRootItem(a,b,c,d,it)
load_comp_lib()
local alpha = (-b*b*b/(27*a*a*a)-d/(2*a)+(b*c)/(6*a*a))
local beta = (c/(3*a))-(b*b)/(9*a*a)
local st = {2*cmath.pi, cmath.zero, -2*cmath.pi}
local s = st[tonumber(tostring(it))or 1]
return -b/(3*a)+2*cmath.sqrt(-beta)*cmath.cos((cmath.acos(alpha/cmath.pow(-beta,3/2))+s)/3)
end
function p._cubicRoot(a,b,c,d)
load_comp_lib()
return {
p._cubicRootItem(a,b,c,d,1),
p._cubicRootItem(a,b,c,d,2),
p._cubicRootItem(a,b,c,d,3),
}
end
function p._quarticRootItem(a,b,c,d,e,it)
load_comp_lib()
local st = {{-1,-1},{-1,1},{1,-1},{1,1}}
local s, t = unpack(st[tonumber(tostring(it))or 1]or{1,1})
local alpha = -3*b*b/(8*a*a)+c/a
local beta = b*b*b/(8*a*a*a)-b*c/(2*a*a)+d/a
local gamma = -3*b*b*b*b/(256*a*a*a*a)+b*b*c/(16*a*a*a)-b*d/(4*a*a)+e/a
if (beta == 0) or (toCnumber(beta)==cmath.zero) then return -b/(4*a)+s*cmath.sqrt((-alpha+t*cmath.sqrt(alpha*alpha-4*gamma))/2)end
local one_3th = cmath.one / 3.0
local P = -alpha*alpha/12-gamma
local Q = -alpha*alpha*alpha/108+alpha*gamma/3-beta*beta/8
local R = -Q/2+cmath.sqrt(Q*Q/4+P*P*P/27)
local U = cmath.pow(R,one_3th)
local y = -(5/6)*alpha + (((U==0) or (toCnumber(U)==cmath.zero))and(-cmath.pow(Q,one_3th))or(U-P/(3*U)))
local W = cmath.sqrt(alpha+2*y)
return -b/(4*a)+(s*W+t*cmath.sqrt(-(3*alpha+2*y+s*((2*beta)/W))))/2
end
function p._quarticRoot(a,b,c,d,e)
load_comp_lib()
return {
p._quarticRootItem(a,b,c,d,e,1),
p._quarticRootItem(a,b,c,d,e,2),
p._quarticRootItem(a,b,c,d,e,3),
p._quarticRootItem(a,b,c,d,e,4),
}
end
--[[
p._quarticEigenRoot({{1, 2, 4, 3}, {5, 7, 6, 8}, {10, 9, 12, 11}, {13, 16, 14, 15}})
p._quarticEigenData({{1, 2, 4, 3}, {5, 7, 6, 8}, {10, 9, 12, 11}, {13, 16, 14, 15}})
{35.4422, 2.72101, -2.05098, -1.11227}
{{0.199913, 0.471587, 0.73557, 1.}, {-0.665669, 1.20938, -1.64109, 1.},
{-0.79522, -0.522759, 0.117929, 1.}, {0.230581, -0.767239, -0.488143, 1.}}
]]
function p._quarticEigenRoot(a)
local e4=1
local e3=-a[1][1] - a[2][2] - a[3][3] - a[4][4]
local e2=-a[1][2]*a[2][1] + a[1][1]*a[2][2] - a[1][3]*a[3][1] - a[2][3]*a[3][2] + a[1][1]*a[3][3] + a[2][2]*a[3][3] - a[1][4]*a[4][1] - a[2][4]*a[4][2] - a[3][4]*a[4][3] + a[1][1]*a[4][4] + a[2][2]*a[4][4] + a[3][3]*a[4][4]
local e1=a[1][3]*a[2][2]*a[3][1] - a[1][2]*a[2][3]*a[3][1] - a[1][3]*a[2][1]*a[3][2] + a[1][1]*a[2][3]*a[3][2] + a[1][2]*a[2][1]*a[3][3] - a[1][1]*a[2][2]*a[3][3] + a[1][4]*a[2][2]*a[4][1] - a[1][2]*a[2][4]*a[4][1] + a[1][4]*a[3][3]*a[4][1] -
a[1][3]*a[3][4]*a[4][1] - a[1][4]*a[2][1]*a[4][2] + a[1][1]*a[2][4]*a[4][2] + a[2][4]*a[3][3]*a[4][2] - a[2][3]*a[3][4]*a[4][2] - a[1][4]*a[3][1]*a[4][3] - a[2][4]*a[3][2]*a[4][3] + a[1][1]*a[3][4]*a[4][3] + a[2][2]*a[3][4]*a[4][3] +
a[1][2]*a[2][1]*a[4][4] - a[1][1]*a[2][2]*a[4][4] + a[1][3]*a[3][1]*a[4][4] + a[2][3]*a[3][2]*a[4][4] - a[1][1]*a[3][3]*a[4][4] - a[2][2]*a[3][3]*a[4][4]
local e0=a[1][4]*a[2][3]*a[3][2]*a[4][1] - a[1][3]*a[2][4]*a[3][2]*a[4][1] - a[1][4]*a[2][2]*a[3][3]*a[4][1] + a[1][2]*a[2][4]*a[3][3]*a[4][1] + a[1][3]*a[2][2]*a[3][4]*a[4][1] - a[1][2]*a[2][3]*a[3][4]*a[4][1] - a[1][4]*a[2][3]*a[3][1]*a[4][2] +
a[1][3]*a[2][4]*a[3][1]*a[4][2] + a[1][4]*a[2][1]*a[3][3]*a[4][2] - a[1][1]*a[2][4]*a[3][3]*a[4][2] - a[1][3]*a[2][1]*a[3][4]*a[4][2] + a[1][1]*a[2][3]*a[3][4]*a[4][2] + a[1][4]*a[2][2]*a[3][1]*a[4][3] - a[1][2]*a[2][4]*a[3][1]*a[4][3] -
a[1][4]*a[2][1]*a[3][2]*a[4][3] + a[1][1]*a[2][4]*a[3][2]*a[4][3] + a[1][2]*a[2][1]*a[3][4]*a[4][3] - a[1][1]*a[2][2]*a[3][4]*a[4][3] - a[1][3]*a[2][2]*a[3][1]*a[4][4] + a[1][2]*a[2][3]*a[3][1]*a[4][4] + a[1][3]*a[2][1]*a[3][2]*a[4][4] -
a[1][1]*a[2][3]*a[3][2]*a[4][4] - a[1][2]*a[2][1]*a[3][3]*a[4][4] + a[1][1]*a[2][2]*a[3][3]*a[4][4]
return p._quarticRoot(e4,e3,e2,e1,e0)
end
function p._quarticEigenData(a)
local qbRoot = p._quarticEigenRoot(a)
local at01 = a[2][3]*a[3][2]*a[4][1] - a[2][2]*a[3][3]*a[4][1] - a[2][3]*a[3][1]*a[4][2] + a[2][1]*a[3][3]*a[4][2] + a[2][2]*a[3][1]*a[4][3] - a[2][1]*a[3][2]*a[4][3]
local at02 = a[2][4]*a[3][2]*a[4][1] - a[2][2]*a[3][4]*a[4][1] - a[2][4]*a[3][1]*a[4][2] + a[2][1]*a[3][4]*a[4][2] + a[2][2]*a[3][1]*a[4][4] - a[2][1]*a[3][2]*a[4][4]
local at03 = -a[2][4]*a[3][3]*a[4][1] + a[2][3]*a[3][4]*a[4][1] + a[2][4]*a[3][1]*a[4][3] - a[2][1]*a[3][4]*a[4][3] - a[2][3]*a[3][1]*a[4][4] + a[2][1]*a[3][3]*a[4][4]
local at04 = -a[3][3]*a[4][2] + a[3][2]*a[4][3]
local at05 = -a[3][4]*a[4][2] + a[3][2]*a[4][4]
return {{-(1/(a[3][2]*a[4][1] - a[3][1]*a[4][2]))*(at05 - a[3][2]*qbRoot[1]) + ((at04 + a[4][2]*qbRoot[1])*(at02 - a[2][2]*a[3][1]*qbRoot[1] + a[2][1]*a[3][2]*qbRoot[1] + a[3][4]*a[4][1]*qbRoot[1] - a[3][1]*a[4][4]*qbRoot[1] +
a[3][1]*(qbRoot[1]*qbRoot[1])))/((a[3][2]*a[4][1] - a[3][1]*a[4][2])*(at01 + a[2][2]*a[4][1]*qbRoot[1] + a[3][3]*a[4][1]*qbRoot[1] - a[2][1]*a[4][2]*qbRoot[1] - a[3][1]*a[4][3]*qbRoot[1] -
a[4][1]*(qbRoot[1]*qbRoot[1]))), -((at03 + a[2][3]*a[3][1]*qbRoot[1] - a[2][1]*a[3][3]*qbRoot[1] + a[2][4]*a[4][1]*qbRoot[1] - a[2][1]*a[4][4]*qbRoot[1] + a[2][1]*(qbRoot[1]*qbRoot[1]))/(at01 + a[2][2]*a[4][1]*qbRoot[1] +
a[3][3]*a[4][1]*qbRoot[1] - a[2][1]*a[4][2]*qbRoot[1] - a[3][1]*a[4][3]*qbRoot[1] - a[4][1]*(qbRoot[1]*qbRoot[1]))), -((at02 - a[2][2]*a[3][1]*qbRoot[1] + a[2][1]*a[3][2]*qbRoot[1] + a[3][4]*a[4][1]*qbRoot[1] -
a[3][1]*a[4][4]*qbRoot[1] + a[3][1]*(qbRoot[1]*qbRoot[1]))/(at01 + a[2][2]*a[4][1]*qbRoot[1] + a[3][3]*a[4][1]*qbRoot[1] - a[2][1]*a[4][2]*qbRoot[1] - a[3][1]*a[4][3]*qbRoot[1] - a[4][1]*(qbRoot[1]*qbRoot[1]))), 1}, {-(1/(
a[3][2]*a[4][1] - a[3][1]*a[4][2]))*(at05 - a[3][2]*qbRoot[2]) + ((at04 + a[4][2]*qbRoot[2])*(at02 - a[2][2]*a[3][1]*qbRoot[2] + a[2][1]*a[3][2]*qbRoot[2] + a[3][4]*a[4][1]*qbRoot[2] - a[3][1]*a[4][4]*qbRoot[2] +
a[3][1]*(qbRoot[2]*qbRoot[2])))/((a[3][2]*a[4][1] - a[3][1]*a[4][2])* (at01 + a[2][2]*a[4][1]*qbRoot[2] + a[3][3]*a[4][1]*qbRoot[2] - a[2][1]*a[4][2]*qbRoot[2] - a[3][1]*a[4][3]*qbRoot[2] -
a[4][1]*(qbRoot[2]*qbRoot[2]))), -((at03 + a[2][3]*a[3][1]*qbRoot[2] - a[2][1]*a[3][3]*qbRoot[2] + a[2][4]*a[4][1]*qbRoot[2] - a[2][1]*a[4][4]*qbRoot[2] + a[2][1]*(qbRoot[2]*qbRoot[2]))/(at01 + a[2][2]*a[4][1]*qbRoot[2] +
a[3][3]*a[4][1]*qbRoot[2] - a[2][1]*a[4][2]*qbRoot[2] - a[3][1]*a[4][3]*qbRoot[2] - a[4][1]*(qbRoot[2]*qbRoot[2]))), -((at02 - a[2][2]*a[3][1]*qbRoot[2] + a[2][1]*a[3][2]*qbRoot[2] + a[3][4]*a[4][1]*qbRoot[2] -
a[3][1]*a[4][4]*qbRoot[2] + a[3][1]*(qbRoot[2]*qbRoot[2]))/(at01 + a[2][2]*a[4][1]*qbRoot[2] + a[3][3]*a[4][1]*qbRoot[2] - a[2][1]*a[4][2]*qbRoot[2] - a[3][1]*a[4][3]*qbRoot[2] - a[4][1]*(qbRoot[2]*qbRoot[2]))), 1}, {-(1/(
a[3][2]*a[4][1] - a[3][1]*a[4][2]))*(at05 - a[3][2]*qbRoot[3]) + ((at04 + a[4][2]*qbRoot[3])*(at02 - a[2][2]*a[3][1]*qbRoot[3] + a[2][1]*a[3][2]*qbRoot[3] + a[3][4]*a[4][1]*qbRoot[3] - a[3][1]*a[4][4]*qbRoot[3] +
a[3][1]*(qbRoot[3]*qbRoot[3])))/((a[3][2]*a[4][1] - a[3][1]*a[4][2])*(at01 + a[2][2]*a[4][1]*qbRoot[3] + a[3][3]*a[4][1]*qbRoot[3] - a[2][1]*a[4][2]*qbRoot[3] - a[3][1]*a[4][3]*qbRoot[3] - a[4][1]*(qbRoot[3]*qbRoot[3]))), -((at03 +
a[2][3]*a[3][1]*qbRoot[3] - a[2][1]*a[3][3]*qbRoot[3] + a[2][4]*a[4][1]*qbRoot[3] - a[2][1]*a[4][4]*qbRoot[3] + a[2][1]*(qbRoot[3]*qbRoot[3]))/(at01 + a[2][2]*a[4][1]*qbRoot[3] + a[3][3]*a[4][1]*qbRoot[3] -
a[2][1]*a[4][2]*qbRoot[3] - a[3][1]*a[4][3]*qbRoot[3] - a[4][1]*(qbRoot[3]*qbRoot[3]))), -((at02 - a[2][2]*a[3][1]*qbRoot[3] + a[2][1]*a[3][2]*qbRoot[3] + a[3][4]*a[4][1]*qbRoot[3] - a[3][1]*a[4][4]*qbRoot[3] +
a[3][1]*(qbRoot[3]*qbRoot[3]))/(at01 + a[2][2]*a[4][1]*qbRoot[3] + a[3][3]*a[4][1]*qbRoot[3] - a[2][1]*a[4][2]*qbRoot[3] - a[3][1]*a[4][3]*qbRoot[3] - a[4][1]*(qbRoot[3]*qbRoot[3]))), 1}, {-(1/( a[3][2]*a[4][1] -
a[3][1]*a[4][2]))*(at05 - a[3][2]*qbRoot[4]) + ((at04 + a[4][2]*qbRoot[4])*(at02 - a[2][2]*a[3][1]*qbRoot[4] + a[2][1]*a[3][2]*qbRoot[4] + a[3][4]*a[4][1]*qbRoot[4] - a[3][1]*a[4][4]*qbRoot[4] + a[3][1]*(qbRoot[4]*qbRoot[4])))/((
a[3][2]*a[4][1] - a[3][1]*a[4][2])*(at01 + a[2][2]*a[4][1]* qbRoot[4] + a[3][3]*a[4][1]*qbRoot[4] - a[2][1]*a[4][2]*qbRoot[4] - a[3][1]*a[4][3]*qbRoot[4] - a[4][1]*(qbRoot[4]*qbRoot[4]))), -((at03 + a[2][3]*a[3][1]*qbRoot[4] -
a[2][1]*a[3][3]*qbRoot[4] + a[2][4]*a[4][1]*qbRoot[4] - a[2][1]*a[4][4]*qbRoot[4] + a[2][1]*(qbRoot[4]*qbRoot[4]))/(at01 + a[2][2]*a[4][1]*qbRoot[4] + a[3][3]*a[4][1]*qbRoot[4] - a[2][1]*a[4][2]*qbRoot[4] - a[3][1]*a[4][3]*qbRoot[4] -
a[4][1]*(qbRoot[4]*qbRoot[4]))), -((at02 - a[2][2]*a[3][1]*qbRoot[4] + a[2][1]*a[3][2]*qbRoot[4] + a[3][4]*a[4][1]*qbRoot[4] - a[3][1]*a[4][4]*qbRoot[4] + a[3][1]*(qbRoot[4]*qbRoot[4]))/(at01 +
a[2][2]*a[4][1]*qbRoot[4] + a[3][3]*a[4][1]*qbRoot[4] - a[2][1]*a[4][2]*qbRoot[4] - a[3][1]*a[4][3]*qbRoot[4] - a[4][1]*(qbRoot[4]*qbRoot[4]))), 1}}
end
function p.getNumber(frame)
local args, working_frame
if frame == mw.getCurrentFrame() then
-- We're being called via #invoke. The args are passed through to the module
-- from the template page, so use the args that were passed into the template.
load_getArgs()
args = getArgs(frame, {parentFirst=true}) --frame.args
working_frame = frame
else
-- We're being called from another module or from the debug console, so assume
-- the args are passed in directly.
args = frame
working_frame = mw.getCurrentFrame()
if type(args) ~= type({}) then args = {frame} end
end
local input_text = args[1] or args["1"]
local got_num = tonumber(input_text)
if got_num == nil then
load_comp_lib()
got_num = toCnumber(input_text)
else
if p._isNaN(got_num) then got_num=tonumber("nan") end
end
if got_num == nil then
load_comp_lib()
local qmath = comp_lib.qmath.init()
local toQnumber = qmath.constructor
got_num = toQnumber(input_text)
else
if p._isNaN(tonumber(tostring(got_num))or 1) then got_num=tonumber("nan") end
end
return got_num
end
function p.numberType(frame)
local args, working_frame
if frame == mw.getCurrentFrame() then
-- We're being called via #invoke. The args are passed through to the module
-- from the template page, so use the args that were passed into the template.
load_getArgs()
args = getArgs(frame, {parentFirst=true}) --frame.args
working_frame = frame
else
-- We're being called from another module or from the debug console, so assume
-- the args are passed in directly.
args = frame
working_frame = mw.getCurrentFrame()
if type(args) ~= type({}) then args = {frame} end
end
local input_text = args[1] or args["1"]
local got_num = p.getNumber(args)
return p._numberType(got_num)
end
function p.trunc(frame,_n)
local args, working_frame
if frame == mw.getCurrentFrame() then
-- We're being called via #invoke. The args are passed through to the module
-- from the template page, so use the args that were passed into the template.
load_getArgs()
args = getArgs(frame, {parentFirst=true}) --frame.args
working_frame = frame
else
-- We're being called from another module or from the debug console, so assume
-- the args are passed in directly.
args = frame
working_frame = mw.getCurrentFrame()
if type(args) ~= type({}) then args = {frame,_n or 0} end
end
local x = tonumber(args[1] or args["1"])or 0
local n = tonumber(args[2] or args["2"])or 0
return p._trunc(x,n)
end
function p.random(frame,_b)
local args, working_frame
if frame == mw.getCurrentFrame() then
-- We're being called via #invoke. The args are passed through to the module
-- from the template page, so use the args that were passed into the template.
load_getArgs()
args = getArgs(frame, {parentFirst=true}) --frame.args
working_frame = frame
math.randomseed(math.floor(os.time() * os.clock()))
else
-- We're being called from another module or from the debug console, so assume
-- the args are passed in directly.
args = frame
working_frame = mw.getCurrentFrame()
if type(args) ~= type({}) then args = {frame,_b} end
end
local str_a = args[1] or args["1"]or ""
local str_b = args[2] or args["2"]or ""
local a = (mw.text.trim(str_a)~="")and tonumber(str_a) or nil
local b = (mw.text.trim(str_b)~="")and tonumber(str_b) or nil
return p._random(a,b)
end
function p.get4x4matrix(frame, lua_call)
local args
local is_invoke = false
if frame == mw.getCurrentFrame() then
-- We're being called via #invoke. The args are passed through to the module
-- from the template page, so use the args that were passed into the template.
load_getArgs()
args = getArgs(frame, {parentFirst=true}) --frame.args
is_invoke = true
else
-- We're being called from another module or from the debug console, so assume
-- the args are passed in directly.
args = frame
if type(args) ~= type({}) then args = {frame} end
end
load_matrix_lib()
local input_text = args[1] or args["1"] or 'nan'
local input_matrix = mmath.toMatrix(input_text)
if not (p.numberType(input_text):lower()=="nan") then return args, is_invoke end
local matrix = {}
for i=1,4 do
local rowdata = {}
for j=1,4 do
rowdata[#rowdata + 1]=(input_matrix[i]or{})[j] or 0
end
matrix[#matrix + 1] = mmath.row(unpack(rowdata))
end
matrix = mmath.matrix(unpack(matrix))
if lua_call then return args, is_invoke, matrix
else return matrix end
end
function p.matrix4x4EigenRoot(frame)
local args, is_invoke, matrix = p.get4x4matrix(frame, true)
if not matrix then return '' end
local result = p._quarticEigenRoot(matrix)
local root = tonumber(args.root)
if root and result[root] then return result[root] end
local comma = args.comma or ','
if comma == '' then comma = ','end
if is_invoke then
local body = ''
for i=1,#result do
if body~=''then body=body..comma end
body=body..tostring(result[i])
end
return body
end
return result
end
function p.matrix4x4EigenVector(frame)
local args, is_invoke, matrix = p.get4x4matrix(frame, true)
if not matrix then return '' end
local result = p._quarticEigenData(matrix)
local root = tonumber(args.root)
local comma = args.comma or ','
if comma == '' then comma = ','end
if root and result[root] then
local output_result = result[root]
if is_invoke then
local output_body = ''
for i=1,#output_result do
if output_body~=''then output_body=output_body..comma end
output_body=output_body..tostring(output_result[i])
end
return output_body
end
return output_result
end
local comma2 = args.comma2 or ';'
if comma2 == '' then comma2 = ';'end
if is_invoke then
local body = ''
for i=1,#result do
if body~=''then body=body..comma2 end
local output_body = ''
local output_result = result[i]
for j=1,#output_result do
if output_body~=''then output_body=output_body..comma end
output_body=output_body..tostring(output_result[j])
end
body=body..output_body
end
return body
end
return result
end
function p.solveEQ(frame,...)
local args, working_frame
local is_invoke = false
if frame == mw.getCurrentFrame() then
-- We're being called via #invoke. The args are passed through to the module
-- from the template page, so use the args that were passed into the template.
load_getArgs()
args = getArgs(frame, {parentFirst=true}) --frame.args
working_frame = frame
is_invoke = true
else
-- We're being called from another module or from the debug console, so assume
-- the args are passed in directly.
args = frame
working_frame = mw.getCurrentFrame()
if type(args) ~= type({}) then args = {frame,...} end
end
load_matrix_lib()
local max_id = -1 for var_id,_ in pairs(args) do local load_id = tonumber(var_id)or-1 if load_id and load_id > max_id then max_id=load_id end end
if max_id <= 0 then return is_invoke and""or{} end
local input_list = {}
for i=1,max_id do
local got_num = p.getNumber(args[i])
if p._isNaN(tonumber(tostring(got_num))or 1) then got_num = 0 end
if got_num==nil then got_num = 0 end
input_list[i] = got_num
end
local ret = p._solveEQ(unpack(input_list))
local root = tonumber(args.root)
local comma = args.comma or ','
if comma == '' then comma = ','end
if root and ret[root] then return ret[root] end
if is_invoke then
local body = ''
for i=1,#ret do
if body~=''then body=body..comma end
body=body..tostring(ret[i])
end
return body
end
return ret
end
return p