Class: Complex

Inherits:
Numeric show all
Defined in:
lib/complex.rb

Overview

The complex number class. See complex.rb for an overview.

Constant Summary collapse

I =

I is the imaginary number. It exists at point (0,1) on the complex plane.

Complex(0,1)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Numeric

#im

Constructor Details

#initialize(a, b) ⇒ Complex

Returns a new instance of Complex.

Raises:

  • (TypeError)


126
127
128
129
130
131
132
133
# File 'lib/complex.rb', line 126

def initialize(a, b)
  raise TypeError, "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric
  raise TypeError, "`#{a.inspect}' for 1st arg" if a.kind_of? Complex
  raise TypeError, "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric
  raise TypeError, "`#{b.inspect}' for 2nd arg" if b.kind_of? Complex
  @real = a
  @image = b
end

Instance Attribute Details

#imageObject (readonly) Also known as: imag

The imaginary part of a complex number.



407
408
409
# File 'lib/complex.rb', line 407

def image
  @image
end

#realObject (readonly)

The real part of a complex number.



404
405
406
# File 'lib/complex.rb', line 404

def real
  @real
end

Class Method Details

.generic?(other) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


106
107
108
109
110
# File 'lib/complex.rb', line 106

def Complex.generic?(other) # :nodoc:
  other.kind_of?(Integer) or
  other.kind_of?(Float) or
  (defined?(Rational) and other.kind_of?(Rational))
end

.new!(a, b = 0) ⇒ Object

Creates a Complex number a+bi.



122
123
124
# File 'lib/complex.rb', line 122

def Complex.new!(a, b=0)
  new(a,b)
end

.polar(r, theta) ⇒ Object

Creates a Complex number in terms of r (radius) and theta (angle).



115
116
117
# File 'lib/complex.rb', line 115

def Complex.polar(r, theta)
  Complex(r*Math.cos(theta), r*Math.sin(theta))
end

Instance Method Details

#%(other) ⇒ Object

Remainder after division by a real or complex number.



245
246
247
248
249
250
251
252
253
254
# File 'lib/complex.rb', line 245

def % (other)
  if other.kind_of?(Complex)
    Complex(@real % other.real, @image % other.image)
  elsif Complex.generic?(other)
    Complex(@real % other, @image % other)
  else
    x , y = other.coerce(self)
    x % y
  end
end

#*(other) ⇒ Object

Multiplication with real or complex number.



170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/complex.rb', line 170

def * (other)
  if other.kind_of?(Complex)
    re = @real*other.real - @image*other.image
    im = @real*other.image + @image*other.real
    Complex(re, im)
  elsif Complex.generic?(other)
    Complex(@real * other, @image * other)
  else
    x , y = other.coerce(self)
    x * y
  end
end

#**(other) ⇒ Object

Raise this complex number to the given (real or complex) power.



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/complex.rb', line 200

def ** (other)
  if other == 0
    return Complex(1)
  end
  if other.kind_of?(Complex)
    r, theta = polar
    ore = other.real
    oim = other.image
    nr = Math.exp!(ore*Math.log!(r) - oim * theta)
    ntheta = theta*ore + oim*Math.log!(r)
    Complex.polar(nr, ntheta)
  elsif other.kind_of?(Integer)
    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.image*x.image, 2*x.real*x.image)
   n = div
 end
 z *= x
 n -= 1
	end
	z
    else
	if defined? Rational
 (Rational(1) / self) ** -other
	else
 self ** Float(other)
	end
    end
  elsif Complex.generic?(other)
    r, theta = polar
    Complex.polar(r**other, theta*other)
  else
    x, y = other.coerce(self)
    x**y
  end
end

#+(other) ⇒ Object

Addition with real or complex number.



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/complex.rb', line 138

def + (other)
  if other.kind_of?(Complex)
    re = @real + other.real
    im = @image + other.image
    Complex(re, im)
  elsif Complex.generic?(other)
    Complex(@real + other, @image)
  else
    x , y = other.coerce(self)
    x + y
  end
end

#-(other) ⇒ Object

Subtraction with real or complex number.



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/complex.rb', line 154

def - (other)
  if other.kind_of?(Complex)
    re = @real - other.real
    im = @image - other.image
    Complex(re, im)
  elsif Complex.generic?(other)
    Complex(@real - other, @image)
  else
    x , y = other.coerce(self)
    x - y
  end
end

#/(other) ⇒ Object

Division by real or complex number.



186
187
188
189
190
191
192
193
194
195
# File 'lib/complex.rb', line 186

def / (other)
  if other.kind_of?(Complex)
    self*other.conjugate/other.abs2
  elsif Complex.generic?(other)
    Complex(@real/other, @image/other)
  else
    x, y = other.coerce(self)
    x/y
  end
end

#<=>(other) ⇒ Object

Compares the absolute values of the two numbers.



312
313
314
# File 'lib/complex.rb', line 312

def <=> (other)
  self.abs <=> other.abs
end

#==(other) ⇒ Object

Test for numerical equality (a == a + 0i).



319
320
321
322
323
324
325
326
327
# File 'lib/complex.rb', line 319

def == (other)
  if other.kind_of?(Complex)
    @real == other.real and @image == other.image
  elsif Complex.generic?(other)
    @real == other and @image == 0
  else
    other == self
  end
end

#absObject

Absolute value (aka modulus): distance from the zero point on the complex plane.



275
276
277
# File 'lib/complex.rb', line 275

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

#abs2Object

Square of the absolute value.



282
283
284
# File 'lib/complex.rb', line 282

def abs2
  @real*@real + @image*@image
end

#argObject Also known as: angle

Argument (angle from (1,0) on the complex plane).



289
290
291
# File 'lib/complex.rb', line 289

def arg
  Math.atan2!(@image, @real)
end

#coerce(other) ⇒ Object

Attempts to coerce other to a Complex number.



332
333
334
335
336
337
338
# File 'lib/complex.rb', line 332

def coerce(other)
  if Complex.generic?(other)
    return Complex.new!(other), self
  else
    super
  end
end

#conjugateObject Also known as: conj

Complex conjugate (z + z.conjugate = 2 * z.real).



304
305
306
# File 'lib/complex.rb', line 304

def conjugate
  Complex(@real, -@image)
end

#denominatorObject

FIXME



343
344
345
# File 'lib/complex.rb', line 343

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

#hashObject

Returns a hash code for the complex number.



386
387
388
# File 'lib/complex.rb', line 386

def hash
  @real.hash ^ @image.hash
end

#inspectObject

Returns “Complex(real, image)”.



393
394
395
# File 'lib/complex.rb', line 393

def inspect
  sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
end

#numeratorObject

FIXME



350
351
352
353
354
# File 'lib/complex.rb', line 350

def numerator
  cd = denominator
  Complex(@real.numerator*(cd/@real.denominator),
   @image.numerator*(cd/@image.denominator))
end

#polarObject

Returns the absolute value and the argument.



297
298
299
# File 'lib/complex.rb', line 297

def polar
  return abs, arg
end

#to_sObject

Standard string representation of the complex number.



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/complex.rb', line 359

def to_s
  if @real != 0
    if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
	if @image >= 0
 @real.to_s+"+("+@image.to_s+")i"
	else
 @real.to_s+"-("+(-@image).to_s+")i"
	end
    else
	if @image >= 0
 @real.to_s+"+"+@image.to_s+"i"
	else
 @real.to_s+"-"+(-@image).to_s+"i"
	end
    end
  else
    if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
	"("+@image.to_s+")i"
    else
	@image.to_s+"i"
    end
  end
end