Class: Complex

Inherits:
Numeric show all
Defined in:
opal/opal/corelib/complex.rb

Constant Summary

I =
new(0, 1)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Numeric

#%, #+@, #<=>, #[], #__coerced__, #ceil, #clone, #div, #divmod, #dup, #floor, #i, #integer?, #negative?, #nonzero?, #positive?, #round, #to_c, #to_int, #truncate, #zero?

Methods included from Comparable

#<, #<=, #>, #>=, #between?, normalize

Constructor Details

#initialize(real, imag = 0) ⇒ Complex

Returns a new instance of Complex



26
27
28
29
# File 'opal/opal/corelib/complex.rb', line 26

def initialize(real, imag = 0)
  @real = real
  @imag = imag
end

Instance Attribute Details

#imagObject (readonly) Also known as: imaginary

Returns the value of attribute imag



24
25
26
# File 'opal/opal/corelib/complex.rb', line 24

def imag
  @imag
end

#realObject (readonly)

Returns the value of attribute real



24
25
26
# File 'opal/opal/corelib/complex.rb', line 24

def real
  @real
end

Class Method Details

.polar(r, theta = 0) ⇒ Object



16
17
18
19
20
21
22
# File 'opal/opal/corelib/complex.rb', line 16

def self.polar(r, theta = 0)
  unless Numeric === r && r.real? && Numeric === theta && theta.real?
    raise TypeError, 'not a real'
  end

  new(r * Math.cos(theta), r * Math.sin(theta))
end

.rect(real, imag = 0) ⇒ Object



4
5
6
7
8
9
10
# File 'opal/opal/corelib/complex.rb', line 4

def self.rect(real, imag = 0)
  unless Numeric === real && real.real? && Numeric === imag && imag.real?
    raise TypeError, 'not a real'
  end

  new(real, imag)
end

.rectangularObject



13
14
15
16
17
18
19
# File 'opal/opal/corelib/complex.rb', line 13

def self.rect(real, imag = 0)
  unless Numeric === real && real.real? && Numeric === imag && imag.real?
    raise TypeError, 'not a real'
  end

  new(real, imag)
end

Instance Method Details

#*(other) ⇒ Object



75
76
77
78
79
80
81
82
83
84
# File 'opal/opal/corelib/complex.rb', line 75

def *(other)
  if Complex === other
    Complex(@real * other.real - @imag * other.imag,
            @real * other.imag + @imag * other.real)
  elsif Numeric === other && other.real?
    Complex(@real * other, @imag * other)
  else
    __coerced__ :*, other
  end
end

#**(other) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'opal/opal/corelib/complex.rb', line 101

def **(other)
  if other == 0
    return Complex.new(1, 0)
  end

  if Complex === other
    r, theta = polar
    ore      = other.real
    oim      = other.imag
    nr       = Math.exp(ore * Math.log(r) - oim * theta)
    ntheta   = theta * ore + oim * Math.log(r)

    Complex.polar(nr, ntheta)
  elsif Integer === other
    if other > 0
      x = self
      z = x
      n = other - 1

      while n != 0
        while (div, mod = n.divmod(2); mod == 0)
          x = Complex(x.real * x.real - x.imag * x.imag, 2 * x.real * x.imag)
          n = div
        end

        z *= x
        n -= 1
      end

      z
    else
      (Rational.new(1, 1) / self) ** -other
    end
  elsif Float === other || Rational === other
    r, theta = polar

    Complex.polar(r ** other, theta * other)
  else
    __coerced__ :**, other
  end
end

#+(other) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'opal/opal/corelib/complex.rb', line 55

def +(other)
  if Complex === other
    Complex(@real + other.real, @imag + other.imag)
  elsif Numeric === other && other.real?
    Complex(@real + other, @imag)
  else
    __coerced__ :+, other
  end
end

#-(other) ⇒ Object



65
66
67
68
69
70
71
72
73
# File 'opal/opal/corelib/complex.rb', line 65

def -(other)
  if Complex === other
    Complex(@real - other.real, @imag - other.imag)
  elsif Numeric === other && other.real?
    Complex(@real - other, @imag)
  else
    __coerced__ :-, other
  end
end

#-@Object



51
52
53
# File 'opal/opal/corelib/complex.rb', line 51

def -@
  Complex(-@real, -@imag)
end

#/(other) ⇒ Object Also known as: divide, quo



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'opal/opal/corelib/complex.rb', line 86

