跳转到内容

模組:Complex Number/CayleyDickson

本页使用了标题或全文手工转换
维基百科,自由的百科全书

这是本页的一个历史版本,由A2569875留言 | 贡献2022年4月24日 (日) 04:17编辑。这可能和当前版本存在着巨大的差异。

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
					if q.cdmath.elementCount > dim then
						return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str)), q.cdmath.toSnumber("0"))
					elseif q.cdmath.elementCount == dim then
						return z.A, z.B
					else
						error(q.cdmath.elementCount.." Not support number system.")
					end
				else
					error(q.cdmath.elementCount .. " " .. tostring(dim) .. " " .. tostring((type(z)==type({}))and z.numberType or '') .." 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
					mw.log(q.cdmath.globalNumberType, "toCayleyDicksonNumber in ", str)
					mw.log(q.cdmath.globalNumberType, "toCayleyDicksonNumber", dim, q.cdmath.elementCount)
					if q.cdmath.elementCount > dim then
						return q.cdmath.getCayleyDicksonNumber(q.cdmath.toSnumber(tostring(str)), q.cdmath.toSnumber("0"))
					elseif q.cdmath.elementCount == dim then
						return q.cdmath.getCayleyDicksonNumber(str.A, str.B)
					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.globalNumberType,"getCayleyDicksonNumber in A=",a, ((type(a)==type({}))and a or{}).numberType)
			mw.log("  ",q.cdmath.globalNumberType,"getCayleyDicksonNumber in B=",b, ((type(b)==type({}))and b or{}).numberType)
			CayleyDicksonNumber.A = q.cdmath.toSnumber(a)
			CayleyDicksonNumber.B = q.cdmath.toSnumber(b)
			if not CayleyDicksonNumber.A then CayleyDicksonNumber.A = q.cdmath.toSnumber("0") end
			if not CayleyDicksonNumber.B then CayleyDicksonNumber.B = q.cdmath.toSnumber("0") end
			mw.log("  ",q.cdmath.globalNumberType,"toSnumber A=",CayleyDicksonNumber.A, (CayleyDicksonNumber.A or{}).numberType)
			mw.log("  ",q.cdmath.globalNumberType,"toSnumber B=",CayleyDicksonNumber.B, (CayleyDicksonNumber.B or{}).numberType)
			CayleyDicksonNumber.numberType = q.cdmath.globalNumberType
			mw.log("  ",q.cdmath.globalNumberType,"result=",CayleyDicksonNumber, (CayleyDicksonNumber or{}).numberType)
			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")

			q.cdmath.elements = {}
			local unit_list = q.cdmath.mathlib.elements or{}
			q.cdmath.elementCount = (#unit_list)*2
			q.cdmath.globalNumberType = tostring(q.cdmath.elementCount).."-onion"
			
			mw.log("globalNumberType",q.cdmath.globalNumberType)
			
			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