[439] | 1 | class 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
|
---|
| 122 | end
|
---|