Browse | Submit A New Snippet | Create A Package

## MathExt

Type:
Class
Category:
Math Functions
Language:
Ruby

Description:
Provides a Factorize function and enhances the print formats (to_s method) of Ruby's built-in Complex, Floatand Rational types

### Versions Of This Snippet::

Dick Pountain
 Snippet ID Download Version Date Posted Author Delete 550 1.8. 2009-12-31 19:55 Dick Pountain

## Latest Snippet Version: :1.8.

```#--------------------------------------------------
#  Extended mathematical routines
#--------------------------------------------------
require 'complex'

# Find prime factors of a number
def factorize(inum, switch=0)

if inum < 0 then
num=-inum
else
num=inum
end

primes = []
for i in 2 .. num
primes[i] = i
end

# generate table of primes using Eratosthenes' Sieve
for i in 2 .. Math.sqrt(num)
next unless primes[i]
(i*i).step(num, i) do |j|
primes[j] = nil
end
end

# remove nils
primes = primes.compact

# find prime factors
x = []
for k in 0..primes.size-1
u = num
while u % primes[k] == 0
u = u/primes[k]
x << primes[k]
end
end

# convert array of factors to a string
y = ""
x.each{|i| y=y+"x"+i.to_s}
y = y[1..y.size]

#return array or string form
if switch == 0 then return x else return y end

end #factorize

# Cancel out matching items from two lists
def cancel(list1, list2)

# what items are present?
items=(list1+list2).uniq
its1={}; its2={}
items.each{|i| its1[i] = 0}
items.each{|i| its2[i] = 0}

# count items
list1.each{|i| its1[i]+=1}
list2.each{|i| its2[i]+=1}

# cancel matching items
items.each do |i|
if its1[i]>its2[i] then
its1[i]-=its2[i];
its2[i]=0
else
its2[i]-=its1[i];
its1[i]=0
end
end

# rebuild cancelled lists
clist1=[]; clist2=[]
items.each{|i| its1[i].times{clist1 << i}}
items.each{|i| its2[i].times{clist2 << i}}

return clist1, clist2

end

# simplify a fraction
def simplify(num,denom)
x = factorize(num,0)
y = factorize(denom,0)
z = cancel(x,y)
snum = 1; sdenom = 1;
z[0].each{|i| snum*=i}
z[1].each{|i| sdenom*=i}

if (num<0).^(denom<0) then
return -snum, sdenom
elsif num==0
return 0, sdenom
else  return snum, sdenom
end
end

# Highest Common Factor of integers via factorisation
def hcff(a,b)
c=simplify(a,b)[0]
if c==0 then 0 else a/c end
end

# Highest Common Factor using Euclid's algorithm
def hcf(a, b)
if b == 0 then return a
else return gcd(b, a % b)
end
end

# Greatest Common Divisor for integers or complex
def gcd(a,b)
if (a.class==Complex) or (b.class==Complex) then
x=hcf(a.real,b.real)
y=hcf(a.image,b.image)
Complex(x,y)
else
hcf(a,b)
end
end

# Reduce a fraction, integer or complex
def reduce(a,b)
c=gcd(a,b)
if c==0 then return [a,b] else return [a/c, b/c] end
end

# Least Common Multiple
def lcm(a,b)
(a*b)/hcf(a,b)
end

#---------------------------------------------------------------------------
# Square root of pos and neg numbers -> Complex
#---------------------------------------------------------------------------
def csqrt(a)
if a < 0 then return Complex(0,Math.sqrt(-a))
else return Complex(Math.sqrt(a),0)
end
end

#------------------------------------------------------------------------------
#  Extend Ruby number classes for better print formatting
#------------------------------------------------------------------------------

# Default number print format
\$format = "%g"

# Abbreviations for creating complex and rational literals
def c(r,i)
Complex(r,i)
end

def r(n,d)
Rational(n,d)
end

#-------------------------------------------------------------------------------------------------------------
# Smarter to_s methods for number classes Complex, Fixnum, Float and Rational
#-------------------------------------------------------------------------------------------------------------

class Complex
def to_f
Complex(@real.to_f, @image.to_f)
end

def to_s(f=\$format)
s=""
s=s+(sprintf f,@real)      unless @real == 0
s=s+"+"                       unless @image <= 0 or @real == 0
s=s+(sprintf f,@image)   unless @image == 0 or @image.abs == 1
s=s+"-"                       if @image == -1
s=s+"i"                       unless @image == 0
if s=="" then return "0" else return s end
end

end

class Fixnum
def to_s(f=\$format)
sprintf f,self.real
end
end

class Float
def to_s(f=\$format)
sprintf f,self.real
end
end

class Rational
def to_s(f=\$format)
(sprintf f,self.numerator)+"/"+(sprintf f,self.denominator)
end
end
```

### Submit a new version

You can submit a new version of this snippet if you have modified it and you feel it is appropriate to share with others..