-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
- 9.1.0.0
- 9.0.5.0
- 9.0.4.0
- 9.0.3.0
- 9.0.1.0
- 9.0.0.0
- 9.0.0.0.rc2
- 9.0.0.0.rc1
- 9.0.0.0.pre2
- 9.0.0.0.pre1
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,363 @@ | ||
# Copyright (c) 2007-2014, Evan Phoenix and contributors | ||
# All rights reserved. | ||
# | ||
# Redistribution and use in source and binary forms, with or without | ||
# modification, are permitted provided that the following conditions are met: | ||
# | ||
# * Redistributions of source code must retain the above copyright notice, this | ||
# list of conditions and the following disclaimer. | ||
# * Redistributions in binary form must reproduce the above copyright notice | ||
# this list of conditions and the following disclaimer in the documentation | ||
# and/or other materials provided with the distribution. | ||
# * Neither the name of Rubinius nor the names of its contributors | ||
# may be used to endorse or promote products derived from this software | ||
# without specific prior written permission. | ||
# | ||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | ||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
# | ||
# complex.rb - | ||
# $Release Version: 0.5 $ | ||
# $Revision: 1.3 $ | ||
# $Date: 1998/07/08 10:05:28 $ | ||
# by Keiju ISHITSUKA(SHL Japan Inc.) | ||
# | ||
|
||
class Complex < Numeric | ||
|
||
# TODO(CS 7 Jan 15) we don't define all these methods yet | ||
|
||
#undef_method :% | ||
#undef_method :< | ||
#undef_method :<= | ||
#undef_method :<=> | ||
#undef_method :> | ||
#undef_method :>= | ||
#undef_method :between? | ||
#undef_method :div | ||
#undef_method :divmod | ||
#undef_method :floor | ||
#undef_method :ceil | ||
#undef_method :modulo | ||
#undef_method :remainder | ||
#undef_method :round | ||
#undef_method :step | ||
#undef_method :truncate | ||
#undef_method :i | ||
|
||
def self.convert(real, imag = undefined) | ||
if real.equal?(nil) || imag.equal?(nil) | ||
raise TypeError, "cannot convert nil into Complex" | ||
end | ||
|
||
real = real.to_c if real.kind_of?(String) | ||
imag = imag.to_c if imag.kind_of?(String) | ||
|
||
if real.kind_of?(Complex) && !real.imag.kind_of?(Float) && real.imag == 0 | ||
real = real.real | ||
end | ||
|
||
if imag.kind_of?(Complex) && !imag.imag.kind_of?(Float) && imag.imag == 0 | ||
imag = imag.real | ||
end | ||
|
||
if real.kind_of?(Complex) && !imag.kind_of?(Float) && imag == 0 | ||
return real | ||
end | ||
|
||
if undefined.equal?(imag) | ||
if real.kind_of?(Numeric) && !real.real? | ||
return real | ||
elsif !real.kind_of?(Numeric) | ||
return Rubinius::Type.coerce_to(real, Complex, :to_c) | ||
else | ||
imag = 0 | ||
end | ||
elsif real.kind_of?(Numeric) && imag.kind_of?(Numeric) && (!real.real? || !imag.real?) | ||
return real + imag * Complex.new(0, 1) | ||
end | ||
|
||
return real if Rubinius.mathn_loaded? && imag.equal?(0) | ||
rect(real, imag) | ||
end | ||
|
||
private_class_method :convert | ||
|
||
def Complex.generic?(other) # :nodoc: | ||
other.kind_of?(Integer) or | ||
other.kind_of?(Float) or | ||
(defined?(Rational) and other.kind_of?(Rational)) | ||
end | ||
|
||
def Complex.rect(real, imag=0) | ||
raise TypeError, 'not a real' unless check_real?(real) && check_real?(imag) | ||
new(real, imag) | ||
end | ||
class << self; alias_method :rectangular, :rect end | ||
|
||
def Complex.polar(r, theta=0) | ||
raise TypeError, 'not a real' unless check_real?(r) && check_real?(theta) | ||
|
||
Complex(r*Math.cos(theta), r*Math.sin(theta)) | ||
end | ||
|
||
def Complex.check_real?(obj) | ||
obj.kind_of?(Numeric) && obj.real? | ||
end | ||
private_class_method :check_real? | ||
|
||
def initialize(a, b = 0) | ||
@real = a | ||
@imag = b | ||
end | ||
|
||
def -@ | ||
Complex(-real, -imag) | ||
end | ||
|
||
def +(other) | ||
if other.kind_of?(Complex) | ||
Complex(real + other.real, imag + other.imag) | ||
elsif other.kind_of?(Numeric) && other.real? | ||
Complex(real + other, imag) | ||
else | ||
redo_coerced(:+, other) | ||
end | ||
end | ||
|
||
def -(other) | ||
if other.kind_of?(Complex) | ||
Complex(real - other.real, imag - other.imag) | ||
elsif other.kind_of?(Numeric) && other.real? | ||
Complex(real - other, imag) | ||
else | ||
redo_coerced(:-, other) | ||
end | ||
end | ||
|
||
def *(other) | ||
if other.kind_of?(Complex) | ||
Complex(real * other.real - imag * other.imag, | ||
real * other.imag + imag * other.real) | ||
elsif other.kind_of?(Numeric) && other.real? | ||
Complex(real * other, imag * other) | ||
else | ||
redo_coerced(:*, other) | ||
end | ||
end | ||
|
||
def divide(other) | ||
if other.kind_of?(Complex) | ||
self * other.conjugate / other.abs2 | ||
elsif other.kind_of?(Numeric) && other.real? | ||
Complex(real.quo(other), imag.quo(other)) | ||
else | ||
redo_coerced(:quo, other) | ||
end | ||
end | ||
|
||
alias_method :/, :divide | ||
alias_method :quo, :divide | ||
|
||
def ** (other) | ||
if !other.kind_of?(Float) && other == 0 | ||
return Complex(1) | ||
end | ||
if other.kind_of?(Complex) | ||
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 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.imag*x.imag, 2*x.real*x.imag) | ||
n = div | ||
end | ||
z *= x | ||
n -= 1 | ||
end | ||
z | ||
else | ||
if defined? Rational | ||
(Rational.new(1, 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 | ||
|
||
def abs | ||
Math.hypot(@real, @imag) | ||
end | ||
|
||
alias_method :magnitude, :abs | ||
|
||
def abs2 | ||
@real*@real + @imag*@imag | ||
end | ||
|
||
def arg | ||
Math.atan2(@imag, @real) | ||
end | ||
alias_method :angle, :arg | ||
alias_method :phase, :arg | ||
|
||
def polar | ||
[abs, arg] | ||
end | ||
|
||
def conjugate | ||
Complex(@real, -@imag) | ||
end | ||
alias conj conjugate | ||
|
||
def ==(other) | ||
if other.kind_of?(Complex) | ||
real == other.real && imag == other.imag | ||
elsif other.kind_of?(Numeric) && other.real? | ||
real == other && imag == 0 | ||
else | ||
other == self | ||
end | ||
end | ||
|
||
def eql?(other) | ||
other.kind_of?(Complex) and | ||
imag.class == other.imag.class and | ||
real.class == other.real.class and | ||
self == other | ||
end | ||
|
||
def coerce(other) | ||
if other.kind_of?(Numeric) && other.real? | ||
[Complex.new(other, 0), self] | ||
elsif other.kind_of?(Complex) | ||
[other, self] | ||
else | ||
raise TypeError, "#{other.class} can't be coerced into Complex" | ||
end | ||
end | ||
|
||
def denominator | ||
@real.denominator.lcm(@imag.denominator) | ||
end | ||
|
||
def numerator | ||
cd = denominator | ||
Complex(@real.numerator*(cd/@real.denominator), | ||
@imag.numerator*(cd/@imag.denominator)) | ||
end | ||
|
||
def real? | ||
false | ||
end | ||
|
||
def rect | ||
[@real, @imag] | ||
end | ||
|
||
alias_method :rectangular, :rect | ||
|
||
def to_f | ||
raise RangeError, "can't convert #{self} into Float" unless !imag.kind_of?(Float) && imag == 0 | ||
real.to_f | ||
end | ||
|
||
def to_i | ||
raise RangeError, "can't convert #{self} into Integer" unless !imag.kind_of?(Float) && imag == 0 | ||
real.to_i | ||
end | ||
|
||
def to_r | ||
raise RangeError, "can't' convert #{self} into Rational" unless !imag.kind_of?(Float) && imag == 0 | ||
real.to_r | ||
end | ||
|
||
def rationalize(eps = nil) | ||
raise RangeError, "can't' convert #{self} into Rational" unless !imag.kind_of?(Float) && imag == 0 | ||
real.rationalize(eps) | ||
end | ||
|
||
def to_s | ||
result = real.to_s | ||
|
||
if imag.kind_of?(Float) ? !imag.nan? && imag.negative? : imag < 0 | ||
result << "-" | ||
else | ||
result << "+" | ||
end | ||
|
||
imag_s = imag.abs.to_s | ||
result << imag_s | ||
|
||
unless imag_s[-1] =~ /\d/ | ||
result << "*" | ||
end | ||
|
||
result << "i" | ||
result | ||
end | ||
|
||
def hash | ||
@real.hash ^ @imag.hash | ||
end | ||
|
||
def inspect | ||
"(#{to_s})" | ||
end | ||
|
||
def fdiv(other) | ||
raise TypeError, "#{other.class} can't be coerced into Complex" unless other.is_a?(Numeric) | ||
|
||
# FIXME | ||
self / other | ||
end | ||
|
||
def marshal_dump | ||
ary = [real, imag] | ||
instance_variables.each do |ivar| | ||
ary.instance_variable_set(ivar, instance_variable_get(ivar)) | ||
end | ||
ary | ||
end | ||
|
||
private :marshal_dump | ||
|
||
def marshal_load(ary) | ||
@real, @imag = ary | ||
ary.instance_variables.each do |ivar| | ||
instance_variable_set(ivar, ary.instance_variable_get(ivar)) | ||
end | ||
self | ||
end | ||
|
||
I = Complex(0, 1) | ||
|
||
attr_reader :real | ||
attr_reader :imag | ||
alias_method :imaginary, :imag | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,4 +41,8 @@ def div(other) | |
self.__slash__(other).floor | ||
end | ||
|
||
def real? | ||
true | ||
end | ||
|
||
end |
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,2 @@ | ||
fails:Complex#** with Fixnum 0 returns Complex(1) | ||
fails:Complex#** with Float 0.0 returns Complex(1.0, 0.0) | ||
fails:Complex#** with Complex returns self raised to the given power | ||
fails:Complex#** with Integer returns self raised to the given power | ||
fails:Complex#** with Rational returns self raised to the given power | ||
fails:Complex#** with Object tries to coerce self into other |
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
fails:Complex#- with Complex subtracts both the real and imaginary components | ||
fails:Complex#- with Integer subtracts the real number from the real component of self | ||
fails:Complex#- with Object tries to coerce self into other | ||
fails:Complex#- passed Numeric which responds to #real? with true coerces the passed argument to the type of the real part and subtracts the resulting elements | ||
fails:Complex#- passed Numeric which responds to #real? with false coerces the passed argument to Complex and subtracts the resulting elements |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,2 @@ | ||
fails:Complex#* with Complex multiplies according to the usual rule for complex numbers: (a + bi) * (c + di) = ac - bd + (ad + bc)i | ||
fails:Complex#* with Integer multiplies both parts of self by the given Integer | ||
fails:Complex#* with Object tries to coerce self into other | ||
fails:Complex#* with a Numeric which responds to #real? with true multiples both parts of self by other | ||
fails:Complex#* with a Numeric which responds to #real? with true with a Numeric which responds to #real? with false coerces the passed argument to Complex and multiplies the resulting elements |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
fails:Complex#+ with Complex adds both the real and imaginary components | ||
fails:Complex#+ with Integer adds the real number to the real component of self | ||
fails:Complex#+ with Object tries to coerce self into other | ||
fails:Complex#+ passed Numeric which responds to #real? with true coerces the passed argument to the type of the real part and adds the resulting elements | ||
fails:Complex#+ passed Numeric which responds to #real? with false coerces the passed argument to Complex and adds the resulting elements |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1 @@ | ||
fails:Complex.polar returns a complex number in terms of radius and angle | ||
fails:Complex.polar raises a TypeError when given non real arguments | ||
fails:Complex#polar returns the absolute value and the argument |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,3 @@ | ||
fails:Complex#rationalize raises RangeError if self has non-zero imaginary part | ||
fails:Complex#rationalize raises RangeError if self has 0.0 imaginary part | ||
fails:Complex#rationalize returns a Rational if self has zero imaginary part | ||
fails:Complex#rationalize sends #rationalize to the real part | ||
fails:Complex#rationalize ignores a single argument | ||
fails:Complex#rationalize raises ArgumentError when passed more than one argument |
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1 @@ | ||
fails:Complex#to_f when the imaginary part is Fixnum 0 returns the result of sending #to_f to the real part | ||
fails:Complex#to_f when the imaginary part is Rational 0 returns the result of sending #to_f to the real part | ||
fails:Complex#to_f when the imaginary part responds to #== 0 with true returns the result of sending #to_f to the real part | ||
fails:Complex#to_f when the imaginary part is non-zero raises RangeError | ||
fails:Complex#to_f when the imaginary part is Float 0.0 raises RangeError |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1 @@ | ||
fails:Complex#to_i when the imaginary part is Fixnum 0 returns the result of sending #to_i to the real part | ||
fails:Complex#to_i when the imaginary part is Rational 0 returns the result of sending #to_i to the real part | ||
fails:Complex#to_i when the imaginary part responds to #== 0 with true returns the result of sending #to_i to the real part | ||
fails:Complex#to_i when the imaginary part is non-zero raises RangeError | ||
fails:Complex#to_i when the imaginary part is Float 0.0 raises RangeError |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1 @@ | ||
fails:Complex#to_r when the imaginary part is Fixnum 0 returns the result of sending #to_r to the real part | ||
fails:Complex#to_r when the imaginary part is Rational 0 returns the result of sending #to_r to the real part | ||
fails:Complex#to_r when the imaginary part responds to #== 0 with true returns the result of sending #to_r to the real part | ||
fails:Complex#to_r when the imaginary part is non-zero raises RangeError | ||
fails:Complex#to_r when the imaginary part is Float 0.0 raises RangeError |
This file was deleted.