class MM::Ratio

Attributes

denominator[RW]
numerator[RW]

Public Class Methods

change_interval(point, index, interval) click to toggle source
# File lib/mm/ratio.rb, line 147
def self.change_interval point, index, interval
  vector = MM::Ratio.to_vector(point)
  if interval == :reciprocal
    interval = vector[index].reciprocal
  end
  vector[index] = interval
  MM::Ratio.from_vector(vector)
end
from_s(r) click to toggle source
# File lib/mm/ratio.rb, line 85
def self.from_s r
  if r.respond_to? :split
    if r =~ /\s/
      r.split(/\s/).inject([]) {|memo, ratio|
        memo << self.from_s(ratio)
      }
    else
      string_to_ratio r
    end
  else
    r.map {|s| self.from_s s}
  end
end
from_vector(vector) click to toggle source
# File lib/mm/ratio.rb, line 143
def self.from_vector vector
  vector.inject([MM::Ratio.new(1,1)]) {|m, r| m << (m.last / r)}
end
from_yaml(yaml_string) click to toggle source

Loads a sequence of MM::Ratios from a YAML file.

# File lib/mm/ratio.rb, line 105
def self.from_yaml yaml_string
  YAML.load(yaml_string).map {|r| MM::Ratio.from_s r}
end
new(n, d) click to toggle source
# File lib/mm/ratio.rb, line 10
def initialize n, d
  gcd = n.gcd d
  @numerator = n / gcd
  @denominator = d / gcd
end
string_to_ratio(string) click to toggle source
# File lib/mm/ratio.rb, line 99
def self.string_to_ratio string
  m = string.match(/(\d+)\/(\d+)/)
  MM::Ratio.new(m[1].to_i, m[2].to_i)
end
to_vector(point) click to toggle source
# File lib/mm/ratio.rb, line 139
def self.to_vector point
  point.each_cons(2).map {|r| r[0] / r[1]}
end

Public Instance Methods

*(other) click to toggle source
# File lib/mm/ratio.rb, line 18
def * other
  MM::Ratio.new(self.numerator * other.numerator, self.denominator * other.denominator)
end
+(other) click to toggle source
# File lib/mm/ratio.rb, line 26
def + other
  MM::Ratio.new(self.numerator*other.denominator + other.numerator*self.denominator,
                self.denominator*other.denominator)
end
-(other) click to toggle source
# File lib/mm/ratio.rb, line 31
def - other
  self + (other * MM::Ratio.new(-1,1))
end
/(other) click to toggle source
# File lib/mm/ratio.rb, line 22
def / other
  self * other.reciprocal
end
<=>(other) click to toggle source
# File lib/mm/ratio.rb, line 60
def <=> other
  # Ensure that the comparison makes sense
  return nil unless other.respond_to? :-

  case
  when (self - other).to_f > 0
    return 1
  when (self - other).to_f < 0
    return -1
  end
  return 0
end
[](i) click to toggle source
# File lib/mm/ratio.rb, line 35
def [] i
  if i == 0
    self.numerator
  elsif i == 1
    self.denominator
  end
end
abs() click to toggle source
# File lib/mm/ratio.rb, line 52
def abs
  if self < MM::Ratio.new(0, 1)
    self * MM::Ratio.new(-1,1)
  else
    self
  end
end
cents() click to toggle source
# File lib/mm/ratio.rb, line 81
def cents
  Math.log2(self.to_f) * 1200.0
end
each() { |r| ... } click to toggle source
# File lib/mm/ratio.rb, line 129
def each
  if block_given?
    [@numerator, @denominator].each do |r|
      yield r
    end
  else
    [@numerator, @denominator].each
  end
end
eql?(other) click to toggle source
# File lib/mm/ratio.rb, line 73
def eql? other
  other.is_a?(MM::Ratio) && (self == other)
end
factors() click to toggle source

Works very similarly to the Prime::prime_division method, except that factors in the numerator are positive, and factors in the denominator are negative.

# File lib/mm/ratio.rb, line 46
def factors
  n_factors = ::Prime.prime_division(@numerator)
  d_factors = ::Prime.prime_division(@denominator).map {|d| d[1] *= -1; d}
  n_factors.concat(d_factors).sort_by {|x| x[0]}
end
hash() click to toggle source
# File lib/mm/ratio.rb, line 77
def hash
  [@numerator, @denominator, MM::Ratio].hash
end
prime_limit() click to toggle source
# File lib/mm/ratio.rb, line 121
def prime_limit
  self.map { |r|
    r.prime_division.map { |s|
      s.first
    }.max
  }.compact.max
end
reciprocal() click to toggle source
# File lib/mm/ratio.rb, line 117
def reciprocal
  MM::Ratio.new(@denominator, @numerator)
end
to_f() click to toggle source
# File lib/mm/ratio.rb, line 109
def to_f
  @numerator.to_f / @denominator
end
to_s() click to toggle source
# File lib/mm/ratio.rb, line 113
def to_s
  "#{@numerator}/#{@denominator}"
end