Added RDoc comments. See comments at EOF for remaining issues.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
gsinclair 2003-02-04 03:47:42 +00:00
Родитель bed06ae87d
Коммит c46774cdb3
1 изменённых файлов: 149 добавлений и 38 удалений

Просмотреть файл

@ -5,48 +5,31 @@
# $Date: 1998/07/08 10:05:28 $
# by Keiju ISHITSUKA(SHL Japan Inc.)
#
# --
# Usage:
# class Complex < Numeric
# ----
#
# Complex(x, y) --> x + yi
# y.im --> 0 + yi
# complex.rb implements the Complex class for complex numbers. Additionally,
# some methods in other Numeric classes are redefined or added to allow greater
# interoperability with Complex numbers.
#
# Complex::polar
#
# Complex::+
# Complex::-
# Complex::*
# Complex::/
# Complex::**
# Complex::%
# Complex::divmod -- obsolete
# Complex::abs
# Complex::abs2
# Complex::arg
# Complex::polar
# Complex::conjugate
# Complex::<=>
# Complex::==
# Complex::to_f
# Complex::to_r
# Complex::to_s
#
# Complex::I
#
# Numeric::im
#
# Math.sqrt
# Math.exp
# Math.cos
# Math.sin
# Math.tan
# Math.log
# Math.log10
# Math.atan2
# Complex numbers can be created in the following manner:
# - <tt>Complex(a, b)</tt>
# - <tt>Complex.new(a, b)</tt>
# - <tt>Complex.polar(radius, theta)</tt>
#
# Additionally, note the following:
# - <tt>Complex::I</tt> (the mathematical constant <i>i</i>)
# - <tt>Numeric#im</tt> (e.g. <tt>5.im -> 0+5i</tt>)
#
# The following +Math+ module methods are redefined to handle Complex arguments.
# They will work as normal with non-Complex arguments.
# sqrt exp cos sin tan log log10 atan2
#
#
# Creates a Complex number. +a+ and +b+ should be Numeric. The result will be
# <tt>a+bi</tt>.
#
def Complex(a, b = 0)
if a.kind_of?(Complex) and b == 0
a
@ -63,21 +46,30 @@ def Complex(a, b = 0)
end
end
#
# The complex number class. See complex.rb for an overview.
#
class Complex < Numeric
@RCS_ID='-$Id: complex.rb,v 1.3 1998/07/08 10:05:28 keiju Exp keiju $-'
undef step
def Complex.generic?(other)
def Complex.generic?(other) # :nodoc:
other.kind_of?(Integer) or
other.kind_of?(Float) or
(defined?(Rational) and other.kind_of?(Rational))
end
#
# Creates a +Complex+ number in terms of +r+ (radius) and +theta+ (angle).
#
def Complex.polar(r, theta)
Complex(r*Math.cos(theta), r*Math.sin(theta))
end
#
# Creates a +Complex+ number <tt>a</tt>+<tt>b</tt><i>i</i>.
#
def initialize(a, b = 0)
raise "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric
raise "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric
@ -85,6 +77,9 @@ class Complex < Numeric
@image = b
end
#
# Addition with real or complex number.
#
def + (other)
if other.kind_of?(Complex)
re = @real + other.real
@ -98,6 +93,9 @@ class Complex < Numeric
end
end
#
# Subtraction with real or complex number.
#
def - (other)
if other.kind_of?(Complex)
re = @real - other.real
@ -111,6 +109,9 @@ class Complex < Numeric
end
end
#
# Multiplication with real or complex number.
#
def * (other)
if other.kind_of?(Complex)
re = @real*other.real - @image*other.image
@ -124,6 +125,9 @@ class Complex < Numeric
end
end
#
# Division by real or complex number.
#
def / (other)
if other.kind_of?(Complex)
self*other.conjugate/other.abs2
@ -135,6 +139,9 @@ class Complex < Numeric
end
end
#
# Raise this complex number to the given (real or complex) power.
#
def ** (other)
if other == 0
return Complex(1)
@ -177,6 +184,9 @@ class Complex < Numeric
end
end
#
# Remainder after division by a real or complex number.
#
def % (other)
if other.kind_of?(Complex)
Complex(@real % other.real, @image % other.image)
@ -188,6 +198,7 @@ class Complex < Numeric
end
end
#--
# def divmod(other)
# if other.kind_of?(Complex)
# rdiv, rmod = @real.divmod(other.real)
@ -200,31 +211,54 @@ class Complex < Numeric
# x.divmod(y)
# end
# end
#++
#
# Absolute value (aka modulus): distance from the zero point on the complex
# plane.
#
def abs
Math.sqrt!((@real*@real + @image*@image).to_f)
end
#
# Square of the absolute value.
#
def abs2
@real*@real + @image*@image
end
#
# Argument (angle from (1,0) on the complex plane).
#
def arg
Math.atan2(@image.to_f, @real.to_f)
end
#
# Returns the absolute value _and_ the argument.
#
def polar
return abs, arg
end
#
# Complex conjugate (<tt>z + z.conjugate = 2 * z.real</tt>).
#
def conjugate
Complex(@real, -@image)
end
#
# Compares the absolute values of the two numbers.
#
def <=> (other)
self.abs <=> other.abs
end
#
# Test for numerical equality (<tt>a == a + 0<i>i</i></tt>).
#
def == (other)
if other.kind_of?(Complex)
@real == other.real and @image == other.image
@ -236,6 +270,9 @@ class Complex < Numeric
end
end
#
# Attempts to coerce +other+ to a Complex number.
#
def coerce(other)
if Complex.generic?(other)
return Complex.new(other), self
@ -244,16 +281,25 @@ class Complex < Numeric
end
end
#
# FIXME
#
def denominator
@real.denominator.lcm(@image.denominator)
end
#
# FIXME
#
def numerator
cd = denominator
Complex(@real.numerator*(cd/@real.denominator),
@image.numerator*(cd/@image.denominator))
end
#
# Standard string representation of the complex number.
#
def to_s
if @real != 0
if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
@ -278,35 +324,65 @@ class Complex < Numeric
end
end
#
# Returns a hash code for the complex number.
#
def hash
@real.hash ^ @image.hash
end
#
# Returns "<tt>Complex(<i>real</i>, <i>image</i>)</tt>".
#
def inspect
sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
end
#
# +I+ is the imaginary number. It exists at point (0,1) on the complex plane.
#
I = Complex(0,1)
# The real part of a complex number.
attr :real
# The imaginary part of a complex number.
attr :image
end
#
# Numeric is a built-in class on which Fixnum, Bignum, etc., are based. Here
# some methods are added so that all number types can be treated to some extent
# as Complex numbers.
#
class Numeric
#
# Returns a Complex number <tt>(0,<i>self</i>)</tt>.
#
def im
Complex(0, self)
end
#
# The real part of a complex number, i.e. <i>self</i>.
#
def real
self
end
#
# The imaginary part of a complex number, i.e. 0.
#
def image
0
end
#
# See Complex#arg.
#
def arg
if self >= 0
return 0
@ -315,20 +391,28 @@ class Numeric
end
end
#
# See Complex#polar.
#
def polar
return abs, arg
end
#
# See Complex#conjugate (short answer: returns <i>self</i>).
#
def conjugate
self
end
end
class Fixnum
if not defined? Rational
alias power! **
end
# Redefined to handle a Complex argument.
def ** (other)
if self < 0
Complex.new(self) ** other
@ -367,6 +451,7 @@ module Math
alias log10! log10
alias atan2! atan2
# Redefined to handle a Complex argument.
def sqrt(z)
if Complex.generic?(z)
if z >= 0
@ -379,6 +464,7 @@ module Math
end
end
# Redefined to handle a Complex argument.
def exp(z)
if Complex.generic?(z)
exp!(z)
@ -387,14 +473,21 @@ module Math
end
end
#
# Hyperbolic cosine.
#
def cosh!(x)
(exp!(x) + exp!(-x))/2.0
end
#
# Hyperbolic sine.
#
def sinh!(x)
(exp!(x) - exp!(-x))/2.0
end
# Redefined to handle a Complex argument.
def cos(z)
if Complex.generic?(z)
cos!(z)
@ -404,6 +497,7 @@ module Math
end
end
# Redefined to handle a Complex argument.
def sin(z)
if Complex.generic?(z)
sin!(z)
@ -413,6 +507,7 @@ module Math
end
end
# Redefined to handle a Complex argument.
def tan(z)
if Complex.generic?(z)
tan!(z)
@ -421,6 +516,7 @@ module Math
end
end
# Redefined to handle a Complex argument.
def log(z)
if Complex.generic?(z) and z >= 0
log!(z)
@ -430,6 +526,7 @@ module Math
end
end
# Redefined to handle a Complex argument.
def log10(z)
if Complex.generic?(z)
log10!(z)
@ -438,6 +535,8 @@ module Math
end
end
# FIXME: I don't know what the point of this is. If you give it Complex
# arguments, it will fail.
def atan2(x, y)
if Complex.generic?(x) and Complex.generic?(y)
atan2!(x, y)
@ -446,10 +545,14 @@ module Math
end
end
#
# Hyperbolic arctangent.
#
def atanh!(x)
log((1.0 + x.to_f) / ( 1.0 - x.to_f)) / 2.0
end
# Redefined to handle a Complex argument.
def atan(z)
if Complex.generic?(z)
atan2!(z, 1)
@ -490,3 +593,11 @@ module Math
module_function :atanh!
end
# Documentation comments:
# - source: original (researched from pickaxe)
# - a couple of fixme's
# - Math module methods sinh! etc. a bit fuzzy. What exactly is the intention?
# - RDoc output for Bignum etc. is a bit short, with nothing but an
# (undocumented) alias. No big deal.