模組:Complex Number/CayleyDickson
外观

本模組為基於Module:Complex Number的凯莱-迪克森结构運算系統,可將Module:Complex Number系列函數庫的任一數學庫套用凯莱-迪克森结构形成新的數學庫,並能提供其他模組呼叫使用。而若要直接在模板或條目中使用可透過Module:Complex Number/Calculate或{{複變運算}}來完成。
模組內容
本模組有5套數學資料結構的定義以及對應的數學運算庫:
- .cdmathQuaternion
- 已將四元數套用凯莱-迪克森结构形成的代數結構之數學資料結構及運算的系統,可當八元數使用。
- .cdmathOctonion
- 已將八元數套用凯莱-迪克森结构形成的代數結構之數學資料結構及運算的系統,可當十六元數使用。
- .cdmathSedenion
- 已將十六元數套用凯莱-迪克森结构形成的代數結構之數學資料結構及運算的系統,可當三十二元數使用。
- .sdmath
- 十六元數的數學資料結構及運算的系統
使用方法
LUA
- 初始化數學庫
- 一般方法:
local 自訂函數庫名稱 = require("Module:Complex Number/CayleyDickson").函數庫名稱.init()
- 例如初始化十六元數數學庫:
local sdmath = require("Module:Complex Number/CayleyDickson").sdmath.init()
- 例如初始化十六元數數學庫:
- 套用凯莱-迪克森结构並初始化數學庫:
- 直接載入已套用凯莱-迪克森结构的數學庫並初始化:
local 自訂函數庫名稱 = require("Module:Complex Number/CayleyDickson")['cdmath=要套用凯莱-迪克森结构的數學庫的模組路徑和名稱'].init()
- 例如初始化將八元數(Module:Complex Number/Octonion)套用凯莱-迪克森结构所形成的十六元數數學庫:
local sdomath = require("Module:Complex Number/CayleyDickson")['cdmath=Module:Complex_Number/Octonion.omath'].init()
- 其中數學庫的模組路徑和名稱格式為
Module:模組名稱.數學庫名稱
- 例如初始化將八元數(Module:Complex Number/Octonion)套用凯莱-迪克森结构所形成的十六元數數學庫:
- 一般方法:
- 初始化指定數學結構的數字
local 變數名稱 = 自訂函數庫名稱.constructor("描述數字的字串,單位元素用ele(n)表示")
- 例如:
local num1 = sdomath.constructor("2+3*ele(2)+ele(4)")
- 例如:
- 執行運算
- 例如:
local sdomath = require("Module:Complex Number/CayleyDickson")['cdmath=Module:Complex_Number/Octonion.omath'].init() local num1 = sdomath.constructor("2+3*ele(2)+ele(4)") local num2 = sdomath.constructor("4+5*ele(3)+ele(4)") print(num1 * num2)
- 輸出:7+15*ele(1)+12*ele(2)+10*ele(3)+6*ele(4)+3*ele(6)-5*ele(7)
- 或者使用函數庫內容:
local sdomath = require("Module:Complex Number/CayleyDickson")['cdmath=Module:Complex_Number/Octonion.omath'].init() local num1 = sdomath.constructor("2+3*ele(2)+ele(4)") print(sdomath.sqrt(num1))
- 輸出:1.6943519980768+0.88529420197369*ele(2)+0.29509806732456*ele(4)
- 例如:
模板
使用{{複變運算}}
- 語法:
{{複變運算|運算式|number class=Module:Complex Number/CayleyDickson.cdmath=要套用凯莱-迪克森结构函數庫模組路徑和名稱}}
- 例如:
{{複變運算|(2+3*ele(2)+ele(4))*(4+5*ele(3)+ele(4))|number class=Module:Complex Number/CayleyDickson.cdmath=Module:Complex Number/Octonion.omath}}
- →「7+15*ele(1)+12*ele(2)+10*ele(3)+6*ele(4)+3*ele(6)-5*ele(7)」
- 例如:
{{複變運算|sqrt(2+3*ele(2)+ele(4))|number class=Module:Complex Number/CayleyDickson.cdmath=Module:Complex Number/Octonion.omath}}
- →「1.6943519980768+0.88529420197369*ele(2)+0.29509806732456*ele(4)」
- 例如:
使用{{計算結果}}
參見
local p = {}
local comp_lib = require("Module:Complex_Number")
local cmath = comp_lib.cmath.init()
function p._isNaN(x)
return (not (x==x)) and (x~=x)
end
--無法套娃的[[凯莱-迪克森结构]]
function p.get_cdmath(_data)
local q = {}
q.cdmath={
scopeflag=_data,
abs=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
local A_len, B_len = q.cdmath.mathlib.abs(A), q.cdmath.mathlib.abs(B)
return math.sqrt( A_len * A_len + B_len * B_len )
end,
floor=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
return q.cdmath.checkMathform(q.cdmath.mathlib.floor(A), q.cdmath.mathlib.floor(B), z)
end,
ceil=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
return q.cdmath.checkMathform(q.cdmath.mathlib.ceil(A), q.cdmath.mathlib.ceil(B), z)
end,
div=function(left,z)
return left*q.cdmath.inverse(z)
end,
round=function(op1,op2,op3)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(op1)
local o2, _2 = q.cdmath.readCayleyDicksonNumberCDpart(op2)
local o3, _3 = q.cdmath.readCayleyDicksonNumberCDpart(op3)
return q.cdmath.checkMathform(q.cdmath.mathlib.round(A,o2,o3), q.cdmath.mathlib.round(B,o2,o3), op1,op2,op3)
end,
re=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
return q.cdmath.mathlib.re(A)
end,
im=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
return q.cdmath.mathlib.im(A)
end,
conjugate=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(q.cdmath.mathlib.conjugate(A), -B), z)
end,
inverse=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
local A_up, B_up = q.cdmath.mathlib.conjugate(A), -B
local A_len, B_len = q.cdmath.mathlib.abs(A), q.cdmath.mathlib.abs(B)
local div_down = ( A_len * A_len + B_len * B_len )
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(A_up / div_down, B_up / div_down), z)
end,
tovector=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
local _A, _B = q.cdmath.toSnumber(tostring(A)), q.cdmath.toSnumber(tostring(B))
return {unpack(q.cdmath.mathlib.tovector(A or 0) or {}), unpack(q.cdmath.mathlib.tovector(B or 0) or {})}
end,
trunc=function(op1,op2)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(op1)
local o2, _2 = q.cdmath.readCayleyDicksonNumberCDpart(op2)
return q.cdmath.checkMathform(q.cdmath.mathlib.trunc(A,o2), q.cdmath.mathlib.trunc(B,o2), op1,op2)
end,
sqrt=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
local s_zero = q.cdmath.toSnumber("0")
if A == s_zero then
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(q.cdmath.mathlib.sqrt(A), q.cdmath.toSnumber("0")), z)
end
return q.cdmath.checkMathform(q.cdmath.pow(z, 0.5), z)
end,
sin=function(z)
local u = q.cdmath.nonRealPart(z)
return ( math.cosh(q.cdmath.abs(u)) * math.sin(q.cdmath.re(z)) ) + ( q.cdmath.sgn(u) * math.sinh(q.cdmath.abs(u)) * math.cos(q.cdmath.re(z)) )
end,
cos=function(z)
local u = q.cdmath.nonRealPart(z)
return ( math.cosh(q.cdmath.abs(u)) * math.cos(q.cdmath.re(z)) ) - ( q.cdmath.sgn(u) * math.sinh(q.cdmath.abs(u)) * math.sin(q.cdmath.re(z)) )
end,
tan=function(z)
local theta = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.sin(theta) * q.cdmath.inverse( q.cdmath.cos(theta) )
end,
cot=function(z)
local theta = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.cos(theta) * q.cdmath.inverse( q.cdmath.sin(theta) )
end,
asin=function(z)
local v = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
local u = q.cdmath.nonRealPart(z)
local sgnu = q.cdmath.sgn(u);
if q.cdmath.abs(sgnu) < 1e-12 then sgnu = sgnu + q.cdmath.ele(1) end
return -sgnu * q.cdmath.asinh( v * sgnu )
end,
acos=function(z)
local v = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
local u = q.cdmath.nonRealPart(z)
local sgnu = q.cdmath.sgn(u);
if q.cdmath.abs(sgnu) < 1e-12 then sgnu = sgnu + q.cdmath.ele(1) end
return -sgnu * q.cdmath.acosh( v )
end,
atan=function(z)
local v = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
local u = q.cdmath.nonRealPart(z)
local sgnu = q.cdmath.sgn(u);
if q.cdmath.abs(sgnu) < 1e-12 then sgnu = sgnu + q.cdmath.ele(1) end
return -sgnu * q.cdmath.atanh( v * sgnu )
end,
acot=function(z)
local v = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
local u = q.cdmath.nonRealPart(z)
local sgnu = q.cdmath.sgn(u);
if q.cdmath.abs(sgnu) < 1e-12 then sgnu = sgnu + q.cdmath.ele(1) end
return sgnu * q.cdmath.acoth( v * sgnu )
end,
sinh=function(z)
local u = q.cdmath.nonRealPart(z)
return ( math.cos(q.cdmath.abs(u)) * math.sinh(q.cdmath.re(z)) ) + ( q.cdmath.sgn(u) * math.sin(q.cdmath.abs(u)) * math.cosh(q.cdmath.re(z)) )
end,
cosh=function(z)
local u = q.cdmath.nonRealPart(z)
return ( math.cos(q.cdmath.abs(u)) * math.cosh(q.cdmath.re(z)) ) + ( q.cdmath.sgn(u) * math.sin(q.cdmath.abs(u)) * math.sinh(q.cdmath.re(z)) )
end,
tanh=function(z)
local theta = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.sinh(theta) * q.cdmath.inverse( q.cdmath.cosh(theta) )
end,
coth=function(z)
local theta = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.cosh(theta) * q.cdmath.inverse( q.cdmath.sinh(theta) )
end,
asinh=function(z)
local _one = q.cdmath.getCayleyDicksonNumber("1", "0")
local u = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.checkMathform(q.cdmath.elog( u + q.cdmath.sqrt( u * u + _one ) ), z)
end,
acosh=function(z)
local _one = q.cdmath.getCayleyDicksonNumber("1", "0")
local u = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.checkMathform(q.cdmath.elog( u + q.cdmath.sqrt( u + _one ) * q.cdmath.sqrt( u - _one ) ),z)
end,
atanh=function(z)
local _one = q.cdmath.getCayleyDicksonNumber("1", "0")
local u = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.checkMathform(( q.cdmath.elog( _one + u ) - q.cdmath.elog( _one - u ) ) / 2, z)
end,
acoth=function(z)
local _one = q.cdmath.getCayleyDicksonNumber("1", "0")
local u = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.checkMathform(( q.cdmath.elog( _one + q.cdmath.inverse(u) ) - q.cdmath.elog( _one - q.cdmath.inverse(u) ) ) / 2, z)
end,
dot = function (op1, op2)
local nonL1, valL1 = q.cdmath.readCayleyDicksonNumberCDpart(op1)
local nonL2, valL2 = q.cdmath.readCayleyDicksonNumberCDpart(op2)
return q.cdmath.mathlib.dot(nonL1, nonL2) + q.cdmath.mathlib.dot(valL1, valL2)
end,
scalarPart=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(q.cdmath.mathlib.re(A))), q.cdmath.toSnumber("0")), z)
end,
vectorPart=function(z)
return q.cdmath.nonRealPart(z)
end,
nonRealPart=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(q.cdmath.mathlib.nonRealPart(A), B), z)
end,
sgn=function(z)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
local A_len, B_len = q.cdmath.mathlib.abs(A), q.cdmath.mathlib.abs(B)
local length = math.sqrt( A_len * A_len + B_len * B_len )
if length <= 0 then return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber("0"),q.cdmath.toSnumber("0")), z) end
return q.cdmath.checkMathform(z / length, z)
end,
arg=function(z) --TODO: verify
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(z)
local A_len, B_len = q.cdmath.mathlib.abs(A), q.cdmath.mathlib.abs(B)
local length = math.sqrt( A_len * A_len + B_len * B_len )
return math.acos( q.cdmath.mathlib.re(A) / length )
end,
cis=function(z)
local u = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(z))
return q.cdmath.cos(u) + q.cdmath.ele(1) * q.cdmath.sin(u)
end,
exp=function(z) --Cayley-Dickson construction
local u = q.cdmath.nonRealPart(z)
return q.cdmath.checkMathform(( (q.cdmath.sgn(u) * math.sin(q.cdmath.abs(u))) + math.cos(q.cdmath.abs(u))) * math.exp(q.cdmath.re(z)), z)
end,
elog=function(z) --Cayley-Dickson construction
local u = q.cdmath.nonRealPart(z)
return q.cdmath.checkMathform(q.cdmath.sgn(u)*q.cdmath.arg(z)+math.log(q.cdmath.abs(z)), z)
end,
log=function(z,basez)
if basez~=nil then return q.cdmath.checkMathform(q.cdmath.elog(basez) * q.cdmath.inverse(q.cdmath.elog(z)), z) end
return q.cdmath.elog(z)
end,
pow=function(op1,op2)
local _zero = q.cdmath.getCayleyDicksonNumber("0", "0")
local a = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(op1))
local z = q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(op2))
a:clean();z:clean();
if a.B == _zero and z.B == _zero then
return q.cdmath.checkMathform(q.cdmath.getOctonionNumberQ(q.cdmath.mathlib.pow(a.A, z.A), q.cdmath.toSnumber("0")), op1, op2)
end
return q.cdmath.checkMathform(q.cdmath.exp(z * q.cdmath.elog(a)):clean(), op1, op2)
end,
ele=function(id)
local _zero = q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber("0"), q.cdmath.toSnumber("0"))
local eles = (q.cdmath.elements or {})
local id_msg = tonumber(tostring(id)) or 0
return q.cdmath.checkMathform(eles[id_msg+1]or _zero, id)
end,
readCayleyDicksonNumberCDpart = function(z)
local dim = tonumber(({tostring((type(z)==type({}))and z.numberType or ''):gsub("%-onion","")})[1])
if type(z) == type({}) then --if already be complex number, don't run string find.
if z.numberType == "complex" then
if q.cdmath.elementCount >= 2 then
return q.cdmath.toSnumber(tostring(z)), q.cdmath.toSnumber("0")
else
return q.cdmath.toSnumber(tostring(q.cdmath.mathlib.re(z))), q.cdmath.toSnumber(tostring(q.cdmath.mathlib.im(z)))
end
elseif z.numberType == "quaternion" then
if q.cdmath.elementCount >= 4 then
return q.cdmath.toSnumber(tostring(z)), q.cdmath.toSnumber("0")
elseif q.cdmath.elementCount >= 2 then
return q.cdmath.toSnumber(tostring(z.real or 0)..'+'..tostring(z.imag or 0)..'i'), q.cdmath.toSnumber(tostring(z.jpart or 0)..'+'..tostring(z.kpart or 0)..'i')
else
error("Can not divide into 2 parts.")
end
elseif z.numberType == "octonion" then
if q.cdmath.elementCount >= 8 then
return q.cdmath.toSnumber(tostring(z)), q.cdmath.toSnumber("0")
elseif q.cdmath.elementCount >= 4 then
return z.nonL, z.valL
elseif q.cdmath.elementCount >= 2 then
return q.cdmath.toSnumber(tostring(z.nonL.real or 0)..'+'..tostring(z.nonL.imag or 0)..'i'), q.cdmath.toSnumber(tostring(z.nonL.jpart or 0)..'+'..tostring(z.nonL.kpart or 0)..'i')
else
error("Can not divide into 2 parts.")
end
elseif dim~=nil then
local this_dim = q.cdmath.elementCount
if dim == this_dim then
return z.A, z.B
elseif dim <= q.cdmath.elementCount then
return q.cdmath.toSnumber(tostring(z)), q.cdmath.toSnumber("0")
else
error(q.cdmath.elementCount.." Not support number system.")
end
else
error(q.cdmath.elementCount.." Not support number system.")
end
elseif type(z) == type(0) then
return q.cdmath.toSnumber(tostring(z)), q.cdmath.toSnumber("0")
end
end,
CayleyDicksonNumberMeta = {
__add = function (op1, op2)
local op1_a, op1_b = q.cdmath.readCayleyDicksonNumberCDpart(op1)
local op2_a, op2_b = q.cdmath.readCayleyDicksonNumberCDpart(op2)
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(op1_a + op2_a, op1_b + op2_b), op1, op2)
end,
__sub = function (op1, op2)
local op1_a, op1_b = q.cdmath.readCayleyDicksonNumberCDpart(op1)
local op2_a, op2_b = q.cdmath.readCayleyDicksonNumberCDpart(op2)
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(op1_a - op2_a, op1_b - op2_b), op1, op2)
end,
__mul = function (op1, op2)
local _a, _b = q.cdmath.readCayleyDicksonNumberCDpart(op1)
local _c, _d = q.cdmath.readCayleyDicksonNumberCDpart(op2)
local r_nonL = _a*_c - q.cdmath.mathlib.conjugate(_d)*_b
local r_valL = _d*_a + _b*q.cdmath.mathlib.conjugate(_c)
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(r_nonL, r_valL), op1, op2)
end,
__div = function (op1, op2)
local op_div = q.cdmath.inverse(op2)
local _a, _b = q.cdmath.readCayleyDicksonNumberCDpart(op1)
local _c, _d = q.cdmath.readCayleyDicksonNumberCDpart(op_div)
local r_nonL = _a*_c - q.cdmath.mathlib.conjugate(_d)*_b
local r_valL = _d*_a + _b*q.cdmath.mathlib.conjugate(_c)
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(r_nonL, r_valL), op1, op2)
end,
__mod = function (op1, op2)
local x = q.cdmath.readComplexNumber(op1)
local y = q.cdmath.readComplexNumber(op2)
return q.cdmath.checkMathform(x - y * qmath.floor(x / y), op1, op2)
end,
__unm = function (this)
return q.cdmath.checkMathform(q.cdmath.getCayleyDicksonNumber(-this.A, -this.B), this)
end,
__eq = function (op1, op2)
return op1.A == op2.A and op1.B == op2.B
end,
__tostring = function (this)
local A, B = q.cdmath.readCayleyDicksonNumberCDpart(this)
local strA = tostring(A)
local strB = tostring(B)
if strA == "nan" or strA == "-nan" then return strA end
if strB == "nan" or strB == "-nan" then return strB end
if strA == "0" and strB == "0" then return "0" end
local body = ''
local eles = (q.cdmath.elements or {})
for i=1,#eles do
--q.cdmath.readCayleyDicksonNumberCDpart(eles[i])
local val = tonumber(q.cdmath.dot(this,eles[i]))or 0
if math.abs(val)>1e-14 then
local val_str = ''
local is_one = (math.abs(math.abs(val)-1)<1e-14)
local has_num = false
if val>0 then
if body~=''then val_str = val_str ..'+'end
val_str = val_str..(is_one and''or tostring(val))
has_num = true
elseif val<0 then
val_str = val_str..(is_one and'-'or tostring(val))
has_num = true
end
if has_num then
if i==1 then
body = body..val_str..(is_one and'1'or'')
else
if this.mathform then
body = body..val_str..' e_{'..tostring(i-1)..'}'
else
body = body..val_str..(is_one and''or'*')..'ele('..tostring(i-1)..')'
end
end
end
end
end
if body=='' then body = 0 end
--return mw.dumpObject(this)
return body
end,
},
checkMathform=function(result,...)
local parms = {...}
local flag = false
for i=1,#parms do flag = flag or ((type(parms[i])==type({}))and parms[i].mathform or false)end
if type(result)==type({})then result.mathform = result.mathform or flag end
return result
end,
mathlib=cmath,
toSnumber=cmath.constructor,
mathform = function(this)this.mathform=true return this end,
toCayleyDicksonNumber = function(str)
--load if already a number
local dim = tonumber(({tostring((type(str)==type({}))and str.numberType or ''):gsub("%-onion","")})[1])
if type(str) == type({}) then --if already be complex number, don't run string find.
if str.numberType == "complex" then
if q.cdmath.elementCount >= 2 then
return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str)), q.cdmath.toSnumber("0"))
else
return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(q.cdmath.mathlib.re(str))), q.cdmath.toSnumber(tostring(q.cdmath.mathlib.im(str))))
end
elseif str.numberType == "quaternion" then
if q.cdmath.elementCount >= 4 then
return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str)), q.cdmath.toSnumber("0"))
elseif q.cdmath.elementCount >= 2 then
return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str.real or 0)..'+'..tostring(str.imag or 0)..'i'), q.cdmath.toSnumber(tostring(str.jpart or 0)..'+'..tostring(str.kpart or 0)..'i'))
end
elseif str.numberType == "octonion" then
if q.cdmath.elementCount >= 8 then
return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str)), q.cdmath.toSnumber("0"))
elseif q.cdmath.elementCount >= 4 then
return q.cdmath.getCayleyDicksonNumber(str.nonL, str.valL)
elseif q.cdmath.elementCount >= 2 then
return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str.nonL.real or 0)..'+'..tostring(str.nonL.imag or 0)..'i'), q.cdmath.toSnumber(tostring(str.nonL.jpart or 0)..'+'..tostring(str.nonL.kpart or 0)..'i'))
end
elseif dim~=nil then
local this_dim = q.cdmath.elementCount
mw.log(q.cdmath.scopeflag, "toCayleyDicksonNumber", dim, this_dim)
if dim == this_dim then
return q.cdmath.getCayleyDicksonNumber(str.A, str.B)
elseif dim <= q.cdmath.elementCount then
return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str)), q.cdmath.toSnumber("0"))
else
end
else
end
elseif type(str) == type(0) then
return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str)), q.cdmath.toSnumber("0"))
end
--try to parse into substring
local tmp_num = q.cdmath.toSnumber(tostring(str))
if tmp_num ~= nil then
return q.cdmath.getCayleyDicksonNumber(tmp_num, q.cdmath.toSnumber("0"))
end
--parse full string
local chk_str = tostring(str)
local got_list = {}
local ismath = false
if mw.ustring.find(chk_str,"%(")then
got_list = mw.text.split(mw.ustring.gsub(chk_str,"([%+%-])",",%1"),",")
for i=1,#got_list do
got_list[i] = mw.ustring.gsub(got_list[i],"ele","*"):gsub("%*+","*"):gsub("[%(%)]","")
end
elseif mw.ustring.find(chk_str,"%{")then
got_list = mw.text.split(mw.ustring.gsub(chk_str,"([%+%-])",",%1"),",")
for i=1,#got_list do
got_list[i] = mw.ustring.gsub(got_list[i],"^e"," e"):gsub("e","*"):gsub(" +","*"):gsub("%*+","*"):gsub("[_%{%}]","")
end
ismath = true
end
if #got_list > 0 then
local eles = (q.cdmath.elements or {})
local result_number = q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber("0"), q.cdmath.toSnumber("0"))
local _zero = q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber("0"), q.cdmath.toSnumber("0"))
local _one = q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber("1"), q.cdmath.toSnumber("0"))
for i=1,#got_list do
if mw.text.trim(got_list[i])~='' then
local check_ele = mw.text.split(got_list[i],"%*+")
local real_coeff = tonumber(check_ele[1])or (tonumber( (tostring(check_ele[1])~='')and(tostring(check_ele[1])..'1')or check_ele[1] ) or 1)
local real_eleid = tonumber(check_ele[2])or 0
local this_ele = eles[real_eleid+1]or _zero
result_number = result_number + this_ele*real_coeff
end
end
result_number.mathform = ismath
return result_number
end
return q.cdmath.getCayleyDicksonNumber(q.cdmath.readCayleyDicksonNumberCDpart(str))
end,
getCayleyDicksonNumber = function(a,b)
CayleyDicksonNumber = {}
setmetatable(CayleyDicksonNumber,q.cdmath.CayleyDicksonNumberMeta)
function CayleyDicksonNumber:update()
xpcall(function()
self.A:update()
self.B:update()
self.argument = 0
self.length = math.sqrt( self.A.length * self.A.length + self.B.length * self.B.length )
end,function()end)
end
function CayleyDicksonNumber:clean()
xpcall(function()
self.A:clean()
self.B:clean()
end,function()end)
return self
end
--mw.log(q.cdmath.toSnumber(a).numberType)
--if q.cdmath.mathlib.elementCount then
-- mw.log("got=",q.cdmath.mathlib.elementCount)
--else
-- mw.log("got=",#(q.cdmath.mathlib.elements or {}))
--end
mw.log(" ",q.cdmath.scopeflag,"A=",q.cdmath.toSnumber(a), (q.cdmath.toSnumber(a)or{}).numberType)
mw.log(" ",q.cdmath.scopeflag,"B=",q.cdmath.toSnumber(b), (q.cdmath.toSnumber(b)or{}).numberType)
CayleyDicksonNumber.A = q.cdmath.toSnumber(a) or q.cdmath.toSnumber("0")
CayleyDicksonNumber.B = q.cdmath.toSnumber(b) or q.cdmath.toSnumber("0")
CayleyDicksonNumber.numberType = tostring(q.cdmath.elementCount).."-onion"
return CayleyDicksonNumber
end,
init = function(math_lib)
return q.cdmath._init(math_lib)
end,
_init = function(math_lib)
if type(math_lib)==type({})then
q.cdmath.mathlib = math_lib.init()
q.cdmath.toSnumber = q.cdmath.mathlib.constructor
end
local _zero = q.cdmath.toSnumber("0")
mw.log("flag",q.cdmath.scopeflag)
q.cdmath.elements = {}
local unit_list = q.cdmath.mathlib.elements or{}
q.cdmath.elementCount = (#unit_list)*2
for i=1,q.cdmath.elementCount do q.cdmath.elements[i] = {} end
for i=1,#unit_list do
mw.log("init",i,"=",unit_list[i],unit_list[i].numberType)
q.cdmath.elements[i] = q.cdmath.getCayleyDicksonNumber(unit_list[i], "0")
xpcall(function()
mw.log("result = ",q.cdmath.elements[i],q.cdmath.elements[i].numberType)
end,function()end)
end
for i=1,#unit_list do
mw.log("init",i+#unit_list,"=",unit_list[i],unit_list[i].numberType)
q.cdmath.elements[i+#unit_list] = q.cdmath.getCayleyDicksonNumber("0", unit_list[i])
xpcall(function()
mw.log("result = ",q.cdmath.elements[i+#unit_list],q.cdmath.elements[i+#unit_list].numberType)
end,function()end)
end
xpcall(function()
mw.log("this eles=")
mw.logObject(q.cdmath.elements)
mw.log("sub eles=")
mw.logObject(q.cdmath.mathlib.elements)
end,function()end)
q.cdmath.pi = q.cdmath.getCayleyDicksonNumber(q.cdmath.mathlib.pi, _zero)
q.cdmath["π"] = q.cdmath.getCayleyDicksonNumber(q.cdmath.mathlib.pi, _zero)
q.cdmath["°"] = q.cdmath.getCayleyDicksonNumber(q.cdmath.mathlib.pi/180, _zero)
q.cdmath.e = q.cdmath.getCayleyDicksonNumber(math.exp(1), _zero)
q.cdmath.nan = q.cdmath.getCayleyDicksonNumber(tonumber("nan"), tonumber("nan"))
q.cdmath.zero = q.cdmath.getCayleyDicksonNumber("0", _zero)
q.cdmath.one = q.cdmath.getCayleyDicksonNumber("1", _zero)
q.cdmath[-1] = q.cdmath.getCayleyDicksonNumber("-1", _zero)
q.cdmath[0],q.cdmath[1] = q.cdmath.zero,q.cdmath.one
q.cdmath.numberType = comp_lib._numberType
q.cdmath.constructor = q.cdmath.toCayleyDicksonNumber
return q.cdmath
end
}
return q
end
p.cdmath = p.get_cdmath(0).cdmath
function p.checkModuleClass(cls)
local class = ((type(cls)==type({}))and( ((cls.args or {})[1]) or cls[1] or '')or( (type(cls)==type("string")) and cls or ''))or''
if mw.ustring.sub(class,1,7):upper()=="MODULE:" then
local data = mw.ustring.sub(class, 8, -1)
local func = mw.ustring.find(data,"%.")
local modu = mw.ustring.sub(data, 1, func -1)
func = mw.ustring.sub(data, func + 1, -1)
return mw.text.trim(modu), mw.text.trim(func)
end
return ''
end
--不能套娃
p.cdmathOctonion={
init = function()
local omath=require("Module:Complex_Number/Octonion").omath.init()
p.cdmathOctonion=mw.clone(p.get_cdmath(1).cdmath).init(omath)
return p.cdmathOctonion._init(omath)
end
}
new_meta = getmetatable( p ) or {}
new_meta.__index = function (this, func_name)
if mw.ustring.find(func_name, "=") then
local eqs, eqe = mw.ustring.find(func_name, "=")
local check_func_name = mw.ustring.sub(func_name,1, (eqs or 0)-1)
local check_r = mw.ustring.find(check_func_name, "=")
if not check_r then
local tocall_obj = p[check_func_name]
if type(tocall_obj) == type({}) then
local math_class = mw.ustring.sub(func_name,(eqe or 0)+1, -1)
if type(tocall_obj._init) ~= nil then
local mymath = cmath
local mytomath = cmath.constructor
if mw.ustring.sub(math_class,1,7):upper()=="MODULE:" then
local module_name, math_lib_name = p.checkModuleClass(math_class)
xpcall(function()
local load_module = require("Module:"..module_name)
if load_module ~= nil then
local load_math_lib = load_module[math_lib_name]
if load_module ~= nil then
local func_type = type(function()end)
local my_math_lib = (type(load_math_lib.init) == func_type) and load_math_lib.init() or load_math_lib
if type(my_math_lib.constructor) == func_type then
math_class = "mymath"
mymath = my_math_lib
mytomath = my_math_lib.constructor
end
end
end
end,function()end)
end
tocall_obj.init=function()
return tocall_obj._init(mymath)
end
end
return tocall_obj
end
end
end
return nil
end
setmetatable(p, new_meta)
return p