-
Notifications
You must be signed in to change notification settings - Fork 0
/
complex.lua
94 lines (81 loc) · 2.58 KB
/
complex.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
---------------------
-- Complex Numbers --
---------------------
local Complex = {}
Complex.__index = Complex
function Complex.new(a,b)
return setmetatable({
real = a or 0,
imag = b or 0
},Complex)
end
local function isComplex(z)
return type(z) == 'table' and type(z.real) == 'number' and type(z.imag) == 'number'
end
local function sgn(x)
if x==0 then
return 0
elseif x<0 then
return -1
else
return 1
end
end
function Complex.__tostring(z)
return z.real.." + "..z.imag.." i"
end
function Complex.__add(a,b)
if type(a)=='number' then
return Complex.new(a+b.real,b.imag)
elseif type(b)=='number' then
return Complex.new(a.real+b,a.imag)
else
assert(isComplex(a) and isComplex(b), "Add: wrong argument types (<complex> or <number> expected)")
return Complex.new(a.real+b.real,a.imag+b.imag)
end
end
function Complex.__sub(a,b)
if type(a)=='number' then
return Complex.new(a-b.real,-b.imag)
elseif type(b)=='number' then
return Complex.new(a.real-b,a.imag)
else
assert(isComplex(a) and isComplex(b), "Sub: wrong argument types (<complex> or <number> expected)")
return Complex.new(a.real-b.real,a.imag-b.imag)
end
end
function Complex.__mul(a,b)
if type(a)=='number' then
return Complex.new(a*b.real,a*b.imag)
elseif type(b)=='number' then
return Complex.new(a.real*b,a.imag*b)
else
assert(isComplex(a) and isComplex(b), "Mul: wrong argument types (<complex> or <number> expected)")
return Complex.new(a.real*b.real-a.imag*b.imag,a.real*b.imag+a.imag*b.real)
end
end
function Complex.__div(a,b)
if type(a)=='number' then
return Complex.new(a*b.real/(b.real*b.real+b.imag*b.imag),-a*b.imag/(b.real*b.real+b.imag*b.imag))
elseif type(b)=='number' then
return Complex.new(a.real/b,a.imag/b)
else
assert(isComplex(a) and isComplex(b), "Div: wrong argument types (<complex> or <number> expected)")
return Complex.new((a.real*b.real+a.imag*b.imag)/(b.real*b.real+b.imag*b.imag),
(a.imag*b.real-a.real*b.imag)/(b.real*b.real+b.imag*b.imag))
end
end
function Complex:arg()
return math.atan2(self.imag,self.real)
end
function Complex:abs()
return math.sqrt(self.real*self.real+self.imag*self.imag)
end
function Complex:sqrt()
local sqrtR = math.sqrt(self:abs())
local phi = math.atan2(self.imag,self.real)
return Complex.new(sqrtR*math.cos(phi/2),sqrtR*math.sin(phi/2))
end
return Complex
---------------------
---------------------