Class: Stellar::Util::ContinuedFraction

Inherits:
Object
  • Object
show all
Defined in:
lib/stellar/util/continued_fraction.rb

Defined Under Namespace

Classes: Fraction

Constant Summary collapse

MAX_PRECISION =
(2**32) - 1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(val, parents = []) ⇒ ContinuedFraction

Returns a new instance of ContinuedFraction.



24
25
26
27
28
# File 'lib/stellar/util/continued_fraction.rb', line 24

def initialize(val, parents=[])
  @i       = val.floor
  @f       = val - @i
  @parents = parents
end

Instance Attribute Details

#fObject (readonly)

Returns the value of attribute f.



6
7
8
# File 'lib/stellar/util/continued_fraction.rb', line 6

def f
  @f
end

#iObject (readonly)

Returns the value of attribute i.



5
6
7
# File 'lib/stellar/util/continued_fraction.rb', line 5

def i
  @i
end

Class Method Details

.best_r(number, max_precision = MAX_PRECISION) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/stellar/util/continued_fraction.rb', line 8

def self.best_r(number, max_precision=MAX_PRECISION)
  cur_cf = new(number)

  loop do
    next_cf = cur_cf.extend()
    cur_r   = cur_cf.to_r(max_precision)
    next_r  = next_cf.to_r(max_precision)

    break cur_r if cur_cf.done? || cur_r == next_r

    cur_cf = next_cf
  end

  cur_cf.to_r(max_precision)
end

Instance Method Details

#convergentsObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/stellar/util/continued_fraction.rb', line 43

def convergents
  return @convergents if defined? @convergents

  c = [Fraction.new(0,1), Fraction.new(1,0)]
  to_a.each_with_index do |a, i|
    i = i + 2

    h = a * c[i-1].n + c[i-2].n
    k = a * c[i-1].d + c[i-2].d
    c << Fraction.new(h,k)
  end

  @converegents = c[2..-1]
end

#done?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/stellar/util/continued_fraction.rb', line 66

def done?
  @f == 0
end

#error(actual) ⇒ Object



34
35
36
# File 'lib/stellar/util/continued_fraction.rb', line 34

def error(actual)
  (actual - to_f).abs
end

#extend(count = 1) ⇒ Object



70
71
72
73
74
75
76
77
78
79
# File 'lib/stellar/util/continued_fraction.rb', line 70

def extend(count=1)
  result = self

  count.times do
    break if result.done?
    result = ContinuedFraction.new(1 / result.f, result.to_a)
  end

  result
end

#to_aObject



30
31
32
# File 'lib/stellar/util/continued_fraction.rb', line 30

def to_a
  @parents + [i]
end

#to_fObject



38
39
40
41
# File 'lib/stellar/util/continued_fraction.rb', line 38

def to_f
  convergent = convergents.last
  convergent.n / convergent.d.to_f
end

#to_r(max_precision = MAX_PRECISION) ⇒ Object



58
59
60
61
62
63
64
# File 'lib/stellar/util/continued_fraction.rb', line 58

def to_r(max_precision=MAX_PRECISION)
  fraction = convergents.take_while do |c|
    c.n <= max_precision && c.d <= max_precision
  end.last

  Rational(fraction.n, fraction.d)
end