fraction-tree 1.0.2 → 1.1.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fraction_tree.rb +49 -10
  3. metadata +17 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d7d96a7fc5bfda274cc147d53e623984fc518de2fbfd3c5454df3d493ea5e44
4
- data.tar.gz: 900b7e263cc5df52e6c90932266a647d3e954e67e1dc3ea750f2d79d7d2b99ea
3
+ metadata.gz: 9d4c2e3c84acc2fa31151b2863bf7c602490e891004198884e8002a7b7f3cc32
4
+ data.tar.gz: c335d6bfb3f54c8471835cbc9283d904f8d71f7786cfde02a41448a1840ecb02
5
5
  SHA512:
6
- metadata.gz: '033058a25b6ab000b1657dd9f76d798969182b394e497ecbf3c220e6d15ae647947e52d5a7a4f16668162a8efd3327da70c3452b787b178962f27e0e0306fd46'
7
- data.tar.gz: 89544cc386de3e45b465294dc1fed8b83429882aa68662ec8e17d5feee149fce7817786ed1e8205f91bbeaed524ebfdac9f2c57a0d78f3853f0b2d6eb961d248
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.2
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-22 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
@@ -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.1
110
+ rubygems_version: 3.5.3
97
111
  signing_key:
98
112
  specification_version: 4
99
113
  summary: Fraction tree