fraction-tree 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fraction_tree.rb +49 -10
  3. metadata +19 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d13b1fb1ddd328714a431288ee0ec04205fb9001ce4a2d1b339e62bef0ed8e4c
4
- data.tar.gz: 55260283f52cfa95dd50ecb02f83baaa436752d85b6fd53b3505d6f752ebb600
3
+ metadata.gz: 9d4c2e3c84acc2fa31151b2863bf7c602490e891004198884e8002a7b7f3cc32
4
+ data.tar.gz: c335d6bfb3f54c8471835cbc9283d904f8d71f7786cfde02a41448a1840ecb02
5
5
  SHA512:
6
- metadata.gz: df04fd1122e08f92ff5bb611f82d9ac582ac26c30e02542f02b9030b2ee248a5ba4f9e9080239fed64587bb55f74db80ec6dcb726e5550d881e61a6f54f616ce
7
- data.tar.gz: db61b0ede817e7b8c1bac18ec4ab07627c20efaef739d01a8fb06bc49db80b7c3cd9243d79a5cdc873085cc0e8482b07eb528ad7ca1c2fb3c0dcceb6761bb402
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 farey_neighbors?(num1, num2)
219
- (num1.numerator * num2.denominator - num1.denominator * num2.numerator).abs == 1
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
- rhs.kind_of?(self.class) && weight == rhs.weight
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.1
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: 2023-12-07 00:00:00.000000000 Z
11
+ date: 2024-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: continued_fractions
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '2.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.0'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -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.4.22
110
+ rubygems_version: 3.5.3
97
111
  signing_key:
98
112
  specification_version: 4
99
113
  summary: Fraction tree