mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Initial revision
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
392296c12d
commit
3db12e8b23
225 changed files with 75935 additions and 0 deletions
308
lib/mathn.rb
Normal file
308
lib/mathn.rb
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
#
|
||||
# mathn.rb -
|
||||
# $Release Version: 0.5 $
|
||||
# $Revision: 1.1 $
|
||||
# $Date: 1997/07/03 04:43:47 $
|
||||
# by Keiju ISHITSUKA(SHL Japan Inc.)
|
||||
#
|
||||
# --
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
require "rational.rb"
|
||||
require "complex.rb"
|
||||
require "matrix.rb"
|
||||
|
||||
class Integer
|
||||
|
||||
def gcd2(int)
|
||||
a = self.abs
|
||||
b = int.abs
|
||||
a, b = b, a if a < b
|
||||
|
||||
pd_a = a.prime_division
|
||||
pd_b = b.prime_division
|
||||
|
||||
gcd = 1
|
||||
for pair in pd_a
|
||||
as = pd_b.assoc(pair[0])
|
||||
if as
|
||||
gcd *= as[0] ** [as[1], pair[1]].min
|
||||
end
|
||||
end
|
||||
return gcd
|
||||
end
|
||||
|
||||
def Integer.from_prime_division(pd)
|
||||
value = 1
|
||||
for prime, index in pd
|
||||
value *= prime**index
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
def prime_division
|
||||
ps = Prime.new
|
||||
value = self
|
||||
pv = []
|
||||
for prime in ps
|
||||
count = 0
|
||||
while (value1, mod = value.divmod(prime)
|
||||
mod) == 0
|
||||
value = value1
|
||||
count += 1
|
||||
end
|
||||
if count != 0
|
||||
pv.push [prime, count]
|
||||
end
|
||||
break if prime * prime >= value
|
||||
end
|
||||
if value > 1
|
||||
pv.push [value, 1]
|
||||
end
|
||||
return pv
|
||||
end
|
||||
end
|
||||
|
||||
class Prime
|
||||
include Enumerable
|
||||
|
||||
def initialize
|
||||
@seed = 1
|
||||
@primes = []
|
||||
@counts = []
|
||||
end
|
||||
|
||||
def succ
|
||||
i = -1
|
||||
size = @primes.size
|
||||
while i < size
|
||||
if i == -1
|
||||
@seed += 1
|
||||
i += 1
|
||||
else
|
||||
while @seed > @counts[i]
|
||||
@counts[i] += @primes[i]
|
||||
end
|
||||
if @seed != @counts[i]
|
||||
i += 1
|
||||
else
|
||||
i = -1
|
||||
end
|
||||
end
|
||||
end
|
||||
@primes.push @seed
|
||||
@counts.push @seed + @seed
|
||||
return @seed
|
||||
end
|
||||
|
||||
def each
|
||||
loop do
|
||||
yield succ
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Fixnum
|
||||
alias divmod! divmod
|
||||
alias / rdiv
|
||||
def divmod(other)
|
||||
a = self.div(other)
|
||||
b = self % other
|
||||
return a,b
|
||||
end
|
||||
end
|
||||
|
||||
class Bignum
|
||||
alias divmod! divmod
|
||||
alias / rdiv
|
||||
end
|
||||
|
||||
class Rational
|
||||
Unify = TRUE
|
||||
|
||||
alias power! **
|
||||
|
||||
def ** (other)
|
||||
if other.kind_of?(Rational)
|
||||
if self < 0
|
||||
return Complex(self, 0) ** other
|
||||
elsif other == 0
|
||||
return Rational(1,1)
|
||||
elsif self == 0
|
||||
return Rational(0,1)
|
||||
elsif self == 1
|
||||
return Rational(1,1)
|
||||
end
|
||||
|
||||
npd = @numerator.prime_division
|
||||
dpd = @denominator.prime_division
|
||||
if other < 0
|
||||
other = -other
|
||||
npd, dpd = dpd, npd
|
||||
end
|
||||
|
||||
for elm in npd
|
||||
elm[1] = elm[1] * other
|
||||
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
|
||||
return Float(self) ** other
|
||||
end
|
||||
elm[1] = elm[1].to_i
|
||||
end
|
||||
|
||||
for elm in dpd
|
||||
elm[1] = elm[1] * other
|
||||
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
|
||||
return Float(self) ** other
|
||||
end
|
||||
elm[1] = elm[1].to_i
|
||||
end
|
||||
|
||||
num = Integer.from_prime_division(npd)
|
||||
den = Integer.from_prime_division(dpd)
|
||||
|
||||
Rational(num,den)
|
||||
|
||||
elsif other.kind_of?(Integer)
|
||||
if other > 0
|
||||
num = @numerator ** other
|
||||
den = @denominator ** other
|
||||
elsif other < 0
|
||||
num = @denominator ** -other
|
||||
den = @numerator ** -other
|
||||
elsif other == 0
|
||||
num = 1
|
||||
den = 1
|
||||
end
|
||||
Rational.new!(num, den)
|
||||
elsif other.kind_of?(Float)
|
||||
Float(self) ** other
|
||||
else
|
||||
x , y = other.coerce(self)
|
||||
x ** y
|
||||
end
|
||||
end
|
||||
|
||||
def power2(other)
|
||||
if other.kind_of?(Rational)
|
||||
if self < 0
|
||||
return Complex(self, 0) ** other
|
||||
elsif other == 0
|
||||
return Rational(1,1)
|
||||
elsif self == 0
|
||||
return Rational(0,1)
|
||||
elsif self == 1
|
||||
return Rational(1,1)
|
||||
end
|
||||
|
||||
dem = nil
|
||||
x = self.denominator.to_f.to_i
|
||||
neard = self.denominator.to_f ** (1.0/other.denominator.to_f)
|
||||
loop do
|
||||
if (neard**other.denominator == self.denominator)
|
||||
dem = neaed
|
||||
break
|
||||
end
|
||||
end
|
||||
nearn = self.numerator.to_f ** (1.0/other.denominator.to_f)
|
||||
Rational(num,den)
|
||||
|
||||
elsif other.kind_of?(Integer)
|
||||
if other > 0
|
||||
num = @numerator ** other
|
||||
den = @denominator ** other
|
||||
elsif other < 0
|
||||
num = @denominator ** -other
|
||||
den = @numerator ** -other
|
||||
elsif other == 0
|
||||
num = 1
|
||||
den = 1
|
||||
end
|
||||
Rational.new!(num, den)
|
||||
elsif other.kind_of?(Float)
|
||||
Float(self) ** other
|
||||
else
|
||||
x , y = other.coerce(self)
|
||||
x ** y
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Math
|
||||
def sqrt(a)
|
||||
if a.kind_of?(Complex)
|
||||
abs = sqrt(a.real*a.real + a.image*a.image)
|
||||
# if not abs.kind_of?(Rational)
|
||||
# return a**Rational(1,2)
|
||||
# end
|
||||
x = sqrt((a.real + abs)/Rational(2))
|
||||
y = sqrt((-a.real + abs)/Rational(2))
|
||||
# if !(x.kind_of?(Rational) and y.kind_of?(Rational))
|
||||
# return a**Rational(1,2)
|
||||
# end
|
||||
if a.image >= 0
|
||||
Complex(x, y)
|
||||
else
|
||||
Complex(x, -y)
|
||||
end
|
||||
elsif a >= 0
|
||||
rsqrt(a)
|
||||
else
|
||||
Complex(0,rsqrt(-a))
|
||||
end
|
||||
end
|
||||
|
||||
def rsqrt(a)
|
||||
if a.kind_of?(Float)
|
||||
sqrt!(a)
|
||||
elsif a.kind_of?(Rational)
|
||||
rsqrt(a.numerator)/rsqrt(a.denominator)
|
||||
else
|
||||
src = a
|
||||
max = 2 ** 32
|
||||
byte_a = [src & 0xffffffff]
|
||||
# ruby's bug
|
||||
while (src >= max) and (src >>= 32)
|
||||
byte_a.unshift src & 0xffffffff
|
||||
end
|
||||
|
||||
answer = 0
|
||||
main = 0
|
||||
side = 0
|
||||
for elm in byte_a
|
||||
main = (main << 32) + elm
|
||||
side <<= 16
|
||||
if answer != 0
|
||||
if main * 4 < side * side
|
||||
applo = main.div(side)
|
||||
else
|
||||
applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
|
||||
end
|
||||
else
|
||||
applo = sqrt!(main).to_i + 1
|
||||
end
|
||||
|
||||
while (x = (side + applo) * applo) > main
|
||||
applo -= 1
|
||||
end
|
||||
main -= x
|
||||
answer = (answer << 16) + applo
|
||||
side += applo * 2
|
||||
end
|
||||
if main == 0
|
||||
answer
|
||||
else
|
||||
sqrt!(a)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module_function :sqrt
|
||||
module_function :rsqrt
|
||||
end
|
||||
|
||||
class Complex
|
||||
Unify = TRUE
|
||||
end
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue