The complex number class. See complex.rb for an overview.
I is the imaginary number. It exists at point (0,1) on the
complex plane.
# File complex.rb, line 128
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
Remainder after division by a real or complex number.
# File complex.rb, line 247
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
Multiplication with real or complex number.
# File complex.rb, line 172
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
Raise this complex number to the given (real or complex) power.
# File complex.rb, line 202
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
Addition with real or complex number.
# File complex.rb, line 140
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
Subtraction with real or complex number.
# File complex.rb, line 156
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
Division by real or complex number.
# File complex.rb, line 188
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
Compares the absolute values of the two numbers.
# File complex.rb, line 314
def <=> (other)
self.abs <=> other.abs
end
Test for numerical equality (a == a + 0i).
# File complex.rb, line 321
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
Absolute value (aka modulus): distance from the zero point on the complex plane.
# File complex.rb, line 277
def abs
Math.hypot(@real, @image)
end
Square of the absolute value.
# File complex.rb, line 284
def abs2
@real*@real + @image*@image
end
Argument (angle from (1,0) on the complex plane).
# File complex.rb, line 291
def arg
Math.atan2!(@image, @real)
end
Attempts to coerce other to a Complex number.
# File complex.rb, line 334
def coerce(other)
if Complex.generic?(other)
return Complex.new!(other), self
else
super
end
end
Complex conjugate (z + z.conjugate = 2 *
z.real).
# File complex.rb, line 306
def conjugate
Complex(@real, -@image)
end
FIXME
# File complex.rb, line 345
def denominator
@real.denominator.lcm(@image.denominator)
end
Returns a hash code for the complex number.
# File complex.rb, line 388
def hash
@real.hash ^ @image.hash
end
Returns “Complex(real, image)”.
# File complex.rb, line 395
def inspect
sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
end
FIXME
# File complex.rb, line 352
def numerator
cd = denominator
Complex(@real.numerator*(cd/@real.denominator),
@image.numerator*(cd/@image.denominator))
end
Returns the absolute value and the argument.
# File complex.rb, line 299
def polar
return abs, arg
end
Standard string representation of the complex number.
# File complex.rb, line 361
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