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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
class Complex < Numeric
def self.polar(abs, arg = 0)
Complex(abs * Math.cos(arg), abs * Math.sin(arg))
end
def inspect
"(#{to_s})"
end
def to_s
"#{real}#{'+' unless imaginary < 0}#{imaginary}i"
end
def +@
Complex(real, imaginary)
end
def -@
Complex(-real, -imaginary)
end
def +(rhs)
if rhs.is_a? Complex
Complex(real + rhs.real, imaginary + rhs.imaginary)
elsif rhs.is_a? Numeric
Complex(real + rhs, imaginary)
end
end
def -(rhs)
if rhs.is_a? Complex
Complex(real - rhs.real, imaginary - rhs.imaginary)
elsif rhs.is_a? Numeric
Complex(real - rhs, imaginary)
end
end
def *(rhs)
if rhs.is_a? Complex
Complex(real * rhs.real - imaginary * rhs.imaginary, real * rhs.imaginary + rhs.real * imaginary)
elsif rhs.is_a? Numeric
Complex(real * rhs, imaginary * rhs)
end
end
def /(rhs)
if rhs.is_a? Complex
__div__(rhs)
elsif rhs.is_a? Numeric
Complex(real / rhs, imaginary / rhs)
end
end
alias_method :quo, :/
def ==(rhs)
if rhs.is_a? Complex
real == rhs.real && imaginary == rhs.imaginary
elsif rhs.is_a? Numeric
imaginary == 0 && real == rhs
end
end
def abs
Math.hypot imaginary, real
end
alias_method :magnitude, :abs
def abs2
real * real + imaginary * imaginary
end
def arg
Math.atan2 imaginary, real
end
alias_method :angle, :arg
alias_method :phase, :arg
def conjugate
Complex(real, -imaginary)
end
alias_method :conj, :conjugate
def fdiv(numeric)
Complex(real.to_f / numeric, imaginary.to_f / numeric)
end
def polar
[abs, arg]
end
def real?
false
end
def rectangular
[real, imaginary]
end
alias_method :rect, :rectangular
def to_r
raise RangeError.new "can't convert #{to_s} into Rational" unless imaginary.zero?
Rational(real, 1)
end
alias_method :imag, :imaginary
[Integer, Float].each do |cls|
[:+, :-, :*, :/, :==].each do |op|
cls.instance_eval do
original_operator_name = :"__original_operator_#{op}_complex"
alias_method original_operator_name, op
define_method op do |rhs|
if rhs.is_a? Complex
Complex(self).__send__(op, rhs)
else
__send__(original_operator_name, rhs)
end
end
end
end
end
end
|