1class Complex < Numeric 2 def self.polar(abs, arg = 0) 3 Complex(abs * Math.cos(arg), abs * Math.sin(arg)) 4 end 5 6 def inspect 7 "(#{to_s})" 8 end 9 10 def to_s 11 "#{real}#{'+' unless imaginary < 0}#{imaginary}i" 12 end 13 14 def +@ 15 Complex(real, imaginary) 16 end 17 18 def -@ 19 Complex(-real, -imaginary) 20 end 21 22 def +(rhs) 23 if rhs.is_a? Complex 24 Complex(real + rhs.real, imaginary + rhs.imaginary) 25 elsif rhs.is_a? Numeric 26 Complex(real + rhs, imaginary) 27 end 28 end 29 30 def -(rhs) 31 if rhs.is_a? Complex 32 Complex(real - rhs.real, imaginary - rhs.imaginary) 33 elsif rhs.is_a? Numeric 34 Complex(real - rhs, imaginary) 35 end 36 end 37 38 def *(rhs) 39 if rhs.is_a? Complex 40 Complex(real * rhs.real - imaginary * rhs.imaginary, real * rhs.imaginary + rhs.real * imaginary) 41 elsif rhs.is_a? Numeric 42 Complex(real * rhs, imaginary * rhs) 43 end 44 end 45 46 def /(rhs) 47 if rhs.is_a? Complex 48 __div__(rhs) 49 elsif rhs.is_a? Numeric 50 Complex(real / rhs, imaginary / rhs) 51 end 52 end 53 alias_method :quo, :/ 54 55 def ==(rhs) 56 if rhs.is_a? Complex 57 real == rhs.real && imaginary == rhs.imaginary 58 elsif rhs.is_a? Numeric 59 imaginary == 0 && real == rhs 60 end 61 end 62 63 def abs 64 Math.hypot imaginary, real 65 end 66 alias_method :magnitude, :abs 67 68 def abs2 69 real * real + imaginary * imaginary 70 end 71 72 def arg 73 Math.atan2 imaginary, real 74 end 75 alias_method :angle, :arg 76 alias_method :phase, :arg 77 78 def conjugate 79 Complex(real, -imaginary) 80 end 81 alias_method :conj, :conjugate 82 83 def fdiv(numeric) 84 Complex(real.to_f / numeric, imaginary.to_f / numeric) 85 end 86 87 def polar 88 [abs, arg] 89 end 90 91 def real? 92 false 93 end 94 95 def rectangular 96 [real, imaginary] 97 end 98 alias_method :rect, :rectangular 99 100 def to_r 101 raise RangeError.new "can't convert #{to_s} into Rational" unless imaginary.zero? 102 Rational(real, 1) 103 end 104 105 alias_method :imag, :imaginary 106 107 [Fixnum, Float].each do |cls| 108 [:+, :-, :*, :/, :==].each do |op| 109 cls.instance_eval do 110 original_operator_name = :"__original_operator_#{op}_complex" 111 alias_method original_operator_name, op 112 define_method op do |rhs| 113 if rhs.is_a? Complex 114 Complex(self).__send__(op, rhs) 115 else 116 __send__(original_operator_name, rhs) 117 end 118 end 119 end 120 end 121 end 122end 123