def /(other)
  if Complex === other
    if (Number === @real && @real.nan?) || (Number === @imag && @imag.nan?) ||
       (Number === other.real && other.real.nan?) || (Number === other.imag && other.imag.nan?)
      Complex.new(Float::NAN, Float::NAN)
    else
      self * other.conj / other.abs2
    end
  elsif Numeric === other && other.real?
    Complex(@real.quo(other), @imag.quo(other))
  else
    __coerced__ :/, other
  end
end

#==(other) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'opal/opal/corelib/complex.rb', line 41

def ==(other)
  if Complex === other
    @real == other.real && @imag == other.imag
  elsif Numeric === other && other.real?
    @real == other && @imag == 0
  else
    other == self
  end
end

#absObject Also known as: magnitude



143
144
145
# File 'opal/opal/corelib/complex.rb', line 143

def abs
  Math.hypot(@real, @imag)
end

#abs2Object



147
148
149
# File 'opal/opal/corelib/complex.rb', line 147

def abs2
  @real * @real + @imag * @imag
end

#angleObject Also known as: arg



151
152
153
# File 'opal/opal/corelib/complex.rb', line 151

def angle
  Math.atan2(@imag, @real)
end

#coerce(other) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'opal/opal/corelib/complex.rb', line 31

def coerce(other)
  if Complex === other
    [other, self]
  elsif Numeric === other && other.real?
    [Complex.new(other, 0), self]
  else
    raise TypeError, "#{other.class} can't be coerced into Complex"
  end
end

#conjObject Also known as: conjugate



157
158
159
# File 'opal/opal/corelib/complex.rb', line 157

def conj
  Complex(@real, -@imag)
end

#denominatorObject



163
164
165
# File 'opal/opal/corelib/complex.rb', line 163

def denominator
  @real.denominator.lcm(@imag.denominator)
end

#eql?(other) ⇒ Boolean

Returns:



169
170
171
# File 'opal/opal/corelib/complex.rb', line 169

def eql?(other)
  Complex === other && @real.class == @imag.class && self == other
end

#fdiv(other) ⇒ Object



173
174
175
176
177
178
179
# File 'opal/opal/corelib/complex.rb', line 173

def fdiv(other)
  unless Numeric === other
    raise TypeError, "#{other.class} can't be coerced into Complex"
  end

  self / other
end

#hashObject



181
182
183
# File 'opal/opal/corelib/complex.rb', line 181

def hash
  "Complex:#@real:#@imag"
end

#inspectObject



187
188
189
# File 'opal/opal/corelib/complex.rb', line 187

def inspect
  "(#{to_s})"
end

#numeratorObject



193
194
195
196
197
198
# File 'opal/opal/corelib/complex.rb', line 193

def numerator
  d = denominator

  Complex(@real.numerator * (d / @real.denominator),
          @imag.numerator * (d / @imag.denominator))
end

#polarObject



202
203
204
# File 'opal/opal/corelib/complex.rb', line 202

def polar
  [abs, arg]
end

#rationalize(eps = undefined) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'opal/opal/corelib/complex.rb', line 208

def rationalize(eps = undefined)
  %x{
    if (arguments.length > 1) {
      #{raise ArgumentError, "wrong number of arguments (#{`arguments.length`} for 0..1)"};
    }
  }

  if @imag != 0
    raise RangeError, "can't' convert #{self} into Rational"
  end

  real.rationalize(eps)
end

#real?Boolean

Returns:



222
223
224
# File 'opal/opal/corelib/complex.rb', line 222

def real?
  false
end

#rectObject Also known as: rectangular



226
227
228
# File 'opal/opal/corelib/complex.rb', line 226

def rect
  [@real, @imag]
end

#to_fObject



232
233
234
235
236
237
238
# File 'opal/opal/corelib/complex.rb', line 232

def to_f
  unless @imag == 0
    raise RangeError, "can't convert #{self} into Float"
  end

  @real.to_f
end

#to_iObject



240
241
242
243
244
245
246
# File 'opal/opal/corelib/complex.rb', line 240

def to_i
  unless @imag == 0
    raise RangeError, "can't convert #{self} into Integer"
  end

  @real.to_i
end

#to_rObject



248
249
250
251
252
253
254
# File 'opal/opal/corelib/complex.rb', line 248

def to_r
  unless @imag == 0
    raise RangeError, "can't convert #{self} into Rational"
  end

  @real.to_r
end

#to_sObject



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'opal/opal/corelib/complex.rb', line 256

def to_s
  result = @real.inspect

  if (Number === @imag && @imag.nan?) || @imag.positive?
    result += ?+
  else
    result += ?-
  end

  result += @imag.abs.inspect

  if Number === @imag && (@imag.nan? || @imag.infinite?)
    result += ?*
  end

  result + ?i
end