fraction-tree 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/fraction_tree.rb +49 -10
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d4c2e3c84acc2fa31151b2863bf7c602490e891004198884e8002a7b7f3cc32
|
4
|
+
data.tar.gz: c335d6bfb3f54c8471835cbc9283d904f8d71f7786cfde02a41448a1840ecb02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef4347b24418118dbf6f4c8fdc6ac03829829aaf5c15d51295befda2f6bddad1b7022b7b428906998ab2a18106a68850dacdc61c3616a345d911f5db32008c86
|
7
|
+
data.tar.gz: 940a05ae9a163d32cae321457da5135334f8a45a96bd0a6141d420d133216c912cd50826c33c3488fa7c17c96286ec11e755e2c8199afe4cddc8fee9846e25bf
|
data/lib/fraction_tree.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "bigdecimal/util"
|
1
2
|
require "continued_fractions"
|
2
3
|
|
3
4
|
# @author Jose Hales-Garcia
|
@@ -66,6 +67,8 @@ class FractionTree
|
|
66
67
|
#
|
67
68
|
def path_to(number, find_parents: false, segment: base_segment)
|
68
69
|
return Node.new(number.numerator, number.denominator) if number.zero?
|
70
|
+
number = number.kind_of?(Float) ? number.to_d : number
|
71
|
+
|
69
72
|
q = Node.new(number.numerator, number.denominator)
|
70
73
|
l = segment.first
|
71
74
|
h = segment.last
|
@@ -200,6 +203,37 @@ class FractionTree
|
|
200
203
|
end
|
201
204
|
end
|
202
205
|
|
206
|
+
# @return [Array] of Farey neighbors to the given number. A Farey neighbor is a number b/c, who's relationship to a/b is such that ad − bc = 1, when c/d < a/b and bc − ad = 1 when c/d > a/b.
|
207
|
+
# @example
|
208
|
+
# FractionTree.farey_neighbors(3/2r, 10)
|
209
|
+
# => [(1/1), (2/1), (4/3), (5/3), (7/5), (8/5), (10/7), (11/7), (13/9), (14/9)]
|
210
|
+
# @param number with neighbors
|
211
|
+
# @param range of harmonic series to search
|
212
|
+
#
|
213
|
+
def farey_neighbors(number, range = 10**(decimal_power(number.numerator)+2))
|
214
|
+
ratio = number.to_r
|
215
|
+
denominator = ratio.denominator
|
216
|
+
|
217
|
+
[].tap do |collection|
|
218
|
+
(1..range-1).each do |i|
|
219
|
+
lower, upper = plus_minus(ratio, Rational(1,i*denominator))
|
220
|
+
collection << lower if farey_neighbors?(ratio, lower)
|
221
|
+
collection << upper if farey_neighbors?(ratio, upper)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# @return [Boolean] whether two numbers are Farey neighbors
|
227
|
+
# @example
|
228
|
+
# FractionTree.farey_neighbors?(3/2r, 4/3r) => true
|
229
|
+
# FractionTree.farey_neighbors?(3/2r, 7/4r) => false
|
230
|
+
# @param num1 of comparison
|
231
|
+
# @param num2 of comparison
|
232
|
+
#
|
233
|
+
def farey_neighbors?(num1, num2)
|
234
|
+
(num1.numerator * num2.denominator - num1.denominator * num2.numerator).abs == 1
|
235
|
+
end
|
236
|
+
|
203
237
|
private
|
204
238
|
def computed_base_segment(number)
|
205
239
|
floor = number.floor
|
@@ -215,18 +249,15 @@ class FractionTree
|
|
215
249
|
_sequence(depth - 1, segment: [segment.first, mediant]) + [mediant] + _sequence(depth - 1, segment: [mediant, segment.last])
|
216
250
|
end
|
217
251
|
|
218
|
-
def
|
219
|
-
|
252
|
+
def plus_minus(number, diff)
|
253
|
+
[number - diff, number + diff]
|
254
|
+
end
|
255
|
+
|
256
|
+
def decimal_power(number)
|
257
|
+
Math.log10(number.abs).floor
|
220
258
|
end
|
221
259
|
end
|
222
260
|
|
223
|
-
# @attr_reader numerator [Integer]
|
224
|
-
# The numerator of the node
|
225
|
-
# @attr_reader denominator [Integer]
|
226
|
-
# The denominator of the node
|
227
|
-
# @attr_reader weight [Rational|Infinity]
|
228
|
-
# The value of the node
|
229
|
-
#
|
230
261
|
class Node
|
231
262
|
include Comparable
|
232
263
|
|
@@ -256,8 +287,16 @@ class FractionTree
|
|
256
287
|
# Needed for intersection operations to work.
|
257
288
|
# https://blog.mnishiguchi.com/ruby-intersection-of-object-arrays
|
258
289
|
# https://shortrecipes.blogspot.com/2006/10/ruby-intersection-of-two-arrays-of.html
|
290
|
+
# Also, allows using with Set, which uses Hash as storage and equality of its elements is determined according to Object#eql? and Object#hash.
|
291
|
+
#
|
259
292
|
def eql?(rhs)
|
260
|
-
|
293
|
+
rhs.instance_of?(self.class) && weight == rhs.weight
|
294
|
+
end
|
295
|
+
|
296
|
+
def hash
|
297
|
+
p, q = 17, 37
|
298
|
+
p = q * @id.hash
|
299
|
+
p = q * @name.hash
|
261
300
|
end
|
262
301
|
|
263
302
|
def +(rhs)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fraction-tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jose Hales-Garcia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: continued_fractions
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.9'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-benchmark
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.6'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.6'
|
69
83
|
description: A collection of Stern-Brocot based models and methods
|
70
84
|
email: jose@halesgarcia.com
|
71
85
|
executables: []
|
@@ -93,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
107
|
- !ruby/object:Gem::Version
|
94
108
|
version: '3.1'
|
95
109
|
requirements: []
|
96
|
-
rubygems_version: 3.5.
|
110
|
+
rubygems_version: 3.5.3
|
97
111
|
signing_key:
|
98
112
|
specification_version: 4
|
99
113
|
summary: Fraction tree
|