continued_fractions 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|