continued_fractions 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/continued_fractions.gemspec +2 -2
- data/lib/continued_fractions.rb +40 -73
- data/spec/continued_fractions/continued_fraction_spec.rb +3 -3
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0122ca9d3d5652ed7b6ae7d91e569d50b7ef1bd
|
4
|
+
data.tar.gz: 1e83d11105ddcb0d59076526a87e994bcaef4341
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a99457b5cb78d9b4dbc55bd2301b546ecf08e21c359eece3683abfbf2d3d2cf91294c5ab9afb94615ceb62757587a138fdb02194dde442da25ca0dbd7e6b082f
|
7
|
+
data.tar.gz: ea78b244bbee7ac1def880af96b5fc9fa786df525da0419e50c1d4d8c98c7f036311d99ad96be698c9f1459ec77f2acf984552552237dc620dad156c0c59b936
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('continued_fractions', '1.
|
5
|
+
Echoe.new('continued_fractions', '1.5.0') do |config|
|
6
6
|
config.summary = 'Generate continued fractions'
|
7
7
|
config.description = 'Class for working with continued fractions'
|
8
8
|
|
data/continued_fractions.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: continued_fractions 1.
|
2
|
+
# stub: continued_fractions 1.5.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "continued_fractions"
|
6
|
-
s.version = "1.
|
6
|
+
s.version = "1.5.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib"]
|
data/lib/continued_fractions.rb
CHANGED
@@ -1,58 +1,11 @@
|
|
1
1
|
# ContinuedFractions
|
2
2
|
#
|
3
|
-
# Generates quotients and convergents for a given number
|
4
|
-
#
|
5
|
-
# Requires Ruby 1.9+
|
3
|
+
# Generates quotients and convergents for a given number
|
6
4
|
#
|
7
5
|
# Author:: Jose Hales-Garcia (mailto:jolohaga@me.com)
|
8
|
-
# Copyright:: Copyright (c)
|
6
|
+
# Copyright:: Copyright (c) 2015 Jose Hales-Garcia
|
9
7
|
#
|
10
8
|
#
|
11
|
-
module ContinuedFractions
|
12
|
-
class << self
|
13
|
-
def convergence_matrix(n,m,fill=nil) #:nodoc:
|
14
|
-
conv_mat = Array.new(n).map!{Array.new(m,fill)}
|
15
|
-
conv_mat[0][0],conv_mat[1][1] = 0,0
|
16
|
-
conv_mat
|
17
|
-
end
|
18
|
-
|
19
|
-
# Given an array of quotients return the array of convergents up to the nth convergent.
|
20
|
-
# If nth is nil, return the entire list.
|
21
|
-
#
|
22
|
-
# Example:
|
23
|
-
# ContinuedFractions.convergents([3,7,15,1])
|
24
|
-
# => [[3, 1], [22, 7], [333, 106], [355, 113]]
|
25
|
-
#
|
26
|
-
# Or:
|
27
|
-
# ContinuedFractions.convergents([3,7,15,1], 3)
|
28
|
-
# => [[3, 1], [22, 7], [333, 106]]
|
29
|
-
#
|
30
|
-
def convergents(quotients,nth=nil)
|
31
|
-
convs = ContinuedFractions.convergence_matrix(quotients.length+2,2,1)
|
32
|
-
nth ||= convs.length
|
33
|
-
2.upto(quotients.length+1) do |i|
|
34
|
-
i_minus1,i_minus2 = i-1,i-2
|
35
|
-
convs[i][0] = convs[i_minus1][0]*quotients[i_minus2]+convs[i_minus2][0]
|
36
|
-
convs[i][1] = convs[i_minus1][1]*quotients[i_minus2]+convs[i_minus2][1]
|
37
|
-
end
|
38
|
-
convs[2...nth+2]
|
39
|
-
end
|
40
|
-
|
41
|
-
# Convert the convergents array to Rationals
|
42
|
-
#
|
43
|
-
def convergents_array_to_rationals(convergents,nth=nil) #:nodoc:
|
44
|
-
nth ||= convergents.length
|
45
|
-
convergents[0...nth].map{|convergent| convergent_to_rational(convergent)}
|
46
|
-
end
|
47
|
-
|
48
|
-
# Convert a convergent element to a Rational
|
49
|
-
#
|
50
|
-
def convergent_to_rational(convergent) #:nodoc:
|
51
|
-
Rational(convergent[0],convergent[1])
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
9
|
class ContinuedFraction
|
57
10
|
attr_accessor :number, :quotients, :limit
|
58
11
|
attr_writer :convergents
|
@@ -102,7 +55,8 @@ class ContinuedFraction
|
|
102
55
|
# => [[3,1], [22,7], [333,106]]
|
103
56
|
#
|
104
57
|
def convergents(nth=nil)
|
105
|
-
|
58
|
+
nth ||= @convergents.length
|
59
|
+
@convergents[0...nth]
|
106
60
|
end
|
107
61
|
|
108
62
|
# Return array of convergents of the continued fraction instance converted as Rationals.
|
@@ -119,61 +73,61 @@ class ContinuedFraction
|
|
119
73
|
# => [(3/1), (22/7), (333/106)]
|
120
74
|
#
|
121
75
|
def convergents_as_rationals(nth=nil)
|
122
|
-
|
76
|
+
nth ||= convergents.length
|
77
|
+
convergents[0...nth].map{|convergent| convergent_to_rational(convergent)}
|
123
78
|
end
|
124
79
|
|
125
80
|
def +(other)
|
126
|
-
|
127
|
-
|
81
|
+
number_of(other) do |num,prec|
|
82
|
+
evaluate("#{@number} + #{num}",prec)
|
128
83
|
end
|
129
84
|
end
|
130
85
|
|
131
86
|
def -(other)
|
132
|
-
|
133
|
-
|
87
|
+
number_of(other) do |num,prec|
|
88
|
+
evaluate("#{@number} - #{num}",prec)
|
134
89
|
end
|
135
90
|
end
|
136
91
|
|
137
92
|
def /(other)
|
138
|
-
|
139
|
-
|
93
|
+
number_of(other) do |num,prec|
|
94
|
+
evaluate("#{@number} / #{num}",prec)
|
140
95
|
end
|
141
96
|
end
|
142
97
|
|
143
98
|
def *(other)
|
144
|
-
|
145
|
-
|
99
|
+
number_of(other) do |num,prec|
|
100
|
+
evaluate("#{@number} * #{num}",prec)
|
146
101
|
end
|
147
102
|
end
|
148
|
-
|
103
|
+
|
104
|
+
def convergent_to_rational(convergent) #:nodoc:
|
105
|
+
Rational(convergent[0],convergent[1])
|
106
|
+
end
|
107
|
+
|
149
108
|
private
|
150
|
-
def
|
151
|
-
ContinuedFraction.new(eval(
|
109
|
+
def evaluate(exp, prec) #:nodoc:
|
110
|
+
ContinuedFraction.new(eval(exp), prec)
|
152
111
|
end
|
153
112
|
|
154
|
-
def
|
113
|
+
def number_of(n) #:nodoc:
|
155
114
|
num = nil
|
156
115
|
prec = nil
|
157
116
|
case n.class.name
|
158
117
|
when "Fixnum","Integer"
|
159
118
|
num = n
|
160
|
-
prec =
|
119
|
+
prec = limit
|
161
120
|
when "ContinuedFraction"
|
162
121
|
num = n.number
|
163
|
-
prec = [n.limit
|
122
|
+
prec = [n.limit,limit].max
|
164
123
|
end
|
165
124
|
yield(num,prec)
|
166
125
|
end
|
167
|
-
|
168
|
-
def _convergents(nth=nil) #:nodoc:
|
169
|
-
nth ||= @convergents.length
|
170
|
-
@convergents[0...nth]
|
171
|
-
end
|
172
126
|
|
173
127
|
def calculate_quotients #:nodoc:
|
174
|
-
qs = Array.new(
|
128
|
+
qs = Array.new(limit)
|
175
129
|
n = @number
|
176
|
-
|
130
|
+
limit.times do |i|
|
177
131
|
qs[i] = n.to_i
|
178
132
|
n = 1.0/(n-qs[i])
|
179
133
|
end
|
@@ -181,6 +135,19 @@ class ContinuedFraction
|
|
181
135
|
end
|
182
136
|
|
183
137
|
def calculate_convergents #:nodoc:
|
184
|
-
|
138
|
+
convs = convergence_matrix(quotients.length+2,2,1)
|
139
|
+
nth ||= convs.length
|
140
|
+
2.upto(quotients.length+1) do |i|
|
141
|
+
i_minus1,i_minus2 = i-1,i-2
|
142
|
+
convs[i][0] = convs[i_minus1][0]*quotients[i_minus2]+convs[i_minus2][0]
|
143
|
+
convs[i][1] = convs[i_minus1][1]*quotients[i_minus2]+convs[i_minus2][1]
|
144
|
+
end
|
145
|
+
convs[2...nth+2]
|
146
|
+
end
|
147
|
+
|
148
|
+
def convergence_matrix(n,m,fill=nil) #:nodoc:
|
149
|
+
conv_mat = Array.new(n).map!{Array.new(m,fill)}
|
150
|
+
conv_mat[0][0],conv_mat[1][1] = 0,0
|
151
|
+
conv_mat
|
185
152
|
end
|
186
153
|
end
|
@@ -8,7 +8,7 @@ describe ContinuedFraction do
|
|
8
8
|
# First 10 convergents of PI are...
|
9
9
|
convs = ['3/1', '22/7', '333/106', '355/113', '103993/33102', '104348/33215', '208341/66317', '312689/99532', '833719/265381', '1146408/364913'].map{|c| Rational(c)}
|
10
10
|
cf = described_class.new(Math::PI,10)
|
11
|
-
expect((
|
11
|
+
expect((cf.convergents_as_rationals - convs)).to be_empty
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should return array for convergents method" do
|
@@ -21,14 +21,14 @@ describe ContinuedFraction do
|
|
21
21
|
|
22
22
|
it "should contain convergents approaching the number" do
|
23
23
|
0.upto(cf.convergents.length-2) do |i|
|
24
|
-
convergent_rational_i_plus1, convergent_rational_i =
|
24
|
+
convergent_rational_i_plus1, convergent_rational_i = cf.convergent_to_rational(cf.convergents[i+1]), cf.convergent_to_rational(cf.convergents[i])
|
25
25
|
expect(((convergent_rational_i_plus1 - cf.number).abs <= (convergent_rational_i - cf.number).abs)).to be true
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should contain convergents which are expressed in lowest terms" do
|
30
30
|
1.upto(cf.convergents.length-1) do |i|
|
31
|
-
convergent_rational_i, convergent_rational_i_plus1 =
|
31
|
+
convergent_rational_i, convergent_rational_i_plus1 = cf.convergent_to_rational(cf.convergent(i)), cf.convergent_to_rational(cf.convergent(i+1))
|
32
32
|
expect((convergent_rational_i.numerator*convergent_rational_i_plus1.denominator - convergent_rational_i_plus1.numerator*convergent_rational_i.denominator)).to eq (-1)**(i)
|
33
33
|
end
|
34
34
|
end
|