跳转到内容

模組:Complex Number/CayleyDickson

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

这是本页的一个历史版本,由A2569875留言 | 贡献2022年4月23日 (六) 11:40 凯莱-迪克森结构编辑。这可能和当前版本存在着巨大的差异。

(差异) ←上一修订 | 最后版本 (差异) | 下一修订→ (差异)

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
p.cdmath={
	abs=function(z)
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		local A_len, B_len = p.cdmath.mathlib.abs(A), p.cdmath.mathlib.abs(B)
		return math.sqrt( A_len * A_len + B_len * B_len )
	end,

	conjugate=function(z)
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		return p.cdmath.getCayleyDicksonNumber(p.cdmath.mathlib.conjugate(A), -B) 
	end,
	re=function(z)
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		return p.cdmath.mathlib.re(A)
	end,
	im=function(z) 
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		return p.cdmath.mathlib.im(A)
	end,
	inverse=function(z)
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		local A_up, B_up = p.cdmath.mathlib.conjugate(A), -B
		local A_len, B_len = p.cdmath.mathlib.abs(A), p.cdmath.mathlib.abs(B)
		local div_down = ( A_len * A_len + B_len * B_len )
		return p.cdmath.getCayleyDicksonNumber(A_up / div_down, B_up / div_down)
	end,
	
	sqrt=function(z)
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		local s_zero = p.cdmath.toSnumber("0")
		if A == s_zero then 
			return p.omath.getOctonionNumberQ(p.cdmath.mathlib.sqrt(A), p.cdmath.toSnumber("0"))
		end
		return p.cdmath.pow(z, 0.5)
	end,

	asinh=function(z)
		local _one = p.cdmath.getCayleyDicksonNumber("1", "0")
		local u = p.cdmath.getCayleyDicksonNumber(p.cdmath.readCayleyDicksonNumberCDpart(z))
		return p.cdmath.elog( u + p.cdmath.sqrt( u * u + _one ) )
	end,
	acosh=function(z)
		local _one = p.cdmath.getCayleyDicksonNumber("1", "0")
		local u = p.cdmath.getCayleyDicksonNumber(p.cdmath.readCayleyDicksonNumberCDpart(z))
		return p.cdmath.elog( u + p.cdmath.sqrt( u + _one ) * p.cdmath.sqrt( u - _one ) )
	end,
	atanh=function(z)
		local _one = p.cdmath.getCayleyDicksonNumber("1", "0")
		local u = p.cdmath.getCayleyDicksonNumber(p.cdmath.readCayleyDicksonNumberCDpart(z))
		return ( p.cdmath.elog( _one + u ) - p.cdmath.elog( _one - u ) ) / 2
	end,
	acoth=function(z)
		local _one = p.cdmath.getCayleyDicksonNumber("1", "0")
		local u = p.cdmath.getCayleyDicksonNumber(p.cdmath.readCayleyDicksonNumberCDpart(z))
		return ( p.cdmath.elog( _one + p.cdmath.inverse(u) ) - p.cdmath.elog( _one - p.cdmath.inverse(u) ) ) / 2
	end,

	dot = function (op1, op2) 
		local nonL1, valL1 = p.cdmath.readCayleyDicksonNumberCDpart(op1)
		local nonL2, valL2 = p.cdmath.readCayleyDicksonNumberCDpart(op2)
		return p.cdmath.mathlib.dot(nonL1, nonL2) + p.cdmath.mathlib.dot(valL1, valL2)
	end,
	scalarPart=function(z)
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		return p.cdmath.getCayleyDicksonNumber(p.cdmath.toSnumber(tostring(p.cdmath.mathlib.re(A))), p.cdmath.toSnumber("0"))
	end,
	vectorPart=function(z)
		return p.cdmath.nonRealPart(z)
	end,

	nonRealPart=function(z) 
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		return p.cdmath.getCayleyDicksonNumber(p.cdmath.mathlib.nonRealPart(A), B) 
	end,
	sgn=function(z)
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		local A_len, B_len = p.cdmath.mathlib.abs(A), p.cdmath.mathlib.abs(B)
		local length = math.sqrt( A_len * A_len + B_len * B_len )
		if length <= 0 then return p.cdmath.getCayleyDicksonNumber(p.cdmath.toSnumber("0"),p.cdmath.toSnumber("0")) end
		return z / length
	end,
	arg=function(z) --TODO: verify
		local A, B = p.cdmath.readCayleyDicksonNumberCDpart(z)
		local A_len, B_len = p.cdmath.mathlib.abs(A), p.cdmath.mathlib.abs(B)
		local length = math.sqrt( A_len * A_len + B_len * B_len )
		return math.acos( p.cdmath.mathlib.re(A) / length )
	end,

	exp=function(z) --Cayley-Dickson construction
		local u = p.cdmath.nonRealPart(z)
		return ( (p.cdmath.sgn(u) * math.sin(p.cdmath.abs(u))) + math.cos(p.cdmath.abs(u))) * math.exp(p.cdmath.re(z))
	end,
	elog=function(z) --Cayley-Dickson construction
		local u = p.cdmath.nonRealPart(z)
		mw.log(p.cdmath.arg(z))
		return p.cdmath.sgn(u)*p.cdmath.arg(z)+math.log(p.cdmath.abs(z))
	end,
	log=function(z,basez)
		if basez~=nil then return p.cdmath.elog(basez) * p.cdmath.inverse(p.cdmath.elog(z)) end
		return p.cdmath.elog(z)
	end,
	pow=function(op1,op2)
		local _zero = p.cdmath.getCayleyDicksonNumber("0", "0")
		local a = p.cdmath.getCayleyDicksonNumber(p.cdmath.readCayleyDicksonNumberCDpart(op1))
		local z = p.cdmath.getCayleyDicksonNumber(p.cdmath.readCayleyDicksonNumberCDpart(op2))
		a:clean();z:clean();
		if a.B == _zero and z.B == _zero then 
			return p.cdmath.getOctonionNumberQ(p.cdmath.mathlib.pow(a.A, z.A), p.cdmath.toSnumber("0"))
		end
		return p.cdmath.exp(z * p.cdmath.elog(a)):clean()
	end,

	
	readCayleyDicksonNumberCDpart = function(z)
		if type(z) == type({}) then --if already be complex number, don't run string find.
			if z.numberType == "complex" then
				if p.cdmath.elementCount() >= 2 then
					return p.cdmath.toSnumber(z), p.cdmath.toSnumber("0")
				else
					return p.cdmath.toSnumber(tostring(p.cdmath.mathlib.re(z))), p.cdmath.toSnumber(tostring(p.cdmath.mathlib.im(z)))
				end
			elseif z.numberType == "quaternion" then
				if p.cdmath.elementCount() >= 4 then
					return p.cdmath.toSnumber(z), p.cdmath.toSnumber("0")
				else
					error("Can not divide into 2 parts.")
				end
			elseif z.numberType == "octonion" then
				if p.cdmath.elementCount() >= 8 then
					return p.cdmath.toSnumber(z), p.cdmath.toSnumber("0")
				else
					return z.nonL, z.valL
				end
			elseif z.numberType == tostring(p.cdmath.elementCount()).."-onion" then
				return z.A, z.B
			else
				error("Not support number system.")
			end
		elseif type(z) == type(0) then
			return p.cdmath.toSnumber(tostring(z)), p.cdmath.toSnumber("0")
		end
	end,
	CayleyDicksonNumberMeta = {
		__add = function (op1, op2) 
			local op1_a, op1_b = p.cdmath.readCayleyDicksonNumberCDpart(op1)
			local op2_a, op2_b = p.cdmath.readCayleyDicksonNumberCDpart(op2)
			return p.cdmath.getCayleyDicksonNumber(op1_a + op2_a, op1_b + op2_b) 
		end,
		__sub = function (op1, op2) 
			local op1_a, op1_b = p.cdmath.readCayleyDicksonNumberCDpart(op1)
			local op2_a, op2_b = p.cdmath.readCayleyDicksonNumberCDpart(op2)
			return p.cdmath.getCayleyDicksonNumber(op1_a - op2_a, op1_b - op2_b) 
		end,
		__mul = function (op1, op2) 
			local _a, _b = p.cdmath.readCayleyDicksonNumberCDpart(op1)
			local _c, _d = p.cdmath.readCayleyDicksonNumberCDpart(op2)
			local r_nonL = _a*_c - p.cdmath.mathlib.conjugate(_d)*_b
			local r_valL = _d*_a + _b*p.cdmath.mathlib.conjugate(_c)
			return p.cdmath.getCayleyDicksonNumber(r_nonL, r_valL) 
		end,
		__div = function (op1, op2) 
			local op_div = p.cdmath.inverse(op2)
			local _a, _b = p.cdmath.readCayleyDicksonNumberCDpart(op1)
			local _c, _d = p.cdmath.readCayleyDicksonNumberCDpart(op_div)
			local r_nonL = _a*_c - p.cdmath.mathlib.conjugate(_d)*_b
			local r_valL = _d*_a + _b*p.cdmath.mathlib.conjugate(_c)
			return p.cdmath.getCayleyDicksonNumber(r_nonL, r_valL) 
		end,
		__mod = function (op1, op2) 
			local x = p.cdmath.readComplexNumber(op1)
			local y = p.cdmath.readComplexNumber(op2)
			return x - y * qmath.floor(x / y) 
		end,
		__unm = function (this)
			return p.cdmath.getCayleyDicksonNumber(-this.A, -this.B) 
		end,
		__eq = function (op1, op2)
			return op1.A == op2.A and op1.B == op2.B
		end,
	},

	mathlib=cmath,
	toSnumber=cmath.constructor,
	elementCount = function() return #(p.cdmath.elements or {}) end,
	getCayleyDicksonNumber = function(a,b)
		CayleyDicksonNumber = {}
		setmetatable(CayleyDicksonNumber,p.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
		CayleyDicksonNumber.A = p.cdmath.toSnumber(a)
		CayleyDicksonNumber.B = p.cdmath.toSnumber(b)
		CayleyDicksonNumber.numberType = tostring(p.cdmath.elementCount()).."-onion"
		return CayleyDicksonNumber
	end,

	init = function(math_lib)
		if type(math_lib)==type({})then
			p.cdmath.mathlib = math_lib.init()
			p.cdmath.toSnumber = p.cdmath.mathlib.constructor
		end
		--p.omath.pi = p.cdmath.mathlib.pi
		--p.omath["π"] = p.omath.getOctonionNumber(math.pi, 0, 0, 0, 0, 0, 0, 0)
		--p.omath["°"] = p.omath.getOctonionNumber(math.pi/180, 0, 0, 0, 0, 0, 0, 0)
		--p.omath.e = p.omath.getOctonionNumber(math.exp(1), 0, 0, 0, 0, 0, 0, 0)
		--p.omath.nan = p.omath.getOctonionNumber(tonumber("nan"), tonumber("nan"), tonumber("nan"), tonumber("nan"), tonumber("nan"), tonumber("nan"), tonumber("nan"), tonumber("nan")) 
		--p.omath.zero = p.omath.getOctonionNumber(0, 0, 0, 0, 0, 0, 0, 0) 
		--p.omath.one = p.omath.getOctonionNumber(1, 0, 0, 0, 0, 0, 0, 0) 
		--p.omath[-1] = p.omath.getOctonionNumber(-1, 0, 0, 0, 0, 0, 0, 0) 

	--	p.omath[0],p.omath[1] = p.omath.zero,p.omath.one
		p.cdmath.numberType = comp_lib._numberType
		p.cdmath.elements = {}
		for i=1,#(p.cdmath.mathlib.elements or{}) do p.cdmath.elements[#(p.cdmath.elements)+1] = p.cdmath.getCayleyDicksonNumber(p.cdmath.mathlib.elements[i],"0")end
		for i=1,#(p.cdmath.mathlib.elements or{}) do p.cdmath.elements[#(p.cdmath.elements)+1] = p.cdmath.getCayleyDicksonNumber("0",p.cdmath.mathlib.elements[i])end
		--p.cdmath.constructor = p.omath.toCDNumber
		return p.cdmath
	end

}
return p