зеркало из https://github.com/github/ruby.git
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:
Родитель
bed06ae87d
Коммит
c46774cdb3
187
lib/complex.rb
187
lib/complex.rb
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче