tonal-tools 4.0.1 → 5.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87e8ef912e87b6414a378f95a598db2dd3ee7ab6cee3d4d3ebeebd85bf230e8e
4
- data.tar.gz: 5beba2db70ca5ece543bfd2795d01471f9cd8d23b8347ae4ec443cfb6f800ea5
3
+ metadata.gz: dc49345ed34f38eed1600818c0b28910a5525a22c8388338c5739650339c9ec1
4
+ data.tar.gz: a63830d52d1ed45aa575c6ee2d924c547a74260697853680928fbc0a586d1cfb
5
5
  SHA512:
6
- metadata.gz: d245e8f861efffe2f7eac563a95b9c1d89f570fdfe49459f57d5c9157c3023c5733f468cc4dbff1ab81da6a67bc68b0de0db98013aeb383e61fd1b7c3f57de76
7
- data.tar.gz: 022b5687ab7b8bf16043b517fa0cbe3124bb17bafedc56f8be0f66a3c54e918b63b188473f1825974078b246672cd02b3aa5017c4372c27f9948aaf6267e21bb
6
+ metadata.gz: 8111bb7846cc0dc220742313c253f6d719d31213ac05c35443eb4dc27058ec236b6bd13b946ad6870ca38b5e48f853385532bc2513f8897c3e5df10c3be3afed
7
+ data.tar.gz: cb3b394f94d175c127b874bba207fc4933e49a91197c48822ea8968578ec57d0dd42730b19eb2a7d6a57eebf44b77615d8b84094d2b3419f88d30b5ae34f1e03
data/data/commas.yml CHANGED
@@ -8,4 +8,4 @@ commas:
8
8
  diaschisma: 2048/2025
9
9
  dieses1: 648/625
10
10
  dieses2: 128/125
11
- septimal: 64/63
11
+ septimal: 64/63
@@ -4,6 +4,9 @@ class Tonal::Ratio
4
4
  DEFAULT_MAX_GRID_SCALE = 100
5
5
  DEFAULT_MAX_GRID_BOUNDARY = 5
6
6
  DEFAULT_DEPTH = Float::INFINITY
7
+ DEFAULT_FRACTION_TREE_DEPTH = 10
8
+ DEFAULT_SUPERPART_DEPTH = 20
9
+ DEFAULT_NEIGHBORHOOD_DEPTH = 10
7
10
  DEFAULT_COMPLEXITY_AMOUNT = 50.0
8
11
  CONVERGENT_LIMIT = 10
9
12
 
@@ -20,7 +23,7 @@ class Tonal::Ratio
20
23
  # @return [Tonal::Ratio::Approximation::Set] of ratios within cent tolerance of self found using continued fraction approximation
21
24
  # @example
22
25
  # Tonal::Ratio.ed(12,1).approximate.by_continued_fraction
23
- # => (4771397596969315/4503599627370496): [(18/17), (196/185), (1657/1564), (7893/7450), (18904/17843), (3118/2943), (1461/1379), (89/84), (17/16)]
26
+ # => (4771397596969315/4503599627370496): [(17/16), (18/17), (89/84), (196/185), (1461/1379), (1657/1564), (3118/2943), (7893/7450), (18904/17843)]
24
27
  # @param cents_tolerance the cents tolerance used to scope the collection
25
28
  # @param depth the maximum number of ratios in the collection
26
29
  # @param max_prime the maximum prime number to allow in the collection
@@ -29,11 +32,11 @@ class Tonal::Ratio
29
32
  def by_continued_fraction(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT)
30
33
  self_in_cents = to_cents
31
34
  within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
32
- Set.new(ratio: ratio).tap do |set|
35
+ Set.new(ratio: ratio) do |ratios|
33
36
  ContinuedFraction.new(antecedent.to_f/consequent, conv_limit).convergents.each do |convergent|
34
37
  ratio2 = ratio.class.new(convergent.numerator,convergent.denominator)
35
- set.ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
36
- break if set.length >= depth
38
+ ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
39
+ break if ratios.length >= depth
37
40
  end
38
41
  end
39
42
  end
@@ -41,21 +44,21 @@ class Tonal::Ratio
41
44
  # @return [Tonal::Ratio::Approximation::Set] of ratios within cent tolerance of self found using a quotient walk on the fraction tree
42
45
  # @example
43
46
  # Tonal::Ratio.ed(12,1).approximate.by_quotient_walk(max_prime: 89)
44
- # => (4771397596969315/4503599627370496): [(18/17), (196/185), (89/84), (71/67), (53/50), (35/33), (17/16)]
47
+ # => (4771397596969315/4503599627370496): [(17/16), (18/17), (35/33), (53/50), (71/67), (89/84), (196/185)]
45
48
  # @param cents_tolerance the cents tolerance used to scope the collection
46
49
  # @param depth the maximum number of ratios in the collection
47
50
  # @param max_prime the maximum prime number to allow in the collection
48
51
  # @param conv_limit the number of convergents to limit the ContinuedFraction method
49
52
  #
50
- def by_quotient_walk(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT)
53
+ def by_quotient_walk(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_FRACTION_TREE_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT)
51
54
  self_in_cents = to_cents
52
55
  within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
53
56
 
54
- Set.new(ratio: ratio).tap do |set|
57
+ Set.new(ratio: ratio) do |ratios|
55
58
  FractionTree.quotient_walk(to_f, limit: conv_limit).each do |node|
56
59
  ratio2 = ratio.class.new(node.weight)
57
- set.ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
58
- break if set.length >= depth
60
+ ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
61
+ break if ratios.length >= depth
59
62
  end
60
63
  end
61
64
  end
@@ -63,19 +66,19 @@ class Tonal::Ratio
63
66
  # @return [Tonal::Ratio::Approximation::Set] of fraction tree ratios within cent tolerance of self
64
67
  # @example
65
68
  # Tonal::Ratio.ed(12,1).approximate.by_tree_path(max_prime: 17)
66
- # => (4771397596969315/4503599627370496): [(18/17), (35/33), (17/16)]
69
+ # => (4771397596969315/4503599627370496): [(17/16), (18/17), (35/33)]
67
70
  # @param cents_tolerance the cents tolerance used to scope the collection
68
71
  # @param depth the maximum number of ratios in the collection
69
72
  # @param max_prime the maximum prime number to allow in the collection
70
73
  #
71
- def by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME)
74
+ def by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_FRACTION_TREE_DEPTH, max_prime: DEFAULT_MAX_PRIME)
72
75
  self_in_cents = to_cents
73
76
  within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
74
- Set.new(ratio: ratio).tap do |set|
77
+ Set.new(ratio: ratio) do |ratios|
75
78
  FractionTree.path_to(to_f).each do |node|
76
79
  ratio2 = ratio.class.new(node.weight)
77
- set.ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
78
- break if set.length >= depth
80
+ ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
81
+ break if ratios.length >= depth
79
82
  end
80
83
  end
81
84
  end
@@ -83,21 +86,21 @@ class Tonal::Ratio
83
86
  # @return [Tonal::Ratio::Approximation::Set] of superparticular approximations within cent tolerance of self
84
87
  # @example
85
88
  # Tonal::Ratio.new(3/2r).approximate.by_superparticular
86
- # => (3/2): [(1098/730), (1095/728), (1092/726), (1089/724), (1086/722), (1083/720), (1080/718), (1077/716), (1074/714), (1071/712), (1068/710), (1065/708), (1062/706), (1059/704), (1056/702), (1053/700), (1050/698), (1047/696), (1044/694), (1041/692)]
89
+ # => (3/2): [(1041/692), (1044/694), (1047/696), (1050/698), (1053/700), (1056/702), (1059/704), (1062/706), (1065/708), (1068/710), (1071/712), (1074/714), (1077/716), (1080/718), (1083/720), (1086/722), (1089/724), (1092/726), (1095/728), (1098/730)]
87
90
  # @param cents_tolerance the cents tolerance used to scope the collection
88
91
  # @param depth the maximum number of ratios in the collection
89
92
  # @param max_prime the maximum prime number to allow in the collection
90
93
  # @param superpart if the superior part is the numerator or denominator
91
94
  #
92
- def by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth: 20, max_prime: DEFAULT_MAX_PRIME, superpart: :upper)
95
+ def by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_SUPERPART_DEPTH, max_prime: DEFAULT_MAX_PRIME, superpart: :upper)
93
96
  self_in_cents = to_cents
94
97
  within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
95
- Set.new(ratio: ratio).tap do |set|
98
+ Set.new(ratio: ratio) do |ratios|
96
99
  n = 1
97
100
  while true do
98
101
  ratio2 = ratio.class.superparticular(n, factor: ratio.to_r, superpart:)
99
- set.ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime) && ratio2 != ratio
100
- break if set.length >= depth
102
+ ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime) && ratio2 != ratio
103
+ break if ratios.length >= depth
101
104
  n += 1
102
105
  end
103
106
  end
@@ -113,18 +116,18 @@ class Tonal::Ratio
113
116
  # @param max_boundary the maximum distance grid ratios will be from the scaled ratio
114
117
  # @param max_scale the maximum self will be scaled
115
118
  #
116
- def by_neighborhood(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, max_boundary: DEFAULT_MAX_GRID_BOUNDARY, max_scale: DEFAULT_MAX_GRID_SCALE)
119
+ def by_neighborhood(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_NEIGHBORHOOD_DEPTH, max_prime: DEFAULT_MAX_PRIME, max_boundary: DEFAULT_MAX_GRID_BOUNDARY, max_scale: DEFAULT_MAX_GRID_SCALE)
117
120
  self_in_cents = to_cents
118
121
  within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
119
- Set.new(ratio: ratio).tap do |set|
122
+ Set.new(ratio: ratio) do |ratios|
120
123
  scale = 1
121
124
  boundary = 1
122
125
 
123
- while set.length <= depth && scale <= max_scale do
126
+ while ratios.length <= depth && scale <= max_scale do
124
127
  while boundary <= max_boundary
125
128
  vacinity = ratio.respond_to?(:to_basic_ratio) ? to_basic_ratio.scale(scale) : ratio.scale(scale)
126
129
  self.class.neighbors(away: boundary, vacinity: vacinity).each do |neighbor|
127
- set.ratios << neighbor if ratio.class.within_cents?(self_in_cents, neighbor.to_cents, within) && neighbor.within_prime?(max_prime) && neighbor != ratio
130
+ ratios << neighbor if ratio.class.within_cents?(self_in_cents, neighbor.to_cents, within) && neighbor.within_prime?(max_prime) && neighbor != ratio
128
131
  end
129
132
  boundary += 1
130
133
  end
@@ -171,19 +174,28 @@ class Tonal::Ratio
171
174
 
172
175
  class Set
173
176
  extend Forwardable
174
- def_delegators :@ratios, :count, :length, :min, :max, :entries, :all?, :any?, :reject, :map
177
+ def_delegators :@ratios, :count, :length, :min, :max, :entries, :all?, :any?, :reject, :map, :find_index
175
178
 
176
179
  attr_reader :ratios, :ratio
177
180
 
178
181
  def initialize(ratio:)
179
182
  @ratio = ratio
180
- @ratios = SortedSet.new
183
+ @ratios = ::Set.new
184
+ yield @ratios if block_given?
181
185
  end
182
186
  alias :approximations :entries
183
187
 
184
188
  def inspect
185
189
  "#{ratio}: #{entries}"
186
190
  end
191
+
192
+ def sort_by(&)
193
+ self.class.new(ratio: ratio) do |ratios|
194
+ entries.sort_by(&).each do |ratio|
195
+ ratios << ratio
196
+ end
197
+ end
198
+ end
187
199
  end
188
200
  end
189
201
  end
@@ -1,4 +1,4 @@
1
1
  module Tonal
2
2
  TOOLS_PRODUCER = "mTonal"
3
- TOOLS_VERSION = "4.0.1"
3
+ TOOLS_VERSION = "5.1.1"
4
4
  end
data/lib/tonal/cents.rb CHANGED
@@ -56,6 +56,7 @@ class Tonal::Cents
56
56
  @value.round(precision)
57
57
  end
58
58
  alias :cents :value
59
+ alias :to_f :value
59
60
 
60
61
  # @return
61
62
  # [Tonal::Cents] nearest hundredth cent value
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tonal-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 5.1.1
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: 2024-03-21 00:00:00.000000000 Z
11
+ date: 2024-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yaml